Added hand code to display/move a manipulator arm

This commit is contained in:
Philip Rosedale 2012-10-14 15:07:31 -07:00
parent 9507824986
commit 8b90a5d40c
10 changed files with 310 additions and 160 deletions

BIN
.DS_Store vendored

Binary file not shown.

View file

@ -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]);

59
hand.cpp Normal file
View file

@ -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;
}

36
hand.h Normal file
View file

@ -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 <iostream>
#include "util.h"
#include "field.h"
#include "world.h"
#include <GLUT/glut.h>
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

156
head.cpp
View file

@ -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();
}

2
head.h
View file

@ -15,6 +15,7 @@
#include <GLUT/glut.h>
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; }

View file

@ -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 = "<group>"; };
D4EE3BC415EBD90C00EE4C89 /* network.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = network.h; sourceTree = "<group>"; };
D4EE3BC515EBD93400EE4C89 /* network.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = network.cpp; sourceTree = "<group>"; };
D4EFE3CE162A2D7300DC5C59 /* hand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hand.h; sourceTree = "<group>"; };
D4EFE3CF162A2DA000DC5C59 /* hand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = hand.cpp; sourceTree = "<group>"; };
/* 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;
};

View file

@ -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">
</FileBreakpoint>

202
main.cpp
View file

@ -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)