From 8b90a5d40c52d60cf671e338ad2b2e91bb06fd10 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sun, 14 Oct 2012 15:07:31 -0700 Subject: [PATCH] Added hand code to display/move a manipulator arm --- .DS_Store | Bin 6148 -> 6148 bytes SerialInterface.cpp | 3 +- hand.cpp | 59 +++++ hand.h | 36 ++++ head.cpp | 156 +++++++------- head.h | 2 + interface.xcodeproj/project.pbxproj | 6 + .../UserInterfaceState.xcuserstate | Bin 94960 -> 96342 bytes .../xcdebugger/Breakpoints.xcbkptlist | 6 +- main.cpp | 202 +++++++++++------- 10 files changed, 310 insertions(+), 160 deletions(-) create mode 100644 hand.cpp create mode 100644 hand.h diff --git a/.DS_Store b/.DS_Store index 8ac4e49dec7f6f01d6be8541a069991a1228efda..70c620c8f2a7d05ffd84484e998eb30841822429 100644 GIT binary patch delta 35 tcmV+;0NnqCFoZC$kOKnmp_5nxDwDhe3j?2~p|jBgHUyD?2eStV{SWo{4MP9` delta 35 rcmZoMXffC@ftl%k`Q!*@t;u_sxtUA(Yc^kGHe;FCz`mKC<1aq|;)M(& diff --git a/SerialInterface.cpp b/SerialInterface.cpp index 5ffdf43372..93e58e73df 100644 --- a/SerialInterface.cpp +++ b/SerialInterface.cpp @@ -72,7 +72,8 @@ int read_sensors(int first_measurement, float * avg_adc_channels, int * adc_chan // At end - Extract value from string to variables if (serial_buffer[0] != 'p') { - sscanf(serial_buffer, "%d %d %d %d", &adc_channels[0], + sscanf(serial_buffer, "%d %d %d %d", + &adc_channels[0], &adc_channels[1], &adc_channels[2], &adc_channels[3]); diff --git a/hand.cpp b/hand.cpp new file mode 100644 index 0000000000..afb1d71256 --- /dev/null +++ b/hand.cpp @@ -0,0 +1,59 @@ +// +// hand.cpp +// interface +// +// Created by Philip Rosedale on 10/13/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#include "hand.h" + +Hand::Hand() +{ + reset(); + noise = 0; +} + +void Hand::render() +{ + glEnable(GL_DEPTH_TEST); + glPushMatrix(); + glLoadIdentity(); + glColor3f(0.5, 0.5, 0.5); + glBegin(GL_LINES); + glVertex3f(-0.05, -0.5, 0.0); + glVertex3f(position.x, position.y, position.z); + glVertex3f(0.05, -0.5, 0.0); + glVertex3f(position.x, position.y, position.z); + glEnd(); + glTranslatef(position.x, position.y, position.z); + glutSolidSphere(0.2, 15, 15); + glPopMatrix(); +} + +void Hand::reset() +{ + position.x = 0.0; + position.y = 0.0; + position.z = -7.0; + velocity.x = velocity.y = velocity.z = 0; +} + +void Hand::simulate(float deltaTime) +{ + position += velocity*deltaTime; + + velocity *= (1.f - 4.0*deltaTime); + + if ((noise) && (randFloat() < 0.1)) + { + velocity.x += (randFloat() - 0.5)*noise; + velocity.y += (randFloat() - 0.5)*noise; + velocity.z += (randFloat() - 0.5)*noise; + + } + //position.x += (randFloat() - 0.5)/20.0; + //position.y += (randFloat() - 0.5)/20.0; + //position.z += (randFloat() - 0.5)/20.0; + +} \ No newline at end of file diff --git a/hand.h b/hand.h new file mode 100644 index 0000000000..c90877bfeb --- /dev/null +++ b/hand.h @@ -0,0 +1,36 @@ +// +// hand.h +// interface +// +// Created by Philip Rosedale on 10/13/12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#ifndef interface_hand_h +#define interface_hand_h + +#include "glm/glm.hpp" +#include +#include "util.h" +#include "field.h" +#include "world.h" +#include + +const float RADIUS_RANGE = 10.0; + +class Hand { +public: + Hand(void); + void simulate (float deltaTime); + void render (); + void reset (); + void setNoise (float mag) { noise = mag; }; + void addVel (glm::vec3 add) { velocity += add; }; +private: + glm::vec3 position, velocity; + float noise; + +}; + + +#endif diff --git a/head.cpp b/head.cpp index 8ff43dc306..9d429ddd3a 100644 --- a/head.cpp +++ b/head.cpp @@ -19,8 +19,6 @@ float BrowPitchAngle[3] = {-70, -60, -50}; float eyeColor[3] = {1,1,1}; float MouthWidthChoices[3] = {0.5, 0.77, 0.3}; - -int randNoise = 0; float browWidth = 0.8; float browThickness = 0.16; @@ -45,6 +43,7 @@ Head::Head() PitchTarget = YawTarget = 0; NoiseEnvelope = 1.0; PupilConverge = 2.1; + setNoise(0); } void Head::reset() @@ -57,7 +56,7 @@ void Head::reset() void Head::simulate(float deltaTime) { - if (!randNoise) + if (!noise) { // Decay back toward center Pitch *= (1.f - DECAY*deltaTime); @@ -71,7 +70,7 @@ void Head::simulate(float deltaTime) Roll *= (1.f - DECAY*deltaTime); } - if (randNoise) + if (noise) { Pitch += (randFloat() - 0.5)*0.05*NoiseEnvelope; Yaw += (randFloat() - 0.5)*0.1*NoiseEnvelope; @@ -116,87 +115,88 @@ void Head::render() glEnable(GL_DEPTH_TEST); glPushMatrix(); - glTranslatef(0.f, 0.f, -7.f); - glRotatef(Yaw/2.0, 0, 1, 0); - glRotatef(Pitch/2.0, 1, 0, 0); - glRotatef(Roll/2.0, 0, 0, 1); - - // Overall scale of head - glScalef(2.0, 2.0, 2.0); - glColor3fv(skinColor); - - // Head - glutSolidSphere(1, 15, 15); - - // Ears - glPushMatrix(); - glTranslatef(1, 0, 0); - for(side = 0; side < 2; side++) - { + glLoadIdentity(); + glTranslatef(0.f, 0.f, -7.f); + glRotatef(Yaw/2.0, 0, 1, 0); + glRotatef(Pitch/2.0, 1, 0, 0); + glRotatef(Roll/2.0, 0, 0, 1); + + // Overall scale of head + glScalef(2.0, 2.0, 2.0); + glColor3fv(skinColor); + + // Head + glutSolidSphere(1, 15, 15); + + // Ears glPushMatrix(); - glScalef(0.5, 0.75, 1.0); - glutSolidSphere(0.5, 15, 15); + glTranslatef(1, 0, 0); + for(side = 0; side < 2; side++) + { + glPushMatrix(); + glScalef(0.5, 0.75, 1.0); + glutSolidSphere(0.5, 15, 15); + glPopMatrix(); + glTranslatef(-2, 0, 0); + } glPopMatrix(); - glTranslatef(-2, 0, 0); - } - glPopMatrix(); - + - // Eyebrows - glPushMatrix(); - glTranslatef(-interBrowDistance/2.0,0.4,0.45); - for(side = 0; side < 2; side++) - { - glColor3fv(browColor); + // Eyebrows glPushMatrix(); - glTranslatef(0, 0.4, 0); - glRotatef(EyebrowPitch[side]/2.0, 1, 0, 0); - glRotatef(EyebrowRoll[side]/2.0, 0, 0, 1); - glScalef(browWidth, browThickness, 1); - glutSolidCube(0.5); + glTranslatef(-interBrowDistance/2.0,0.4,0.45); + for(side = 0; side < 2; side++) + { + glColor3fv(browColor); + glPushMatrix(); + glTranslatef(0, 0.4, 0); + glRotatef(EyebrowPitch[side]/2.0, 1, 0, 0); + glRotatef(EyebrowRoll[side]/2.0, 0, 0, 1); + glScalef(browWidth, browThickness, 1); + glutSolidCube(0.5); + glPopMatrix(); + glTranslatef(interBrowDistance, 0, 0); + } glPopMatrix(); - glTranslatef(interBrowDistance, 0, 0); - } - glPopMatrix(); - - // Mouth - glPushMatrix(); - glTranslatef(0,-0.3,0.75); - glColor3fv(mouthColor); - glRotatef(MouthPitch, 1, 0, 0); - glRotatef(MouthYaw, 0, 0, 1); - glScalef(MouthWidth, MouthHeight, 1); - glutSolidCube(0.5); - glPopMatrix(); - - glTranslatef(0, 1.0, 0); + + // Mouth + glPushMatrix(); + glTranslatef(0,-0.3,0.75); + glColor3fv(mouthColor); + glRotatef(MouthPitch, 1, 0, 0); + glRotatef(MouthYaw, 0, 0, 1); + glScalef(MouthWidth, MouthHeight, 1); + glutSolidCube(0.5); + glPopMatrix(); + + glTranslatef(0, 1.0, 0); - // Right Eye - glTranslatef(-0.25,-0.5,0.7); - glColor3fv(eyeColor); - glutSolidSphere(0.25, 15, 15); - // Right Pupil - glPushMatrix(); - glRotatef(EyeballPitch[1], 1, 0, 0); - glRotatef(EyeballYaw[1] + PupilConverge, 0, 1, 0); - glTranslatef(0,0,.25); - glColor3f(0,0,0); - glutSolidSphere(PupilSize, 10, 10); - glPopMatrix(); - // Left Eye - glColor3fv(eyeColor); - glTranslatef(interPupilDistance, 0, 0); - glutSolidSphere(0.25f, 15, 15); - // Left Pupil - glPushMatrix(); - glRotatef(EyeballPitch[0], 1, 0, 0); - glRotatef(EyeballYaw[0] - PupilConverge, 0, 1, 0); - glTranslatef(0,0,.25); - glColor3f(0,0,0); - glutSolidSphere(PupilSize, 10, 10); - glPopMatrix(); + // Right Eye + glTranslatef(-0.25,-0.5,0.7); + glColor3fv(eyeColor); + glutSolidSphere(0.25, 15, 15); + // Right Pupil + glPushMatrix(); + glRotatef(EyeballPitch[1], 1, 0, 0); + glRotatef(EyeballYaw[1] + PupilConverge, 0, 1, 0); + glTranslatef(0,0,.25); + glColor3f(0,0,0); + glutSolidSphere(PupilSize, 10, 10); + glPopMatrix(); + // Left Eye + glColor3fv(eyeColor); + glTranslatef(interPupilDistance, 0, 0); + glutSolidSphere(0.25f, 15, 15); + // Left Pupil + glPushMatrix(); + glRotatef(EyeballPitch[0], 1, 0, 0); + glRotatef(EyeballYaw[0] - PupilConverge, 0, 1, 0); + glTranslatef(0,0,.25); + glColor3f(0,0,0); + glutSolidSphere(PupilSize, 10, 10); + glPopMatrix(); - + glPopMatrix(); } diff --git a/head.h b/head.h index 1e20c9bf95..f1318105d7 100644 --- a/head.h +++ b/head.h @@ -15,6 +15,7 @@ #include class Head { + float noise; float Pitch; float Yaw; float Roll; @@ -44,6 +45,7 @@ class Head { public: Head(void); void reset(); + void setNoise (float mag) { noise = mag; } void setPitch(float p) {Pitch = p; } void setYaw(float y) {Yaw = y; } void addPitch(float p) {Pitch -= p; } diff --git a/interface.xcodeproj/project.pbxproj b/interface.xcodeproj/project.pbxproj index 120d7e77e7..c61e0141b8 100644 --- a/interface.xcodeproj/project.pbxproj +++ b/interface.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ D4EE3BBE15E7465700EE4C89 /* field.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4EE3BBD15E7465700EE4C89 /* field.cpp */; }; D4EE3BC215E761B000EE4C89 /* util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4EE3BC115E761B000EE4C89 /* util.cpp */; }; D4EE3BC615EBD93600EE4C89 /* network.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4EE3BC515EBD93400EE4C89 /* network.cpp */; }; + D4EFE3D0162A2DA000DC5C59 /* hand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4EFE3CF162A2DA000DC5C59 /* hand.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -64,6 +65,8 @@ D4EE3BC315E7625000EE4C89 /* util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; D4EE3BC415EBD90C00EE4C89 /* network.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = network.h; sourceTree = ""; }; D4EE3BC515EBD93400EE4C89 /* network.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = network.cpp; sourceTree = ""; }; + D4EFE3CE162A2D7300DC5C59 /* hand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hand.h; sourceTree = ""; }; + D4EFE3CF162A2DA000DC5C59 /* hand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hand.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -113,6 +116,8 @@ D4EE3BBD15E7465700EE4C89 /* field.cpp */, D4B96D4715FF966200CE6E8B /* head.h */, D4B96D4815FF967C00CE6E8B /* head.cpp */, + D4EFE3CE162A2D7300DC5C59 /* hand.h */, + D4EFE3CF162A2DA000DC5C59 /* hand.cpp */, D4EE3BBF15E7467600EE4C89 /* field.h */, D4EE3BBA15E45FFE00EE4C89 /* SerialInterface.h */, D4EE3BBB15E45FFE00EE4C89 /* SerialInterface.cpp */, @@ -201,6 +206,7 @@ B6BDADD415F4085B002A07DF /* audio.cpp in Sources */, B6BDAE4415F6BE53002A07DF /* particle.cpp in Sources */, D4B96D4915FF967C00CE6E8B /* head.cpp in Sources */, + D4EFE3D0162A2DA000DC5C59 /* hand.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate b/interface.xcodeproj/project.xcworkspace/xcuserdata/philip.xcuserdatad/UserInterfaceState.xcuserstate index 0f0eea406579cd4f4f6fd7d0043ab37e0e134e87..0482ce5eb2a4acfad933912162ac9391e66fcddc 100644 GIT binary patch delta 33329 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 diff --git a/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist b/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist index e77afab681..3bc997fffe 100644 --- a/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist +++ b/interface.xcodeproj/xcuserdata/philip.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist @@ -19,11 +19,11 @@ ignoreCount = "0" continueAfterRunningActions = "No" filePath = "main.cpp" - timestampString = "371847418.921205" + timestampString = "371943667.487943" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "312" - endingLineNumber = "312" + startingLineNumber = "325" + endingLineNumber = "325" landmarkName = "init(void)" landmarkType = "7"> diff --git a/main.cpp b/main.cpp index 768db41083..e632210489 100644 --- a/main.cpp +++ b/main.cpp @@ -42,6 +42,7 @@ #include "network.h" #include "audio.h" #include "head.h" +#include "hand.h" //TGAImg Img; @@ -52,6 +53,8 @@ int serial_on = 0; // Are we using serial port for I/O? timeval begin_ping, end_ping; timeval timer_start, timer_end; +timeval last_frame; + double elapsedTime; // Socket operation stuff @@ -77,6 +80,7 @@ double ping = 0; #define TEXT_HEIGHT 14 Head myHead; // The rendered head of oneself or others +Hand myHand; // My hand (used to manipulate things in world) // Test data for creating fields that affect particles // If the simulation 'world' is a box with 10M boundaries, the offset to a field cell is given by: @@ -88,8 +92,9 @@ Head myHead; // The rendered head of oneself or others // y = (int)(i % 100 / 10) // x = (int)(i % 10) +#define RENDER_FRAME_MSECS 10 #define SLEEP 0 -#define NUM_TRIS 100000 +#define NUM_TRIS 20000 //000 struct { float vertices[NUM_TRIS * 9]; float normals [NUM_TRIS * 3]; @@ -121,7 +126,10 @@ float fwd_vel = 0.0f; #define MAX_FILE_CHARS 100000 // Biggest file size that can be read to the system int stats_on = 1; // Whether to show onscreen text overlay with stats -int noise_on = 0; // Whether to fire randomly + +int noise_on = 0; // Whether to add random noise +float noise = 1.0; // Overall magnitude scaling for random noise levels + int step_on = 0; int display_levels = 1; int display_head = 0; @@ -139,13 +147,23 @@ int speed; float mag_imbalance = 0.f; -int adc_channels[4]; // Measured input values for gyros, accelerometers +// +// Serial I/O channel mapping: +// +// 0 Head Gyro Pitch +// 1 Head Gyro Yaw +// 2 Head Accelerometer X +// 3 Head Accelerometer Z +// + +int adc_channels[4]; float avg_adc_channels[4]; - int first_measurement = 1; - -int framecount = 0; // Measure timing for framerate int samplecount = 0; + +// Frame rate Measurement + +int framecount = 0; float FPS = 120.f; void output(int x, int y, char *string) @@ -243,6 +261,11 @@ void init(void) field_init(); printf( "Field Initilialized.\n" ); + if (noise_on) + { + myHand.setNoise(noise); + myHead.setNoise(noise); + } /* const float FIELD_SCALE = 0.00005; @@ -329,6 +352,7 @@ void init(void) } gettimeofday(&timer_start, NULL); + gettimeofday(&last_frame, NULL); } void terminate () { @@ -437,14 +461,15 @@ void reset_sensors() head_mouse_x = WIDTH/2; head_mouse_y = HEIGHT/2; myHead.reset(); + myHand.reset(); if (serial_on) read_sensors(1, &avg_adc_channels[0], &adc_channels[0]); } void update_pos(float frametime) // Using serial data, update avatar/render position and angles { - float measured_yaw_rate = adc_channels[1] - avg_adc_channels[1]; float measured_pitch_rate = adc_channels[0] - avg_adc_channels[0]; + float measured_yaw_rate = adc_channels[1] - avg_adc_channels[1]; float measured_lateral_accel = adc_channels[2] - avg_adc_channels[2]; float measured_fwd_accel = avg_adc_channels[3] - adc_channels[3]; @@ -554,7 +579,6 @@ void display(void) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - glPushMatrix(); glEnable(GL_COLOR_MATERIAL); glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); @@ -563,7 +587,6 @@ void display(void) glLightfv(GL_LIGHT0, GL_POSITION, light_position0); GLfloat ambient_color[] = { 0.125, 0.305, 0.5 }; glLightfv(GL_LIGHT0, GL_AMBIENT, ambient_color); - //GLfloat diffuse_color[] = { 1.0, 0.84, 0.66}; GLfloat diffuse_color[] = { 0.5, 0.42, 0.33 }; glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse_color); GLfloat specular_color[] = { 1.0, 1.0, 1.0, 1.0}; @@ -571,10 +594,7 @@ void display(void) glMaterialfv(GL_FRONT, GL_SPECULAR, specular_color); glMateriali(GL_FRONT, GL_SHININESS, 96); - - - glPushMatrix(); - + // Rotate, translate to camera location glRotatef(render_pitch, 1, 0, 0); glRotatef(render_yaw, 0, 1, 0); @@ -620,79 +640,77 @@ void display(void) render_world_box(); - glPopMatrix(); // Display floating head in front of viewer if (display_head) { myHead.render(); } + myHand.render(); - glEnd(); - glPopMatrix(); // Render 2D overlay: I/O level bar graphs and text glMatrixMode(GL_PROJECTION); glPushMatrix(); - glLoadIdentity(); - gluOrtho2D(0, WIDTH, HEIGHT, 0); - glDisable(GL_DEPTH_TEST); - glDisable(GL_LIGHTING); + glLoadIdentity(); + gluOrtho2D(0, WIDTH, HEIGHT, 0); + glDisable(GL_DEPTH_TEST); + glDisable(GL_LIGHTING); - if (mouse_pressed == 1) - { - glPointSize(20.f); - glColor3f(1,1,1); - glEnable(GL_POINT_SMOOTH); - glBegin(GL_POINTS); - glVertex2f(target_x, target_y); - glEnd(); - } - if (display_head_mouse) - { - glPointSize(20.f); - glColor4f(1.0, 1.0, 0.0, 0.8); - glEnable(GL_POINT_SMOOTH); - glBegin(GL_POINTS); - glVertex2f(head_mouse_x, head_mouse_y); - glEnd(); - } - /* - if (display_ping) - { - // Draw a green dot to indicate receipt of ping signal - glPointSize(10.f); - if (display_ping == 2) - glColor4f(1.f, 0.f, 0.f, 1.f); - else - glColor4f(0.f, 1.f, 0.f, 1.f); - glBegin(GL_POINTS); - glVertex2f(50, 400); - glEnd(); - display_ping = 0; - } - */ - if (display_levels) - { - glColor4f(1.f, 1.f, 1.f, 1.f); - glBegin(GL_LINES); - glVertex2f(10, HEIGHT*0.95); - glVertex2f(10, HEIGHT*(0.25 + 0.75f*adc_channels[0]/4096)); - - glVertex2f(20, HEIGHT*0.95); - glVertex2f(20, HEIGHT*(0.25 + 0.75f*adc_channels[1]/4096)); - - glVertex2f(30, HEIGHT*0.95); - glVertex2f(30, HEIGHT*(0.25 + 0.75f*adc_channels[2]/4096)); - - glVertex2f(40, HEIGHT*0.95); - glVertex2f(40, HEIGHT*(0.25 + 0.75f*adc_channels[3]/4096)); - glEnd(); - - } + if (mouse_pressed == 1) + { + glPointSize(20.f); + glColor3f(1,1,1); + glEnable(GL_POINT_SMOOTH); + glBegin(GL_POINTS); + glVertex2f(target_x, target_y); + glEnd(); + } + if (display_head_mouse) + { + glPointSize(20.f); + glColor4f(1.0, 1.0, 0.0, 0.8); + glEnable(GL_POINT_SMOOTH); + glBegin(GL_POINTS); + glVertex2f(head_mouse_x, head_mouse_y); + glEnd(); + } + /* + if (display_ping) + { + // Draw a green dot to indicate receipt of ping signal + glPointSize(10.f); + if (display_ping == 2) + glColor4f(1.f, 0.f, 0.f, 1.f); + else + glColor4f(0.f, 1.f, 0.f, 1.f); + glBegin(GL_POINTS); + glVertex2f(50, 400); + glEnd(); + display_ping = 0; + } + */ + if (display_levels) + { + glColor4f(1.f, 1.f, 1.f, 1.f); + glBegin(GL_LINES); + glVertex2f(10, HEIGHT*0.95); + glVertex2f(10, HEIGHT*(0.25 + 0.75f*adc_channels[0]/4096)); + + glVertex2f(20, HEIGHT*0.95); + glVertex2f(20, HEIGHT*(0.25 + 0.75f*adc_channels[1]/4096)); + + glVertex2f(30, HEIGHT*0.95); + glVertex2f(30, HEIGHT*(0.25 + 0.75f*adc_channels[2]/4096)); + + glVertex2f(40, HEIGHT*0.95); + glVertex2f(40, HEIGHT*(0.25 + 0.75f*adc_channels[3]/4096)); + glEnd(); + + } - if (stats_on) display_stats(); + if (stats_on) display_stats(); glPopMatrix(); glutSwapBuffers(); @@ -707,7 +725,21 @@ void key(unsigned char k, int x, int y) if (k == 'q') ::terminate(); if (k == '/') stats_on = !stats_on; // toggle stats - if (k == 'n') noise_on = !noise_on; // toggle random mutation + if (k == 'n') + { + noise_on = !noise_on; // Toggle noise + if (noise_on) + { + myHand.setNoise(noise); + myHead.setNoise(noise); + } + else + { + myHand.setNoise(0); + myHead.setNoise(0); + } + + } if (k == 'h') display_head = !display_head; if (k == 'f') display_field = !display_field; if (k == 'e') location[1] -= WORLD_SIZE/100.0; @@ -751,17 +783,31 @@ void read_network() void idle(void) { - if (!step_on) glutPostRedisplay(); + timeval check; + gettimeofday(&check, NULL); + + // Check and render display frame + if (diffclock(last_frame,check) > RENDER_FRAME_MSECS) + { + // Simulation + update_pos(1.f/FPS); + update_tris(); + myHead.simulate(1.f/FPS); + myHand.simulate(1.f/FPS); + + if (!step_on) glutPostRedisplay(); + last_frame = check; + } + + // Read network packets read_network(); + // Read serial data if (serial_on) samplecount += read_sensors(0, &avg_adc_channels[0], &adc_channels[0]); - update_pos(1.f/FPS); - update_tris(); - myHead.simulate(1.f/FPS); + if (SLEEP) { usleep(SLEEP); } - } void reshape(int width, int height)