PhidgetServo.cpp
Go to the documentation of this file.
00001 #include "ros/ros.h"
00002 #include <stdio.h>
00003 #include <phidget21.h>
00004 
00005 #include "corobot_srvs/GetEngaged.h"
00006 #include "corobot_srvs/SetEngaged.h"
00007 #include "corobot_srvs/GetPosition.h"
00008 #include "corobot_srvs/SetPosition.h"
00009 #include "corobot_srvs/GetMotorCount.h"
00010 #include "corobot_srvs/SetParam.h"
00011 #include "corobot_msgs/ServoPosition.h"
00012 #include "corobot_srvs/GetSerialNumber.h"
00013 #include "corobot_srvs/GetType.h"
00014 #include "corobot_srvs/SetType.h"
00015 #include "corobot_msgs/ServoType.h"
00016 #include <diagnostic_updater/diagnostic_updater.h>
00017 #include <diagnostic_updater/publisher.h>
00018 
00019 
00020 //Declare a servo handle
00021 CPhidgetAdvancedServoHandle servo = 0;
00022 ros::Publisher position_pub;
00023 int servoError = 0; // used for diagnostics purpose
00024 
00029 bool GetEngaged(corobot_srvs::GetEngaged::Request  &req,corobot_srvs::GetEngaged::Response &res )
00030 {
00031         int state;
00032         int err = CPhidgetAdvancedServo_getEngaged(servo, req.index, &state);
00033 
00034         res.state = state;
00035         return err;
00036 }
00037 
00042 bool SetEngaged(corobot_srvs::SetEngaged::Request  &req,corobot_srvs::SetEngaged::Response &res )
00043 {
00044         return CPhidgetAdvancedServo_setEngaged(servo,req.index, req.state);
00045 }
00046 
00051 bool GetPosition(corobot_srvs::GetPosition::Request  &req,corobot_srvs::GetPosition::Response &res )
00052 {
00053         double position;
00054         int err = CPhidgetAdvancedServo_getPosition(servo, req.index, &position);
00055         res.position = position;
00056         
00057         return err;
00058 }
00059 
00064 bool SetPosition(corobot_srvs::SetPosition::Request  &req,corobot_srvs::SetPosition::Response &res )
00065 {
00066         return CPhidgetAdvancedServo_setPosition(servo, req.index, req.position);
00067 }
00068 
00073 bool GetMotorCount(corobot_srvs::GetMotorCount::Request  &req,corobot_srvs::GetMotorCount::Response &res )
00074 {
00075         int count;
00076         int err = CPhidgetAdvancedServo_getMotorCount(servo, &count);
00077 
00078         res.numberMotors = count;
00079         return err;
00080 }
00081 
00086 bool GetPositionMax(corobot_srvs::GetPosition::Request  &req,corobot_srvs::GetPosition::Response &res )
00087 {
00088         double position;
00089         int err = CPhidgetAdvancedServo_getPositionMax(servo, req.index, &position);
00090 
00091         res.position = position;
00092         return err;
00093 }
00094 
00099 bool GetPositionMin(corobot_srvs::GetPosition::Request  &req,corobot_srvs::GetPosition::Response &res )
00100 {
00101         double position;
00102         int err = CPhidgetAdvancedServo_getPositionMax(servo, req.index, &position);
00103         
00104         res.position = position;
00105         return err;     
00106 }
00107 
00112 bool SetServoParameters(corobot_srvs::SetParam::Request  &req,corobot_srvs::SetParam::Response &res )
00113 {
00114         return CPhidgetAdvancedServo_setServoParameters(servo, req.index, req.min_us, req.max_us, req.degrees, req.velocity_max);
00115 }
00116 
00120 int PositionChangeHandler(CPhidgetAdvancedServoHandle phid, void *userPtr, int index, double position)
00121 {
00122         if(position_pub)
00123         {
00124                 corobot_msgs::ServoPosition position_msg;
00125                 position_msg.index = index;
00126                 position_msg.position = position;
00127                 position_pub.publish(position_msg);
00128         }
00129         return 0;
00130 }
00131 
00137 void setPositionCallback(const corobot_msgs::ServoPosition &msg)
00138 {
00139         ROS_INFO("phidget_servo, servo: %d, angle: %f", msg.index, msg.position);
00140         int err = CPhidgetAdvancedServo_setPosition(servo, msg.index, msg.position);
00141         if (err != 0)
00142         {
00143                 ROS_ERROR("Could not set the servo motor number %d to the position %f",msg.index, msg.position);
00144                 servoError = 3;
00145         }
00146 }
00147 
00151 int ErrorHandler(CPhidgetHandle SERV, void *userptr, int ErrorCode, const char *Description)
00152 {
00153         ROS_ERROR("Error Phidget Servo motor %d : %s",ErrorCode, Description);
00154         return 0;
00155 }
00156 
00161 bool GetSerialNumber(corobot_srvs::GetSerialNumber::Request  &req,corobot_srvs::GetSerialNumber::Response &res)
00162 {
00163         int serial;
00164         int err = CPhidget_getSerialNumber((CPhidgetHandle)servo, &serial);
00165         
00166         res.serialNumber = serial;
00167         return err;     
00168 }
00169 
00174 bool GetServoType(corobot_srvs::GetType::Request  &req,corobot_srvs::GetType::Response &res )
00175 {
00176         int type;
00177         int err = CPhidgetAdvancedServo_getServoType(servo, req.index, (CPhidget_ServoType *)type);
00178 
00179         res.type = type;
00180         return err;
00181 }
00182 
00187 bool SetServoType(corobot_srvs::SetType::Request  &req,corobot_srvs::SetType::Response &res )
00188 {
00189         return CPhidgetAdvancedServo_setServoType(servo, req.index, (CPhidget_ServoType)req.type);
00190 }
00191 
00197 void setTypeCallback(const corobot_msgs::ServoType &msg)
00198 {       
00199         CPhidgetAdvancedServo_setServoType(servo, msg.index, (CPhidget_ServoType)msg.type);
00200 }
00201 
00202 void servo_diagnostic(diagnostic_updater::DiagnosticStatusWrapper &stat)
00206 {
00207         if (!servoError)  
00208                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::OK, "intialized");
00209         else if(servoError == 1)
00210         {
00211                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR, "cannot be initialized");
00212                 stat.addf("Recommendation", "Please verify that the robot has a Phidget Servo Controller board. If present, please unplug and replug the Phidget Board USB cable from the Motherboard. Also, Please make sure that the phidget library is correctly installed.");
00213         }
00214 
00215         else if(servoError == 2)
00216         {
00217                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR, "cannot be attached");
00218                 stat.addf("Recommendation", "Please verify that the robot has a Phidget Servo Controller board. If present, please unplug and replug the Phidget Board USB cable from the Motherboard.");
00219         }
00220         else if(servoError == 3)
00221         {
00222                 stat.summaryf(diagnostic_msgs::DiagnosticStatus::ERROR, "cannot set position");
00223                 stat.addf("Recommendation", "Please verify that the servos are well connected to the Phidget Servo Controller Board.");
00224         }
00225 
00226 }
00227 
00228 
00229 int main(int argc, char* argv[])
00230 {
00231         ros::init(argc, argv, "phidget_servomotors");
00232         ros::NodeHandle n;
00233         ros::NodeHandle n_private("~");
00234         int serialNumber = -1;
00235         double minAccel, maxVel;
00236         int err;
00237 
00238         //create an updater that will send information on the diagnostics topics
00239         diagnostic_updater::Updater updater;
00240         updater.setHardwareIDf("Phidget");
00241         updater.add("Servo Controller", servo_diagnostic); //function that will be executed with updater.update()
00242         ros::Rate loop_rate(20);  //20 Hz
00243 
00244 
00245         //create the servo object
00246         err = CPhidgetAdvancedServo_create(&servo);
00247         if (err != 0)
00248         {
00249                 ROS_ERROR("error create the Phidget servo controller device");
00250                 servoError = 1;
00251         }
00252 
00253         //Set the handlers to be run when the device is plugged in or opened from software, unplugged or closed from software, or generates an error.
00254         CPhidget_set_OnError_Handler((CPhidgetHandle)servo, ErrorHandler, NULL);
00255 
00256         //Registers a callback that will run when the motor position is changed.
00257         //Requires the handle for the Phidget, the function that will be called, and an arbitrary pointer that will be supplied to the callback function (may be NULL).
00258         CPhidgetAdvancedServo_set_OnPositionChange_Handler(servo,PositionChangeHandler,NULL);
00259 
00260 
00261         n_private.param("serialNumber", serialNumber, -1);
00262 
00263         //open the servo for device connections
00264         err = CPhidget_open((CPhidgetHandle)servo, serialNumber);
00265         if (err != 0)
00266         {
00267                 ROS_ERROR("error opening the Phidget servo controller device");
00268                 servoError = 1;
00269         }
00270         if((err = CPhidget_waitForAttachment((CPhidgetHandle)servo, 10000)))
00271         {
00272                 ROS_ERROR("Problem waiting for attachment of Phidget servo controller");
00273                 servoError = 2;
00274         }
00275 
00276         //Engage every servo to make sure they are powered on, setup the acceleration value and setup the default position value. 
00277         for(int i=0;i<8;i++)
00278         {
00279                 err = CPhidgetAdvancedServo_getAccelerationMin(servo, i, &minAccel);
00280                 if (err != 0)
00281                         ROS_ERROR("error getting the acceleration min of the servo motor number %d",i);
00282                 err = CPhidgetAdvancedServo_setAcceleration(servo, i, minAccel*2);
00283                 if (err != 0)
00284                         ROS_ERROR("error setting the acceleration of the servo motor number %d",i);
00285                 err = CPhidgetAdvancedServo_getVelocityMax(servo, 0, &maxVel);
00286                 if (err != 0)
00287                         ROS_ERROR("error getting the max velocity of the servo motor number %d",i);
00288                 err = CPhidgetAdvancedServo_setVelocityLimit(servo, 0, maxVel/2);
00289                 if (err != 0)
00290                         ROS_ERROR("error setting the lvelocity limit of the servo motor number %d",i);
00291                 err = CPhidgetAdvancedServo_setEngaged(servo,i,1);
00292                 if (err != 0)
00293                         ROS_ERROR("error engaging the servo motor number %d",i);
00294         }       
00295         
00296         //setup the default type of servo motors
00297         err = CPhidgetAdvancedServo_setServoType(servo, 0, PHIDGET_SERVO_HITEC_HS645MG);
00298         if (err != 0)
00299                 ROS_ERROR("error setting up the type of the servo motor number: 0");
00300         err = CPhidgetAdvancedServo_setServoType(servo, 1, PHIDGET_SERVO_HITEC_HS645MG);
00301         if (err != 0)
00302                 ROS_ERROR("error setting up the type of the servo motor number: 1");
00303         err = CPhidgetAdvancedServo_setServoType(servo, 2, PHIDGET_SERVO_HITEC_HS422);
00304         if (err != 0)
00305                 ROS_ERROR("error setting up the type of the servo motor number: 2");
00306         err = CPhidgetAdvancedServo_setServoType(servo, 3, PHIDGET_SERVO_HITEC_HS422);
00307         if (err != 0)
00308                 ROS_ERROR("error setting up the type of the servo motor number: 3");
00309         err = CPhidgetAdvancedServo_setServoType(servo, 4, PHIDGET_SERVO_HITEC_HS645MG);
00310         if (err != 0)
00311                 ROS_ERROR("error setting up the type of the servo motor number: 4");
00312         err = CPhidgetAdvancedServo_setServoType(servo, 5, PHIDGET_SERVO_HITEC_HS645MG);
00313         if (err != 0)
00314                 ROS_ERROR("error setting up the type of the servo motor number: 5");
00315         err = CPhidgetAdvancedServo_setServoType(servo, 6, PHIDGET_SERVO_HITEC_HS422);
00316         if (err != 0)
00317                 ROS_ERROR("error setting up the type of the servo motor number: 6");
00318         err = CPhidgetAdvancedServo_setServoType(servo, 7, PHIDGET_SERVO_HITEC_HS422);
00319         if (err != 0)
00320                 ROS_ERROR("error setting up the type of the servo motor number: 7");
00321 
00322         //Declare every services
00323 
00324 
00325 
00326         ros::ServiceServer getEngaged = n.advertiseService("phidgetServo_getEngaged", GetEngaged);
00327         ros::ServiceServer setEngaged = n.advertiseService("phidgetServo_setEngaged", SetEngaged);
00328         ros::ServiceServer getPos = n.advertiseService("phidgetServo_getPosition", GetPosition);
00329         ros::ServiceServer setPos = n.advertiseService("phidgetServo_setPosition", SetPosition);
00330         ros::ServiceServer getPosMax = n.advertiseService("phidgetServo_getPositionMax", GetPositionMax);
00331         ros::ServiceServer getposMin = n.advertiseService("phidgetServo_getPositionMin", GetPositionMin);
00332         ros::ServiceServer getmotorCount = n.advertiseService("phidgetServo_getMotorCount", GetMotorCount);
00333         ros::ServiceServer setparam = n.advertiseService("phidgetServo_setServoParameters", SetServoParameters);
00334         ros::ServiceServer serialNumberService = n.advertiseService("phidgetServo_getSerialNumber", GetSerialNumber);
00335         ros::ServiceServer getType = n.advertiseService("phidgetServo_getServoType", GetServoType);
00336         ros::ServiceServer setType = n.advertiseService("phidgetServo_setServoType", SetServoType);
00337 
00338         //Declare every topics
00339         position_pub = n.advertise<corobot_msgs::ServoPosition>("phidgetServo_getPosition", 100);
00340 
00341         //Subscribe to every necessary topics
00342         ros::Subscriber position_sub = n.subscribe("phidgetServo_setPosition",100, &setPositionCallback);
00343         ros::Subscriber type_sub = n.subscribe("phidgetServo_setType",100, &setTypeCallback);
00344         
00345         while (ros::ok())
00346             {
00347                 updater.update();
00348                 ros::spinOnce();
00349                 loop_rate.sleep();
00350             }
00351 
00352 
00353         //Go back to the default position and disengage every servo motor before closing the servo handle
00354         for(int i=0;i<8;i++)
00355         {
00356                 err = CPhidgetAdvancedServo_setPosition (servo, i, 0.00);
00357                 err += CPhidgetAdvancedServo_setEngaged(servo,i,0);
00358                 if (err != 0)
00359                         ROS_ERROR("error closing the servo motor number : %d", i);
00360         }
00361 
00362         CPhidget_close((CPhidgetHandle)servo);
00363         CPhidget_delete((CPhidgetHandle)servo);
00364 
00365 }


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