13. Making a robot arm


3関節ロボットアーム(ソースコードはたった100行)
A robot arm simulator

This is the 13th ODE (Open Dynamics Engine) tutorial.

This time, let's make a simple three-articulated robot arm gathering knowlege so far.  Using the ODE,  you can make such a simulator only about 100 lines. Collision detections are omitted to simplify the sample program.  The robot can beoperated by a keyboard. The first joint can be moved by the j (increase) or f (decrease) key, d and k keys move the second joint, and l and s keys moves the third joints.

To move the joints, using a simple control, the P control, which controls the joint  proportional to the difference between the current value of the angular velocity and the target velocity.  The current value of joint angle values and goals are far apart, if you have a large angular velocity and angular velocity if the goal is the same as the value 0 to stop the next joint. Also, as the target for the current best value, you will be a negative sign for a reversal of rotation, and the current value is close to the target value.

The control function realizes that. dParamVel is the target angular velocity, and  dParamFMax is the maximum torque to realize the angular velocity. If dParamFMax is set to 0, you cannot control the joint, bacause the torque is not provied to the joint. t

The source code, sample13.cpp, can be downloaded from here.

C++:
  1. //  sample13.cpp  3 DOF manipulator by   Kosei Demura  2006-2008
  2. #include "ode/ode.h"                     // ODE
  3. #include "drawstuff/drawsutt.h"
  4. #define NUM 4         // Number of links
  5.  
  6. dWorldID    world;       // A dynamic world
  7. dBodyID     link[NUM];    // Links link[0] is a base
  8. dJointID      joint[NUM]// Joints    joint[0] is a fixed joint between a base and a ground
  9. static double THETA[NUM] = { 0.0, 0.0, 0.0, 0.0}// Target joint angles[rad]
  10. static double l[NUM]  = { 0.10, 0.90, 1.00, 1.00}// Length of links[m]
  11. static double r[NUM]  = { 0.20, 0.04, 0.04, 0.04}// Radius of links[m]
  12.  
  13. void control() {  /***  P control  ****/
  14.    static int step = 0;     // Steps of simulation
  15.    double k1 =  10.0,  fMax  = 100.0; // k1: proportional gain,  fMax:Max torque[Nm]
  16.    printf("\r%6d:",step++);
  17.    for (int j = 1; j <NUM; j++) {
  18.      double tmpAngle = dJointGetHingeAngle(joint[j])// Present angle[rad]
  19.      double z = THETA[j] - tmpAngle;  // z: residual=target angle - present angle
  20.      dJointSetHingeParam(joint[j], dParamVel, k1*z); // Set angular velocity[m/s]
  21.      dJointSetHingeParam(joint[j], dParamFMax, fMax); // Set max torque[N/m]
  22.    }
  23. }
  24.  
  25. void start() { /*** Initialize drawing API ***/
  26.   float xyz[3] = {  3.04, 1.28, 0.76};   // View point x, y, z [m]
  27.   float hpr[3] = { -160.0, 4.50, 0.00}// View direction(heading, pitch, roll) [°]
  28.   dsSetViewpoint(xyz,hpr);               // Set view point and direction
  29. }
  30.  
  31. void command(int cmd) { /*** Keyboard function ***/
  32.   switch (cmd) {
  33.   case ‘j'’:  THETA[1] += 0.05; break;  // When j key is pressed, THETA[1] is increases at 0.05[rad]
  34.   case 'f':  THETA[1] -= 0.05; break;
  35.  case 'j':  THETA[2] += 0.05; break;
  36.  case 'd':  THETA[2] -= 0.05; break;
  37.  case 'l':  THETA[3] += 0.05; break;
  38.  case 's':  THETA[3] -= 0.05; break;
  39.  }
  40.   if (THETA[1] <  - M_PI)   THETA[1] =  - M_PI;   if (THETA[1]>     M_PI)    THETA[1] =    M_PI;
  41.   if (THETA[2] < -2*M_PI/3)  THETA[2] =  - 2*M_PI/3;
  42.   if (THETA[2]>   2*M_PI/3)  THETA[2] =   2*M_PI/3;
  43.   if (THETA[3] < -2*M_PI/3)  THETA[3] =  - 2*M_PI/3;
  44.   if (THETA[3]>   2*M_PI/3)  THETA[3] =   2*M_PI/3;
  45. }
  46. // Simulation loop
  47. void simLoop(int pause) {
  48.   control();
  49.   dWorldStep(world, 0.02);
  50.   // Draw an robot
  51.   dsSetColor(1.0,1.0,1.0); // Set color (r, g, b), In this case white is set
  52.   for (int i = 0; i <NUM; i++ ) // Draw capsules for links of the robot
  53.     dsDrawCapsuleD(dBodyGetPosition(link[i]), dBodyGetRotation(link[i]), l[i], r[i]);
  54. }
  55. int main(int argc, char *argv[]) {
  56.   dsFunctions fn;
  57.   dMass mass;
  58.   double x[NUM] = {0.00}, y[NUM] = {0.00};  // Center of gravity
  59.   double z[NUM]         = { 0.05, 0.50, 1.50, 2.55};
  60.   double m[NUM] = {10.00, 2.00, 2.00, 2.00};       // mass
  61.   double anchor_x[NUM]  = {0.00}, anchor_y[NUM] = {0.00};// anchors of joints
  62.  double anchor_z[NUM] = { 0.00, 0.10, 1.00, 2.00};
  63.   double axis_x[NUM]  = { 0.00, 0.00, 0.00, 0.00};  // axises of joints
  64.   double axis_y[NUM]  = { 0.00, 0.00, 1.00, 1.00};
  65.   double axis_z[NUM]  = { 1.00, 1.00, 0.00, 0.00};
  66.   fn.version = DS_VERSION;  fn.start   = &start;
  67.   fn.step   = &simLoop;      fn.command = &command;
  68.   fn.path_to_textures = "../../drawstuff/textures";
  69.   dInitODE();  // Initialize ODE
  70.   world = dWorldCreate();  // Create a world
  71.   dWorldSetGravity(world, 0, 0, -9.8);
  72.   for (int i = 0; i <NUM; i++) {
  73.     link[i] = dBodyCreate(world);
  74.     dBodySetPosition(link[i], x[i], y[i], z[i]); // Set a position
  75.     dMassSetZero(&mass);      // Set mass parameter to zero
  76.     dMassSetCappedCylinderTotal(&mass,m[i],3,r[i],l[i]);  // Calculate mass parameter
  77.     dBodySetMass(link[i], &mass);  // Set mass
  78.   }
  79.   joint[0] = dJointCreateFixed(world, 0); // A fixed joint
  80.   dJointAttach(joint[0], link[0], 0);     // Attach the joint between the ground and the base
  81.   dJointSetFixed(joint[0]);               // Set the fixed joint
  82.   for (int j = 1; j <NUM; j++) {
  83.     joint[j] = dJointCreateHinge(world, 0); // Create a hinge joint
  84.     dJointAttach(joint[j], link[j-1], link[j]); // Attach the joint
  85.     dJointSetHingeAnchor(joint[j], anchor_x[j], anchor_y[j],anchor_z[j]);
  86.     dJointSetHingeAxis(joint[j], axis_x[j], axis_y[j], axis_z[j]);
  87.   }
  88.   dsSimulationLoop(argc, argv, 640, 570, &fn); // Simulation loop
  89.   dCloseODE();
  90.   return 0;
  91. }

That's all.  See you !

demu

Leave a Reply

カウンタ (since 2008-3-15)
Copyright © 1998-2008    Kosei Demura