00001 #include "epos_driver/epos_driver.hpp"
00002
00003
00004
00005
00006
00007
00008
00019 eposdriver::eposdriver(ros::NodeHandle parameters){
00020 parameters.param<std::string>("port",port,"/dev/usb0");
00021 parameters.param<bool>("use_radps",useRadps,true);
00022 parameters.param<double>("max_velocity_radps",pMaxVelocityRadps,0.4);
00023 parameters.param<double>("accel_radpss",pAccelRadpss,0.02);
00024 parameters.param<double>("deccel_radpss",pDeccelRadpss,0.02);
00025 parameters.param<int>("max_velocity_rpm",pMaxVelocityRpm,57);
00026 parameters.param<int>("accel_rpmps",pAccelRpmps,2);
00027 parameters.param<int>("deccel_rpmps",pDeccelRpmps,2);
00028 parameters.param<bool>("use_trapezoidal",useTrapezoidal,false);
00029 parameters.param<double>("topic_frequency",topicFrequency,20);
00030 parameters.param<std::string>("my_frame_id", myFrameId, "maxon");
00031 parameters.param<std::string>("parent_frame_id", parentFrameId, "base");
00032 parameters.param<double>("sensor_pose_x", sensorPoseX, 0.0);
00033 parameters.param<double>("sensor_pose_y", sensorPoseY, 0.0);
00034 parameters.param<double>("sensor_pose_z", sensorPoseZ, 0.0);
00035 parameters.param<int>("treshold_ticks",tresholdTicks,10);
00036 parameters.param<int>("time_shift",timeShift,6);
00037
00038 if(useRadps){
00039 maxVelocity=Radps2rpm(pMaxVelocityRadps);
00040 accel=Radps2rpm(pAccelRadpss);
00041 deccel=Radps2rpm(pAccelRadpss);
00042 }
00043 else{
00044 maxVelocity=pMaxVelocityRpm;
00045 accel=pAccelRpmps;
00046 deccel=pAccelRpmps;
00047 }
00048 }
00049
00050
00051
00052
00053
00054
00062
00063
00064
00065 int eposdriver::On(){
00066 WORD eposStatus=0x0;
00067 int eposState=0;
00068 char deviceName[128];
00069 int functionReturns;
00070 unsigned long win;
00071 long pos = -99;
00072 ROS_INFO("*** EPOS driver initialising ***");
00073 ROS_INFO("Openning the device. Port: %s",port.c_str());
00074 if(openEPOS(const_cast<char *>(port.c_str()))<0){
00075 ROS_ERROR("Could not open EPOS on port: %s.",port.c_str());
00076 ROS_ERROR("EXITING NODE");
00077 ros::shutdown();
00078 }
00079 else{
00080 ROS_INFO("EPOS on port %s opened.",port.c_str());
00081 }
00082
00083 if(readDeviceName(deviceName)<0){
00084 ROS_ERROR("Could not read the device name");
00085 }
00086 else{
00087 ROS_INFO("Connected device name is: %s",deviceName);
00088 }
00089
00090 functionReturns=readSWversion();
00091 if(functionReturns<0){
00092 ROS_ERROR("Could not read the software version");
00093 }
00094 else{
00095 ROS_INFO("Software version is is: %x",functionReturns);
00096 }
00097
00098 functionReturns=readRS232timeout();
00099 if(functionReturns<0){
00100 ROS_ERROR("Could not read the RS232 timeout");
00101 EposError();
00102 }
00103 else{
00104 ROS_INFO("RS232 timeout is: %d ms\n", functionReturns);
00105 }
00106
00107 ROS_INFO("*** Checking EPOS status ***");
00108 functionReturns = readStatusword(&eposStatus);
00109 if (functionReturns<0){
00110 ROS_ERROR("Could not check EPOS status");
00111 EposError();
00112 }
00113 else{
00114 ROS_INFO("EPOS status is: %#06x \n",eposStatus);
00115 }
00116 ROS_INFO("*** Switching on EPOS ***");
00117 eposState=checkEPOSstate();
00118 ROS_INFO("EPOS state; %d:",eposState);
00119 if (eposState==11){
00120 ROS_INFO("EPOS is in FAULT state, doing FAULT RESET.");
00121 changeEPOSstate(6);
00122 eposState=checkEPOSstate();
00123 if(eposState==11){
00124 ROS_ERROR("EPOS still in FAULT state, quit!");
00125 EposError();
00126 return -1;
00127 }
00128 else{
00129 ROS_INFO("Success! (Now in state %d)", eposState);
00130 }
00131 }
00132 if(eposState!=4 && eposState!=7) {
00133 ROS_INFO("EPOS is in FAULT state, doing FAULT RESET.");
00134 changeEPOSstate(3);
00135 eposState=checkEPOSstate();
00136 if (eposState!=2){
00137 ROS_ERROR("EPOS is NOT in 'switch on disabled' state, quit!");
00138 return -1;
00139 }
00140 else {
00141 ROS_INFO("EPOS is in 'switch on disabled' state, doing shutdown.");
00142 changeEPOSstate(0);
00143 }
00144 ROS_INFO("Switching on EPOS");
00145 changeEPOSstate(1);
00146 ROS_INFO("Enable operation" );
00147 changeEPOSstate(5);
00148 }
00149 EposState();
00150 readPositionWindow(&win);
00151 ROS_INFO("EPOS position window is %lu.", win);
00152 readActualPosition(&pos);
00153 ROS_INFO("Please wait until homing complete...");
00154 if (setHomePolarity(1)) {
00155 ROS_ERROR(" *** UNABLE TO SET HomeSwitch TO low-active!!! ***");
00156 }
00157 while ((functionReturns= doHoming(18,0))!=0){
00158 ROS_ERROR("#### doHoming() returned %d ####", functionReturns);
00159 changeEPOSstate(5);
00160 }
00161 if(setOpMode(1)){
00162 ROS_ERROR("Error with setOpMode(1)");
00163 return(-1);
00164 }
00165 EposState();
00166 readActualPosition(&pos);
00167 ROS_INFO("EPOS position is %ld.", pos);
00168 motorState=1;
00169 moduleCount=1;
00170 ROS_INFO("Prameters %d %d %d", maxVelocity,accel,deccel);
00171 set_speed_profile(maxVelocity,accel,deccel,useTrapezoidal);
00172 ROS_INFO("EPOS driver is reday");
00173 return(0);
00174 }
00175
00176
00177
00178
00179
00180
00182 int eposdriver::Off(){
00183 ROS_INFO("Shutting EPOS driver down");
00184 if(closeEPOS()<0){
00185 ROS_ERROR("Failure druing shooting down");
00186 return -1;
00187 }
00188 else{
00189 ROS_INFO("EPOS driver has been shutdown");
00190 }
00191 return 0;
00192 }
00193
00194
00195
00196
00197
00198
00203
00204
00205 int eposdriver::Main(){
00206 long rawPosition;
00207 double pos;
00208 long rawSpeed;
00209 double speed;
00210 double acceleration;
00211 short current;
00212 long oldSpeed;
00213 float deltaSpeed;
00214 bool validDeltaSpeed(false);
00215 moveSingle=true;
00216 synchronize=true;
00217 epos_driver::EPOSState msg;
00218 ros::Time then;
00219 ros::Time now;
00220 ros::Duration elapsedTime;
00221 static const double mradPerTick=0.000209;
00222
00223 statePublisher=nodeHandler.advertise<epos_driver::EPOSState>("EPOSState",1000);
00224 ros::ServiceServer MoveToService=nodeHandler.advertiseService("MoveTo",&eposdriver::MoveTo,this);
00225 ros::ServiceServer MoveCycleService=nodeHandler.advertiseService("MoveCycle",&eposdriver::MoveCycle,this);
00226 tf::Transform transform;
00227 static tf::TransformBroadcaster tfPublisher;
00228
00229 ros::Time time_framerate_start;
00230 ros::Time time_framerate_end;
00231 ros::Time time_realtime_start;
00232 ros::Time time_realtime_end;
00233
00234 time_framerate_start=ros::Time::now();
00235 time_realtime_start=time_framerate_start;
00236
00237 while(ros::ok()){
00238 time_realtime_end=ros::Time::now();
00239
00240 time_realtime_start=ros::Time::now();
00241
00242 oldSpeed=speed;
00243 then=now;
00244 now=ros::Time::now();
00245 readActualVelocity(&rawSpeed);
00246 readActualPosition(&rawPosition);
00247 readActualCurrent(¤t);
00248 pos=mradPerTick*static_cast<double>(rawPosition);
00249 speed=mradPerTick*static_cast<double>(rawSpeed);
00250 if(validDeltaSpeed){
00251 deltaSpeed=speed-oldSpeed;
00252 elapsedTime=now-then;
00253 acceleration=deltaSpeed/elapsedTime.toSec();
00254 }
00255 else{
00256 acceleration=0;
00257 }
00258 if(!validDeltaSpeed)
00259 validDeltaSpeed=true;
00260 msg.header.stamp=ros::Time::now();
00261 msg.raw_position=rawPosition;
00262 msg.position=pos;
00263 msg.raw_speed=rawSpeed;
00264 msg.speed=speed;
00265 msg.acceleration=acceleration;
00266 msg.current=current;
00267 if(moveSingle){
00268 if(speed==0.0)
00269 synchronize=true;
00270 else
00271 synchronize=false;
00272 }
00273 if(!moveSingle){
00274 if(moveDown){
00275 synchronize=false;
00276 if(rawPosition>=int(highLimit/mradPerTick)-tresholdTicks){
00277 synchronize=true;
00278 moveAbsolute(lowLimit/mradPerTick);
00279 moveUp=true;
00280 moveDown=false;
00281 }
00282 }
00283 else if(moveUp){
00284 synchronize=false;
00285 if(rawPosition<=int(lowLimit/mradPerTick)+tresholdTicks){
00286 synchronize=true;
00287 moveAbsolute(highLimit/mradPerTick);
00288 moveUp=false;
00289 moveDown=true;
00290 }
00291 }
00292 }
00293 msg.sync=synchronize;
00294 transform.setOrigin(tf::Vector3(sensorPoseX,sensorPoseY,sensorPoseZ));
00295 transform.setRotation(tf::createQuaternionFromRPY(0.0,0.0,pos));
00296 tfPublisher.sendTransform(tf::StampedTransform(transform,ros::Time::now()+ros::Duration(0,timeShift), parentFrameId, myFrameId));
00297 statePublisher.publish(msg);
00298 time_framerate_end=ros::Time::now();
00299 ros::Duration elapsed=time_framerate_end-time_framerate_start;
00300 ros::Duration sleep_;
00301 if (ros::Duration(1/topicFrequency)-elapsed<ros::Duration(0))
00302 sleep_= ros::Duration(0);
00303 else
00304 sleep_= ros::Duration(1/topicFrequency)-elapsed;
00305 ros::Duration(sleep_).sleep();
00306 time_framerate_start=ros::Time::now();
00307 ros::spinOnce();
00308
00309 }
00310 return 0;
00311 }
00312
00313
00314
00315
00316
00317
00318
00325
00326
00327 unsigned int eposdriver::Radps2rpm(double radps){
00328 static const double mradPerTick=1000.0*0.000209;
00329 static const double radpsToRpm = 3.0*10.0*100.0*1000.0/mradPerTick/1000.0;
00330 ROS_INFO("value %f -> %d",radps*radpsToRpm,int(radps*radpsToRpm));
00331 return int(radps*radpsToRpm);
00332 }
00333
00334
00335
00336
00337
00338
00339
00345 int eposdriver::EposError(){
00346 switch(E_error) {
00347 case E_NOERR:
00348 return(0);
00349 case E_ONOTEX:
00350 ROS_ERROR("EPOS responds with error: requested object does not exist!"); break;
00351 case E_SUBINEX:
00352 ROS_ERROR("EPOS responds with error: requested subindex does not exist!"); break;
00353 case E_OUTMEM:
00354 ROS_ERROR("EPOS responds with error: out of memory!"); break;
00355 case E_NOACCES:
00356 ROS_ERROR("EPOS responds with error: unsupported access to an object!"); break;
00357 case E_WRITEONLY:
00358 ROS_ERROR("EPOS responds with error: attempt to read a write-only object!"); break;
00359 case E_READONLY:
00360 ROS_ERROR("EPOS responds with error: attempt to write a read-only object!"); break;
00361 case E_PARAMINCOMP:
00362 ROS_ERROR("EPOS responds with error: general parameter incompatibility!"); break;
00363 case E_INTINCOMP:
00364 ROS_ERROR("EPOS responds with error: general internal incompatibility in the device!"); break;
00365 case E_HWERR:
00366 ROS_ERROR("EPOS responds with error: access failed due to an HARDWARE ERROR!"); break;
00367 case E_PRAGNEX:
00368 ROS_ERROR("EPOS responds with error: value range of parameter exeeded!"); break;
00369 case E_PARHIGH:
00370 ROS_ERROR("EPOS responds with error: value of parameter written is too high!"); break;
00371 case E_PARLOW:
00372 ROS_ERROR("EPOS responds with error: value of parameter written is too low!"); break;
00373 case E_PARREL:
00374 ROS_ERROR("EPOS responds with error: maximum value is less than minimum value!"); break;
00375 case E_NMTSTATE:
00376 ROS_ERROR("EPOS responds with error: wrong NMT state!"); break;
00377 case E_RS232:
00378 ROS_ERROR("EPOS responds with error: rs232 command illegeal!"); break;
00379 case E_PASSWD:
00380 ROS_ERROR("EPOS responds with error: password incorrect!"); break;
00381 case E_NSERV:
00382 ROS_ERROR("EPOS responds with error: device not in service mode!"); break;
00383 case E_NODEID:
00384 ROS_ERROR("EPOS responds with error: error in Node-ID!"); break;
00385 default:
00386 ROS_ERROR("EPOS responds with error: unknown EPOS error code: %#lx",E_error); break;
00387 }
00388 return(-1);
00389 }
00390
00391
00392
00393
00394
00395
00396
00402 int eposdriver::EposState(){
00403 switch(checkEPOSstate()){
00404 case 0: ROS_INFO("EPOS is in state: start"); break;
00405 case 1: ROS_INFO("EPOS is in state: Not ready to switch on."); break;
00406 case 2: ROS_INFO("EPOS is in state: Switch on disabled."); break;
00407 case 3: ROS_INFO("EPOS is in state: Ready to switch on."); break;
00408 case 4: ROS_INFO("EPOS is in state: Switched on."); break;
00409 case 5: ROS_INFO("EPOS is in state: Refresh."); break;
00410 case 6: ROS_INFO("EPOS is in state: Measure init."); break;
00411 case 7: ROS_INFO("EPOS is in state: Operation enable."); break;
00412 case 8: ROS_INFO("EPOS is in state: Quick stop active"); break;
00413 case 9: ROS_INFO("EPOS is in state: Fault reaction active (disabled)"); break;
00414 case 10: ROS_INFO("EPOS is in state: Fault reaction active (enabled)"); break;
00415 case 11: ROS_INFO("EPOS is in state: FAULT\n"); break;
00416 default:
00417 ROS_INFO("EPOS is in state: UNKNOWN!\n");
00418 return(-1);
00419 }
00420 return(0);
00421 }
00422
00423
00424
00425
00426
00427
00432 bool eposdriver::MoveTo(epos_driver::MoveTo::Request &req,epos_driver::MoveTo::Response &res){
00433 static const float radPerTick = 0.000209;
00434 moveAbsolute(req.pose/radPerTick);
00435 moveSingle=true;
00436 return true;
00437 }
00438
00439
00440
00441
00442
00443
00444
00449 bool eposdriver::MoveCycle(epos_driver::MoveCycle::Request &req,epos_driver::MoveCycle::Response &res){
00450 static const float radPerTick = 0.000209;
00451 long rawSpeed;
00452 highLimit=req.pose_top;
00453 lowLimit=req.pose_bottom;
00454 moveAbsolute(highLimit/radPerTick);
00455 if(highLimit>lowLimit){
00456 do{
00457 readActualVelocity(&rawSpeed);
00458 ros::Duration(0.1).sleep();
00459 }while(rawSpeed!=0);
00460 moveSingle=false;
00461 moveUp=false;
00462 moveDown=true;
00463 }
00464 else {
00465 ROS_ERROR("Limits of motion wrongly setted!");
00466 }
00467 return true;
00468 }
00469