corobot_arm.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include <stdio.h>
00003 #include <math.h>
00004 
00005 #include "std_msgs/Float64.h"
00006 #include "corobot_msgs/MoveArm.h"
00007 #include "corobot_msgs/ServoPosition.h"
00008 #include "corobot_msgs/ServoType.h"
00009 
00010 typedef enum
00011 {
00012         base_rotation,
00013         shoulder,
00014         elbow,
00015         wrist_flex,
00016         wrist_rotation,
00017         gripper
00018 } servo_type;
00019 
00020 typedef enum
00021 {
00022         arbotix,
00023         ssc32,
00024         phidget
00025 } hardware_controller;
00026 
00027 typedef struct
00028 {
00029         servo_type type;
00030         int id;
00031         int min_angle;
00032         int max_angle; 
00033 } servo;
00034 
00035 int rotationPos, shoulderPos,elbowPos, wristPos, gripperPos;
00036 ros::Publisher position_pub, type_pub;
00037 double centerOffset;
00038 servo * servos = NULL;
00039 int number_servo = 0;
00040 hardware_controller controller;
00041 ros::Publisher * arbotix_publisher = NULL;
00042 
00046 void setServoPosition(const corobot_msgs::MoveArm &msg)
00047 {
00048         corobot_msgs::ServoPosition msg_sending;
00049         
00050         for(int i; i<number_servo; i++)
00051         {
00052                 msg_sending.index = -1;
00053 
00054                 //We received the indication on which servo we want to move, so now we are finding the index corresponding to the servo.  
00055                 if(msg.index == msg.BASE_ROTATION && servos[i].type == base_rotation)
00056                         msg_sending.index = servos[i].id;
00057                 if(msg.index == msg.SHOULDER && servos[i].type == shoulder)
00058                         msg_sending.index = servos[i].id;
00059                 if(msg.index == msg.ELBOW && servos[i].type == elbow)
00060                         msg_sending.index = servos[i].id;
00061                 if(msg.index == msg.WRIST_FLEX && servos[i].type == wrist_flex)
00062                         msg_sending.index = servos[i].id;
00063                 if(msg.index == msg.WRIST_ROTATION && servos[i].type == wrist_rotation)
00064                         msg_sending.index = servos[i].id;
00065                 if(msg.index == msg.GRIPPER && servos[i].type == gripper)
00066                         msg_sending.index = servos[i].id;
00067 
00068                 if(msg_sending.index != -1)
00069                 {
00070                         msg_sending.position = msg.position;
00071 
00072                         if(msg_sending.position < servos[i].min_angle)
00073                                 msg_sending.position = servos[i].min_angle;
00074                         else if(msg_sending.position > servos[i].max_angle)
00075                                 msg_sending.position = servos[i].max_angle;
00076 
00077                 
00078                         if(controller == arbotix)
00079                         {
00080                                 std_msgs::Float64 msg_arbotix;
00081                                 msg_arbotix.data = (msg_sending.position / 180) * M_PI; // the arbotix controller code take angles in radian and not degrees
00082                                 arbotix_publisher[i].publish(msg_arbotix);
00083                         }
00084                         else
00085                                 position_pub.publish(msg_sending);
00086                 }
00087         }
00088 }
00089 
00090 
00091 void init_servos_db(XmlRpc::XmlRpcValue dynamixels, ros::NodeHandle n)
00092 {
00093         if(dynamixels.hasMember("base"))
00094         {
00095                 servos[number_servo].type = base_rotation;
00096                 servos[number_servo].id = (int) dynamixels["base"]["id"];
00097                 servos[number_servo].min_angle = (int) dynamixels["base"]["min_angle"];
00098                 servos[number_servo].max_angle = (int) dynamixels["base"]["max_angle"];
00099 
00100                 if(controller == arbotix)
00101                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/base/command", 100);
00102 
00103                 number_servo++;
00104         }
00105         if(dynamixels.hasMember("shoulder"))
00106         {
00107                 servos[number_servo].type = shoulder;
00108                 servos[number_servo].id = (int) dynamixels["shoulder"]["id"];
00109                 servos[number_servo].min_angle = (int) dynamixels["shoulder"]["min_angle"];
00110                 servos[number_servo].max_angle = (int) dynamixels["shoulder"]["max_angle"];
00111 
00112                 if(controller == arbotix)
00113                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/shoulder/command", 100);
00114 
00115                 number_servo++;
00116         }
00117         if(dynamixels.hasMember("shoulder2"))
00118         {
00119                 servos[number_servo].type = shoulder;
00120                 servos[number_servo].id = (int) dynamixels["shoulder2"]["id"];
00121                 servos[number_servo].min_angle = (int) dynamixels["shoulder2"]["min_angle"];
00122                 servos[number_servo].max_angle = (int) dynamixels["shoulder2"]["max_angle"];
00123 
00124                 if(controller == arbotix)
00125                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/shoulder2/command", 100);
00126 
00127                 number_servo++;
00128         }
00129         if(dynamixels.hasMember("elbow"))
00130         {
00131                 servos[number_servo].type = elbow;
00132                 servos[number_servo].id = (int) dynamixels["elbow"]["id"];
00133                 servos[number_servo].min_angle = (int) dynamixels["elbow"]["min_angle"];
00134                 servos[number_servo].max_angle = (int) dynamixels["elbow"]["max_angle"];
00135 
00136                 if(controller == arbotix)
00137                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/elbow/command", 100);
00138         
00139                 number_servo++;
00140         }
00141         if(dynamixels.hasMember("elbow2"))
00142         {
00143                 servos[number_servo].type = elbow;
00144                 servos[number_servo].id = (int) dynamixels["elbow2"]["id"];
00145                 servos[number_servo].min_angle = (int) dynamixels["elbow2"]["min_angle"];
00146                 servos[number_servo].max_angle = (int) dynamixels["elbow2"]["max_angle"];
00147 
00148                 if(controller == arbotix)
00149                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/elbow2/command", 100);
00150 
00151                 number_servo++;
00152         }
00153         if(dynamixels.hasMember("wrist_flex"))
00154         {
00155                 servos[number_servo].type = wrist_flex;
00156                 servos[number_servo].id = (int) dynamixels["wrist_flex"]["id"];
00157                 servos[number_servo].min_angle = (int) dynamixels["wrist_flex"]["min_angle"];
00158                 servos[number_servo].max_angle = (int) dynamixels["wrist_flex"]["max_angle"];
00159 
00160                 if(controller == arbotix)
00161                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/wrist_flex/command", 100);
00162 
00163                 number_servo++;
00164         }
00165         if(dynamixels.hasMember("wrist_rotation"))
00166         {
00167                 servos[number_servo].type = wrist_rotation;
00168                 servos[number_servo].id = (int) dynamixels["wrist_rotation"]["id"];
00169                 servos[number_servo].min_angle = (int) dynamixels["wrist_rotation"]["min_angle"];
00170                 servos[number_servo].max_angle = (int) dynamixels["wrist_rotation"]["max_angle"];
00171 
00172                 if(controller == arbotix)
00173                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/wrist_rotation/command", 100);
00174 
00175                 number_servo++;
00176         }
00177         if(dynamixels.hasMember("gripper"))
00178         {
00179                 servos[number_servo].type = gripper;
00180                 servos[number_servo].id = (int) dynamixels["gripper"]["id"];
00181                 servos[number_servo].min_angle = -180;
00182                 servos[number_servo].max_angle = 180;
00183 
00184                 if(controller == arbotix)
00185                         arbotix_publisher[number_servo] = n.advertise<std_msgs::Float64>("/gripper/command", 100);
00186 
00187                 number_servo++;
00188         }
00189 }
00190 
00191 int main(int argc, char **argv)
00192 {
00193         ros::init(argc, argv, "corobot_arm");
00194         ros::NodeHandle n;
00195         ros::NodeHandle n_private("~");
00196 
00197 
00198         //Subscribe to topics
00199         ros::Subscriber armPos= n.subscribe("armPosition", 100, setServoPosition); //Command received by corobot_teleop or any other controlling node
00200 
00201         //Read the index of each servos.
00202         //n_private.param("rotation", rotationPos, -1);
00203         //n_private.param("shoulder", shoulderPos, 0);
00204         //n_private.param("elbow", elbowPos, 1);
00205         //n_private.param("wrist", wristPos, 2);
00206         //n_private.param("gripper", gripperPos, 3);
00207 
00208         //Set up an offset, in case the servo in not at its default position when it is supposed to  
00209         n_private.param("offset", centerOffset, 0.0);
00210 
00211 
00212         //Read yalm file parameters.
00213         XmlRpc::XmlRpcValue dynamixels;
00214         XmlRpc::XmlRpcValue controller_type;
00215         n_private.param("dynamixels", dynamixels, dynamixels);
00216         n_private.param("controller_type", controller_type, controller_type);
00217 
00218         //Read the type of arm we are controlling
00219         if (strcmp(static_cast<std::string>(controller_type).c_str(), "arbotix") == 0)
00220         {
00221                         controller = arbotix;
00222                         arbotix_publisher = new ros::Publisher[dynamixels.size()];
00223         }
00224         else if (strcmp(static_cast<std::string>(controller_type).c_str(), "ssc32") == 0)
00225         {
00226                         controller = ssc32;
00227         }
00228         else if (strcmp(static_cast<std::string>(controller_type).c_str(), "phidget") == 0)
00229         {
00230                         controller = phidget;
00231         }
00232         //Read information about the servos
00233         servos = (servo*) malloc(dynamixels.size() * sizeof(servo));
00234         init_servos_db(dynamixels, n_private);
00235 
00236 
00237         //Declare the necessary topics and set up the type of servos
00238         if(controller == phidget) 
00239         {
00240                 position_pub = n.advertise<corobot_msgs::ServoPosition>("setPositionServo", 100); //Set the position of the servo. Use for phidgetServo and corobot_ssc32
00241                 type_pub = n.advertise<corobot_msgs::ServoType>("phidgetServo_setType", 100); //Set the type of servos. PhidgetServo needs it.
00242 
00243                 corobot_msgs::ServoType typeMsg;
00244 
00245                 typeMsg.index = shoulderPos;
00246                 typeMsg.type = 11;
00247                 type_pub.publish(typeMsg);
00248                 typeMsg.index = elbowPos;
00249                 type_pub.publish(typeMsg);
00250                 typeMsg.index = wristPos;
00251                 typeMsg.type = 6;
00252                 type_pub.publish(typeMsg);
00253                 typeMsg.index = gripperPos;
00254                 type_pub.publish(typeMsg);
00255         }
00256         else if (controller == ssc32)
00257         {
00258                 position_pub = n.advertise<corobot_msgs::ServoPosition>("setPositionServo", 100); //Set the position of the servo. Use for phidgetServo and corobot_ssc32
00259         }
00260 
00261 
00262         if(controller == phidget || controller == ssc32)
00263         { 
00264                 //Make sure that the arm is in the default initial position for non arbotix arms (wrist horizontal, gripper open and shoulder and elbow angle at 0)
00265                 corobot_msgs::ServoPosition msg;
00266 
00267                 ros::spinOnce();
00268                 ros::Rate loop_rate(0.5);  //We wait 2s to make sure that the node PhidgetServo has already subscribed to the topic
00269                 loop_rate.sleep();
00270 
00271                 if (rotationPos != -1)
00272                 {
00273                         msg.index = rotationPos;
00274                         msg.position = 90.0;
00275                         position_pub.publish(msg);
00276                 }       
00277 
00278                 msg.index = shoulderPos;
00279                 msg.position = 0.0;
00280                 position_pub.publish(msg);
00281 
00282                 msg.index = elbowPos;
00283                 msg.position = 0.0;
00284                 position_pub.publish(msg);
00285 
00286                 msg.index = wristPos;
00287                 msg.position = 90.0;
00288                 position_pub.publish(msg);
00289 
00290                 msg.index = gripperPos;
00291                 msg.position = 0.0;
00292                 position_pub.publish(msg);
00293         }
00294 
00295         ros::spin();
00296         
00297         free(servos);
00298         delete[] arbotix_publisher;
00299         return 0;
00300 }


corobot_arm
Author(s): Morgan Cormier/mcormier@coroware.com
autogenerated on Tue Jan 7 2014 11:39:14