From 7728a54d269624e9e5f71236dd30ee9269007183 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Mon, 20 May 2013 19:00:49 -0700 Subject: [PATCH] Converted Transmitter to separate class, removed V1 (Google Glass, Android) support for V2 (iOS) transmitter --- interface/src/Application.cpp | 28 ++--- interface/src/Application.h | 2 + interface/src/Avatar.cpp | 168 --------------------------- interface/src/Avatar.h | 20 +--- libraries/shared/src/PacketHeaders.h | 1 - 5 files changed, 15 insertions(+), 204 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3c356af930..dbcba2f5c2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -156,6 +156,7 @@ Application::Application(int& argc, char** argv) : _bytesCount(0) { gettimeofday(&_applicationStartupTime, NULL); + _window->setWindowTitle("Interface"); printLog("Interface Startup:\n"); _voxels.setViewFrustum(&_viewFrustum); @@ -408,14 +409,16 @@ void Application::paintGL() { } } - _frameCount++; + _frameCount++; + // If application has just started, report time from startup to now (first frame display) if (_justStarted) { float startupTime = (usecTimestampNow() - usecTimestamp(&_applicationStartupTime))/1000000.0; _justStarted = false; - char title[30]; - snprintf(title, 30, "Interface: %4.2f seconds", startupTime); + char title[50]; + sprintf(title, "Interface: %4.2f seconds\n", startupTime); + printLog("%s", title); _window->setWindowTitle(title); } } @@ -852,13 +855,10 @@ void Application::idle() { float deltaTime = 1.f/_fps; - // Use Transmitter Hand to move hand if connected, else use mouse - if (_myAvatar.isTransmitterV2Connected()) { + // Use Transmitter Hand to move hand if connected, else use mouse + if (_myTransmitter.isConnected()) { const float HAND_FORCE_SCALING = 0.05f; - const float* handAcceleration = _myAvatar.getTransmitterHandLastAcceleration(); - _myAvatar.setMovedHandOffset(glm::vec3(-handAcceleration[0] * HAND_FORCE_SCALING, - handAcceleration[1] * HAND_FORCE_SCALING, - handAcceleration[2] * HAND_FORCE_SCALING)); + _myAvatar.setMovedHandOffset(_myTransmitter.getLastAcceleration() * HAND_FORCE_SCALING); } else { // update behaviors for avatar hand movement: handControl takes mouse values as input, // and gives back 3D values modulated for smooth transitioning between interaction modes. @@ -1757,8 +1757,8 @@ void Application::displayOverlay() { if (_displayLevels) _serialPort.renderLevels(_glWidget->width(), _glWidget->height()); // Show hand transmitter data if detected - if (_myAvatar.isTransmitterV2Connected()) { - _myAvatar.transmitterV2RenderLevels(_glWidget->width(), _glWidget->height()); + if (_myTransmitter.isConnected()) { + _myTransmitter.renderLevels(_glWidget->width(), _glWidget->height()); } // Display stats and log text onscreen glLineWidth(1.0f); @@ -2111,13 +2111,9 @@ void* Application::networkReceive(void* args) { app->_bytesCount += bytesReceived; switch (app->_incomingPacket[0]) { - case PACKET_HEADER_TRANSMITTER_DATA_V1: - // V1 = android app, or the Google Glass - app->_myAvatar.processTransmitterData(app->_incomingPacket, bytesReceived); - break; case PACKET_HEADER_TRANSMITTER_DATA_V2: // V2 = IOS transmitter app - app->_myAvatar.processTransmitterDataV2(app->_incomingPacket, bytesReceived); + app->_myTransmitter.processIncomingData(app->_incomingPacket, bytesReceived); break; case PACKET_HEADER_MIXED_AUDIO: diff --git a/interface/src/Application.h b/interface/src/Application.h index dae7f8d71b..99c4e530de 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -189,6 +189,8 @@ private: Avatar _myAvatar; // The rendered avatar of oneself + Transmitter _myTransmitter; // Gets UDP data from transmitter app used to animate the avatar + Camera _myCamera; // My view onto the world Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode diff --git a/interface/src/Avatar.cpp b/interface/src/Avatar.cpp index d789f3751a..093e5f26d5 100644 --- a/interface/src/Avatar.cpp +++ b/interface/src/Avatar.cpp @@ -76,11 +76,6 @@ Avatar::Avatar(bool isMine) : _speed(0.0f), _maxArmLength(0.0f), _orientation(), - _transmitterIsFirstData(true), - _transmitterHz(0.0f), - _transmitterPackets(0), - _transmitterInitialReading(0.0f, 0.0f, 0.0f), - _isTransmitterV2Connected(false), _pelvisStandingHeight(0.0f), _displayingHead(true), _distanceToNearestAvatar(std::numeric_limits::max()), @@ -1133,169 +1128,6 @@ void Avatar::renderBody(bool lookingInMirror) { } } -// -// Process UDP interface data from Android transmitter or Google Glass -// -void Avatar::processTransmitterData(unsigned char* packetData, int numBytes) { - // Read a packet from a transmitter app, process the data - float - accX, accY, accZ, // Measured acceleration - graX, graY, graZ, // Gravity - gyrX, gyrY, gyrZ, // Gyro velocity in radians/sec as (pitch, roll, yaw) - linX, linY, linZ, // Linear Acceleration (less gravity) - rot1, rot2, rot3, rot4; // Rotation of device: - // rot1 = roll, ranges from -1 to 1, 0 = flat on table - // rot2 = pitch, ranges from -1 to 1, 0 = flat on table - // rot3 = yaw, ranges from -1 to 1 - char device[100]; // Device ID - - enum deviceTypes { DEVICE_GLASS, DEVICE_ANDROID, DEVICE_IPHONE, DEVICE_UNKNOWN }; - - sscanf((char *)packetData, - "tacc %f %f %f gra %f %f %f gyr %f %f %f lin %f %f %f rot %f %f %f %f dna \"%s", - &accX, &accY, &accZ, - &graX, &graY, &graZ, - &gyrX, &gyrY, &gyrZ, - &linX, &linY, &linZ, - &rot1, &rot2, &rot3, &rot4, (char *)&device); - - // decode transmitter device type - deviceTypes deviceType = DEVICE_UNKNOWN; - if (strcmp(device, "ADR")) { - deviceType = DEVICE_ANDROID; - } else { - deviceType = DEVICE_GLASS; - } - - if (_transmitterPackets++ == 0) { - // If first packet received, note time, turn head spring return OFF, get start rotation - gettimeofday(&_transmitterTimer, NULL); - if (deviceType == DEVICE_GLASS) { - _head.setReturnToCenter(true); - _head.setSpringScale(10.f); - printLog("Using Google Glass to drive head, springs ON.\n"); - - } else { - _head.setReturnToCenter(false); - printLog("Using Transmitter %s to drive head, springs OFF.\n", device); - - } - //printLog("Packet: [%s]\n", packetData); - //printLog("Version: %s\n", device); - - _transmitterInitialReading = glm::vec3(rot3, rot2, rot1); - } - - const int TRANSMITTER_COUNT = 100; - if (_transmitterPackets % TRANSMITTER_COUNT == 0) { - // Every 100 packets, record the observed Hz of the transmitter data - timeval now; - gettimeofday(&now, NULL); - double msecsElapsed = diffclock(&_transmitterTimer, &now); - _transmitterHz = static_cast((double)TRANSMITTER_COUNT / (msecsElapsed / 1000.0)); - _transmitterTimer = now; - printLog("Transmitter Hz: %3.1f\n", _transmitterHz); - } - //printLog("Gyr: %3.1f, %3.1f, %3.1f\n", glm::degrees(gyrZ), glm::degrees(-gyrX), glm::degrees(gyrY)); - //printLog("Rot: %3.1f, %3.1f, %3.1f, %3.1f\n", rot1, rot2, rot3, rot4); - - // Update the head with the transmitter data - glm::vec3 eulerAngles((rot3 - _transmitterInitialReading.x) * 180.f, - -(rot2 - _transmitterInitialReading.y) * 180.f, - (rot1 - _transmitterInitialReading.z) * 180.f); - if (eulerAngles.x > 180.f) { eulerAngles.x -= 360.f; } - if (eulerAngles.x < -180.f) { eulerAngles.x += 360.f; } - - glm::vec3 angularVelocity; - if (deviceType != DEVICE_GLASS) { - angularVelocity = glm::vec3(glm::degrees(gyrZ), glm::degrees(-gyrX), glm::degrees(gyrY)); - setHeadFromGyros(&eulerAngles, &angularVelocity, - (_transmitterHz == 0.f) ? 0.f : 1.f / _transmitterHz, 1.0); - - } else { - angularVelocity = glm::vec3(glm::degrees(gyrY), glm::degrees(-gyrX), glm::degrees(-gyrZ)); - setHeadFromGyros(&eulerAngles, &angularVelocity, - (_transmitterHz == 0.f) ? 0.f : 1.f / _transmitterHz, 1000.0); - } -} -// -// Process UDP data from version 2 Transmitter acting as Hand -// -void Avatar::processTransmitterDataV2(unsigned char* packetData, int numBytes) { - if (numBytes == 3 + sizeof(_transmitterHandLastRotationRates) + - sizeof(_transmitterHandLastAcceleration)) { - memcpy(_transmitterHandLastRotationRates, packetData + 2, - sizeof(_transmitterHandLastRotationRates)); - memcpy(_transmitterHandLastAcceleration, packetData + 3 + - sizeof(_transmitterHandLastRotationRates), - sizeof(_transmitterHandLastAcceleration)); - // Convert from transmitter units to internal units - for (int i = 0; i < 3; i++) { - _transmitterHandLastRotationRates[i] *= 180.f / PI; - _transmitterHandLastAcceleration[i] *= GRAVITY_EARTH; - } - if (!_isTransmitterV2Connected) { - printf("Transmitter V2 Connected.\n"); - _isTransmitterV2Connected = true; - } - } else { - printf("Transmitter V2 packet read error.\n"); - } -} - -void Avatar::transmitterV2RenderLevels(int width, int height) { - - char val[50]; - const int LEVEL_CORNER_X = 10; - const int LEVEL_CORNER_Y = 400; - - // Draw the numeric degree/sec values from the gyros - sprintf(val, "Yaw %4.1f", _transmitterHandLastRotationRates[1]); - drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y, 0.10, 0, 1.0, 1, val, 0, 1, 0); - sprintf(val, "Pitch %4.1f", _transmitterHandLastRotationRates[0]); - drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 15, 0.10, 0, 1.0, 1, val, 0, 1, 0); - sprintf(val, "Roll %4.1f", _transmitterHandLastRotationRates[2]); - drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 30, 0.10, 0, 1.0, 1, val, 0, 1, 0); - sprintf(val, "X %4.3f", _transmitterHandLastAcceleration[0]); - drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 45, 0.10, 0, 1.0, 1, val, 0, 1, 0); - sprintf(val, "Y %4.3f", _transmitterHandLastAcceleration[1]); - drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 60, 0.10, 0, 1.0, 1, val, 0, 1, 0); - sprintf(val, "Z %4.3f", _transmitterHandLastAcceleration[2]); - drawtext(LEVEL_CORNER_X, LEVEL_CORNER_Y + 75, 0.10, 0, 1.0, 1, val, 0, 1, 0); - - // Draw the levels as horizontal lines - const int LEVEL_CENTER = 150; - const float ACCEL_VIEW_SCALING = 50.f; - glLineWidth(2.0); - glColor4f(1, 1, 1, 1); - glBegin(GL_LINES); - // Gyro rates - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 3); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _transmitterHandLastRotationRates[1], LEVEL_CORNER_Y - 3); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 12); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _transmitterHandLastRotationRates[0], LEVEL_CORNER_Y + 12); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 27); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + _transmitterHandLastRotationRates[2], LEVEL_CORNER_Y + 27); - // Acceleration - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 42); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_transmitterHandLastAcceleration[0] * ACCEL_VIEW_SCALING), - LEVEL_CORNER_Y + 42); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 57); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_transmitterHandLastAcceleration[1] * ACCEL_VIEW_SCALING), - LEVEL_CORNER_Y + 57); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 72); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER + (int)(_transmitterHandLastAcceleration[2] * ACCEL_VIEW_SCALING), - LEVEL_CORNER_Y + 72); - - glEnd(); - // Draw green vertical centerline - glColor4f(0, 1, 0, 0.5); - glBegin(GL_LINES); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y - 6); - glVertex2f(LEVEL_CORNER_X + LEVEL_CENTER, LEVEL_CORNER_Y + 30); - glEnd(); -} - void Avatar::setHeadFromGyros(glm::vec3* eulerAngles, glm::vec3* angularVelocity, float deltaTime, float smoothingTime) { // // Given absolute position and angular velocity information, update the avatar's head angles diff --git a/interface/src/Avatar.h b/interface/src/Avatar.h index 3832fa1902..500237930f 100644 --- a/interface/src/Avatar.h +++ b/interface/src/Avatar.h @@ -20,6 +20,7 @@ #include "SerialInterface.h" #include "Balls.h" #include "Head.h" +#include "Transmitter.h" enum DriveKeys { @@ -122,16 +123,6 @@ public: void setThrust(glm::vec3 newThrust) { _thrust = newThrust; }; void addThrust(glm::vec3 newThrust) { _thrust += newThrust; }; glm::vec3 getThrust() { return _thrust; }; - - // Related to getting transmitter UDP data used to animate the avatar hand - void processTransmitterData(unsigned char * packetData, int numBytes); - void processTransmitterDataV2(unsigned char * packetData, int numBytes); - const bool isTransmitterV2Connected() const { return _isTransmitterV2Connected; }; - const float* getTransmitterHandLastAcceleration() const { return _transmitterHandLastAcceleration; }; - const float* getTransmitterHandLastRotationRates() const { return _transmitterHandLastRotationRates; }; - void transmitterV2RenderLevels(int width, int height); - - float getTransmitterHz() { return _transmitterHz; }; void writeAvatarDataToFile(); void readAvatarDataFromFile(); @@ -179,15 +170,6 @@ private: float _maxArmLength; Orientation _orientation; int _driveKeys[MAX_DRIVE_KEYS]; - bool _transmitterIsFirstData; - timeval _transmitterTimeLastReceived; - timeval _transmitterTimer; - float _transmitterHz; - int _transmitterPackets; - glm::vec3 _transmitterInitialReading; - float _transmitterHandLastRotationRates[3]; - float _transmitterHandLastAcceleration[3]; - bool _isTransmitterV2Connected; float _pelvisStandingHeight; float _height; Balls* _balls; diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 8d9c4ae880..39f81bf651 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -28,7 +28,6 @@ const PACKET_HEADER PACKET_HEADER_ERASE_VOXEL = 'E'; const PACKET_HEADER PACKET_HEADER_VOXEL_DATA = 'V'; const PACKET_HEADER PACKET_HEADER_VOXEL_DATA_MONOCHROME = 'v'; const PACKET_HEADER PACKET_HEADER_BULK_AVATAR_DATA = 'X'; -const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA_V1 = 't'; const PACKET_HEADER PACKET_HEADER_TRANSMITTER_DATA_V2 = 'T'; const PACKET_HEADER PACKET_HEADER_ENVIRONMENT_DATA = 'e'; const PACKET_HEADER PACKET_HEADER_DOMAIN_LIST_REQUEST = 'L';