/* kine4.c display four windows of data, control and report window */ /* 3D control system to reach 0,0,0 from negative X */ #include #include #include #include #define Pi 3.14159265358979323846 #undef abs #define abs(x) ((x)<0.0?(-(x)):(x)) static int XZw; /* XZ display window handle */ static int orthow; /* ortho display window handle */ static int XYw; /* XY display window handle */ static int YZw; /* YZ vector display window handle */ static int controlw; /* control window handle */ static int reportw; /* report window handle */ static int width = 300; /* window width */ static int height = 300; /* window height */ static int cwidth = 300; /* control width */ static int trace = 0; /* trace path */ static int run = 0; /* automatic run */ static float scale = 1.0; /* window scale */ static int xm; /* mouse x */ static int ym; /* mouse y corrected */ static double t = 0.0; /* simulation time */ static double dt = 0.02; /* simulation step time */ typedef struct {float x; float y; float z; float ax; float ay; float az;} ptype; static ptype p[8000]; /* for plotting lication each delta t */ static np = 0; static float view_theta = 22.0; /* object rotation about X axis */ static float view_phi = 16.0; /* object rotation about Z axis */ /* chosen control parameters */ static double kr = 3.0, ka = 8.0, kb = -3.0; /* was -1.5; */ /* chosen starting point */ static double dx, dy, dz; /* goal is origin */ /* state values in XY plane */ static double alpha, beta, theta, dalpha, dbeta, dtheta; static double rho, drho; /* state values in Z-XY plane */ static double alphaz, betaz, thetaz, dalphaz, dbetaz, dthetaz; static double rhoz, drhoz; static double dxy; /* length of XY projection */ static double ax, ay, az; static double delx, dely, delz, delxy, delax, delay, delaz; static int position = 0; static double dxp[16] = { 0.7, 0.0, -0.7, -1.0, -0.7, 0.0, 0.7, 1.0, 0.7, 0.0, -0.7, -1.0, -0.7, 0.0, 0.7, 1.0}; static double dyp[16] = { 0.7, 1.0, 0.7, 0.0, -0.7, -1.0, -0.7, 0.0, 0.6, 0.9, 0.6, 0.1, -0.6, -0.9, -0.6, -0.1}; static double dzp[16] = { 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, 0.7, -0.7, -0.7, -0.7, -0.7, -0.7, -0.7, -0.7, -0.7}; /* function prototypes */ static void init(void); static void physics(void); static void draw_box(float x1, float x2, float y1, float y2, float z1, float z2); static writeText(GLfloat x, GLfloat y, GLfloat z, GLfloat size, char * msg); static void display_XZ(void); static void display_ortho(void); static void display_XY(void); static void display_YZ(void); static void display_control(void); static void update_displays(void); /* all */ static void myinit(void); static void mouse(int btn, int state, int x, int y); static void mouse_control(int btn, int state, int x, int y); static int in_rect(int x, int y, int w, int h); static void keys(unsigned char key, int x, int y); static void reshape(int w, int h); static void runFunc(void); static void controlReshape(int w, int h); /* int main(int argc, char * argv[]); */ static void finish(void); static void init(void) { printf("kine4.c starting position %d\n", position); t = 0.0; dx = dxp[position]; /* delta position to origin */ dy = dyp[position]; dz = dzp[position]; alpha = Pi/8.0; /* velocity angle from robot X in Y direction */ theta = atan2(dy, dx); /* -(beta+alpha) angle robot X to inertial */ beta = -(theta+alpha); /* angle robot cg to goal */ rho = sqrt(dx*dx+dy*dy); dalpha = 0.0; dbeta = 0.0; dtheta = 0.0; drho = 0.0; dxy = rho; alphaz = Pi/10.0; /* velocity angle from robot X in Z direction */ thetaz = atan2(dz, dxy); /* in spherical, phi = Pi - thetaz */ betaz = -(thetaz+alphaz); rhoz = sqrt(dxy*dxy+dz*dz); /* = sqrt(dx*dx+dy*dy+dz*dz) */ dalphaz = 0.0; dbetaz = 0.0; dthetaz = 0.0; drhoz = 0.0; ax = 0.1*cos(theta+alpha); ay = 0.1*sin(theta+alpha); az = 0.1*cos(thetaz+alphaz); p[np].x = dx;; p[np].y = dy; p[np].z = dz; p[np].ax = ax; p[np].ay = ay; p[np].az = az; np++; } /* end init */ static void physics(void) { /* compute deltas from control system */ drho = -kr*rho*cos(alpha); dalpha = kr*sin(alpha) - ka*alpha - kb*beta; dbeta = -kr*sin(alpha); dtheta = -(dbeta+dalpha); drhoz = -kr*rhoz*cos(alphaz); dalphaz = kr*sin(alphaz) - ka*alphaz - kb*betaz; dbetaz = -kr*sin(alphaz); dthetaz = -(dbetaz+dalphaz); /* robot has to move distance drho*dt */ /* at angle theta+dtheta*dt */ delx = drho*dt*cos(theta+dtheta*dt); dx = dx + delx; dely = drho*dt*sin(theta+dtheta*dt); dy = dy + dely; rho = sqrt(dx*dx+dy*dy); theta = theta+dtheta*dt; alpha = -(theta - atan2(dy, dx)); beta = -(theta + alpha); delxy = drhoz*dt*cos(thetaz+dthetaz*dt); dxy = dxy + delxy; delz = drhoz*dt*sin(thetaz+dthetaz*dt); dz = dz + delz; rhoz = sqrt(dxy*dxy+dz*dz); thetaz = thetaz+dthetaz*dt; alphaz = -(thetaz - atan2(dz, dxy)); betaz = -(thetaz + alphaz); ax = 0.1*cos(theta+alpha); ay = 0.1*sin(theta+alpha); az = 0.1*cos(thetaz+alphaz); printf("delx=%f, dely=%f, delz=%f\n\n", delx, dely, delz); p[np].x = dx;; p[np].y = dy; p[np].z = dz; p[np].ax = ax; p[np].ay = ay; p[np].az = az; np++; if(np>7999) np--; t = t + dt; if(abs(dx)+abs(dy)+abs(dz)<0.01) { position++; if(position>15) { position = 0; run = 0; } init(); } } static writeText(GLfloat x, GLfloat y, GLfloat z, GLfloat size, char * msg) { char * p; glPushMatrix(); glLoadIdentity (); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glTranslatef(x, y, z); glScalef(size/1000.0, size/1000.0, 0.0); for(p=msg; *p; p++) glutStrokeCharacter(GLUT_STROKE_MONO_ROMAN, *p); glPopMatrix(); } /* end writeText, may have to reset glEnable's after call */ static void display_XZ(void) { int i; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glColor3f (0.0, 0.0, 0.0); glPointSize(2.0); glBegin(GL_POINTS); for(i=0; ix && xmy && ym