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
00021 CPhidgetAdvancedServoHandle servo = 0;
00022 ros::Publisher position_pub;
00023 int servoError = 0;
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
00239 diagnostic_updater::Updater updater;
00240 updater.setHardwareIDf("Phidget");
00241 updater.add("Servo Controller", servo_diagnostic);
00242 ros::Rate loop_rate(20);
00243
00244
00245
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
00254 CPhidget_set_OnError_Handler((CPhidgetHandle)servo, ErrorHandler, NULL);
00255
00256
00257
00258 CPhidgetAdvancedServo_set_OnPositionChange_Handler(servo,PositionChangeHandler,NULL);
00259
00260
00261 n_private.param("serialNumber", serialNumber, -1);
00262
00263
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
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
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
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
00339 position_pub = n.advertise<corobot_msgs::ServoPosition>("phidgetServo_getPosition", 100);
00340
00341
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
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 }