00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00104 #ifdef HAVE_CONFIG_H
00105 #include "config.h"
00106 #endif
00107
00108 #include <unistd.h>
00109 #include <inttypes.h>
00110 #include <stdio.h>
00111 #include <string.h>
00112 #include <math.h>
00113 #include <stdlib.h>
00114
00115 #include <fcntl.h>
00116 #include <linux/serial.h>
00117 #include <signal.h>
00118 #include <sys/stat.h>
00119 #include <sys/types.h>
00120 #include <netinet/in.h>
00121 #include <termio.h>
00122 #include <termios.h>
00123 #include <sys/socket.h>
00124 #include <netinet/tcp.h>
00125 #include <netdb.h>
00126
00127 #include "wbr914.h"
00128
00129 #undef PLAYER_MSG0
00130 #define PLAYER_MSG0(a,b) LogMe(b)
00131
00132 static void LogMe( const char* s )
00133 {
00134 FILE* fp = fopen( "plog", "a+" );
00135 fprintf( fp, s );
00136 fclose( fp );
00137 }
00138
00139
00140
00141 Driver* wbr914_Init(ConfigFile* cf, int section)
00142 {
00143 return (Driver*)(new wbr914(cf,section));
00144 }
00145
00146 void wbr914_Register(DriverTable* table)
00147 {
00148 table->AddDriver("wbr914", wbr914_Init);
00149 }
00150
00151 wbr914::wbr914(ConfigFile* cf, int section)
00152 : Driver(cf,section,true,PLAYER_MSGQUEUE_DEFAULT_MAXLEN),
00153 _tioChanged( false ),
00154 _stopped( true ), _motorsEnabled( false ), _lastDigOut( 0 )
00155 {
00156 last_lpos = 0;
00157 last_rpos = 0;
00158
00159
00160 _baud = 416666;
00161
00162 ErrorInit( 9 );
00163
00164
00165
00166 memset(&this->position_id, 0, sizeof(player_devaddr_t));
00167 memset(&this->ir_id, 0, sizeof(player_devaddr_t));
00168
00169 memset(&this->last_position_cmd, 0, sizeof(player_position2d_cmd_vel_t));
00170
00171 this->position_subscriptions = 0;
00172 this->ir_subscriptions = 0;
00173
00174
00175 if(cf->ReadDeviceAddr(&(this->position_id), section, "provides",
00176 PLAYER_POSITION2D_CODE, -1, NULL) == 0)
00177 {
00178 if(this->AddInterface(this->position_id) != 0)
00179 {
00180 this->SetError(-1);
00181 return;
00182 }
00183 }
00184
00185
00186 if(cf->ReadDeviceAddr(&(this->ir_id), section, "provides",
00187 PLAYER_IR_CODE, -1, NULL) == 0)
00188 {
00189 if(this->AddInterface(this->ir_id) != 0)
00190 {
00191 this->SetError(-1);
00192 return;
00193 }
00194 }
00195
00196
00197 if(cf->ReadDeviceAddr(&(this->aio_id), section, "provides",
00198 PLAYER_AIO_CODE, -1, NULL) == 0)
00199 {
00200 if(this->AddInterface(this->aio_id) != 0)
00201 {
00202 this->SetError(-1);
00203 return;
00204 }
00205 }
00206
00207
00208 if(cf->ReadDeviceAddr(&(this->dio_id), section, "provides",
00209 PLAYER_DIO_CODE, -1, NULL) == 0)
00210 {
00211 if(this->AddInterface(this->dio_id) != 0)
00212 {
00213 this->SetError(-1);
00214 return;
00215 }
00216 }
00217
00218
00219
00220 _serial_port = cf->ReadString(section,"port",DEFAULT_M3_PORT);
00221 _percentTorque = cf->ReadInt(section,"torque", DEFAULT_PERCENT_TORQUE );
00222 _debug = cf->ReadInt(section,"debug",0 );
00223 _fd = -1;
00224
00225
00226
00227
00228
00229 if ( _percentTorque > 100 )
00230 {
00231 _percentTorque = 100;
00232 }
00233 else if ( _percentTorque < 20 )
00234 {
00235 _percentTorque = 20;
00236 }
00237
00238
00239
00240 memset(&_robot2d_geom, 0, sizeof(_robot2d_geom));
00241
00242
00243
00244
00245
00246
00247
00248
00249 _robot2d_geom.size.sw = 0.37;
00250
00251 _robot2d_geom.size.sl = 0.42;
00252 _robot2d_geom.size.sh = 0.3;
00253
00254 _robot3d_geom.pose = _robot2d_geom.pose;
00255 _robot3d_geom.size = _robot2d_geom.size;
00256
00257
00258
00259
00260
00261
00262
00263 _ir_geom.poses_count = NUM_IR_SENSORS;
00264 _ir_geom.poses = new player_pose3d_t[_ir_geom.poses_count];
00265
00266 _ir_geom.poses[ 0 ].px = 0.030;
00267 _ir_geom.poses[ 0 ].py = -0.190;
00268 _ir_geom.poses[ 0 ].pyaw = DTOR( -90 );
00269
00270 _ir_geom.poses[ 1 ].px = 0.190;
00271 _ir_geom.poses[ 1 ].py = -0.090;
00272 _ir_geom.poses[ 1 ].pyaw = DTOR( -30 );
00273
00274 _ir_geom.poses[ 2 ].px = 0.210;
00275 _ir_geom.poses[ 2 ].py = 0.0;
00276 _ir_geom.poses[ 2 ].pyaw = DTOR( 0 );
00277
00278 _ir_geom.poses[ 3 ].px = 0.190;
00279 _ir_geom.poses[ 3 ].py = 0.090;
00280 _ir_geom.poses[ 3 ].pyaw = DTOR( 30 );
00281
00282 _ir_geom.poses[ 4 ].px = 0.030;
00283 _ir_geom.poses[ 4 ].py = 0.190;
00284 _ir_geom.poses[ 4 ].pyaw = DTOR( 90 );
00285
00286
00287
00288
00289 _ir_geom.poses[ 5 ].px = 0.200;
00290 _ir_geom.poses[ 5 ].py = -0.060;
00291 _ir_geom.poses[ 5 ].pyaw = DTOR( -60 );
00292
00293 _ir_geom.poses[ 6 ].px = 0.210;
00294 _ir_geom.poses[ 6 ].py = 0.0;
00295 _ir_geom.poses[ 6 ].pyaw = DTOR( 0 );
00296
00297 _ir_geom.poses[ 7 ].px = 0.200;
00298 _ir_geom.poses[ 7 ].py = 0.060;
00299 _ir_geom.poses[ 7 ].pyaw = DTOR( 60 );
00300
00301 _data.ir.ranges_count = NUM_IR_SENSORS;
00302 _data.ir.voltages_count = _data.ir.ranges_count;
00303 _data.ir.ranges = new float [_data.ir.ranges_count];
00304 _data.ir.voltages = new float [_data.ir.voltages_count];
00305
00306 }
00307
00311 wbr914::~wbr914()
00312 {
00313 if ( _tioChanged )
00314 tcsetattr( this->_fd, TCSADRAIN, &_old_tio);
00315 Shutdown();
00316 delete [] _ir_geom.poses;
00317 delete [] _data.ir.ranges;
00318 delete [] _data.ir.voltages;
00319
00320 }
00321
00322 int wbr914::Setup()
00323 {
00324 struct termios term;
00325 int flags;
00326
00327
00328 printf( "Initializing White Box Robotics Controller on %s...\n", _serial_port);
00329 fflush(stdout);
00330
00331 PLAYER_MSG0( 0, "Starting WBR driver\n" );
00332
00333
00334 if((this->_fd = open(_serial_port, O_RDWR | O_NOCTTY, S_IRUSR | S_IWUSR )) < 0 )
00335 {
00336 printf("open() failed: %s\n", strerror(errno));
00337 return(-1);
00338 }
00339
00340 if(tcgetattr(this->_fd, &term) < 0 )
00341 {
00342 printf("tcgetattr() failed: %s\n", strerror(errno));
00343 close(this->_fd);
00344 this->_fd = -1;
00345 return(-1);
00346 }
00347
00348 tcgetattr( this->_fd, &_old_tio);
00349
00350 cfmakeraw( &term );
00351 cfsetispeed( &term, B38400 );
00352 cfsetospeed( &term, B38400 );
00353
00354
00355 term.c_cflag |= CSTOPB | CLOCAL | CREAD;
00356 term.c_iflag |= IGNPAR;
00357
00358
00359 term.c_cc[ VTIME ] = 1;
00360 term.c_cc[ VMIN ] = 0;
00361
00362 if(tcsetattr(this->_fd, TCSADRAIN, &term) < 0 )
00363 {
00364 printf("tcsetattr() failed: %s\n", strerror(errno));
00365 close(this->_fd);
00366 this->_fd = -1;
00367 return(-1);
00368 }
00369
00370 _tioChanged = true;
00371
00372 {
00373 struct serial_struct serial_info;
00374
00375 if ( ioctl( _fd, TIOCGSERIAL, &serial_info ) < 0)
00376 {
00377
00378 perror("config_serial_port: ioctl TIOCGSERIAL");
00379 return(-1);
00380 }
00381
00382
00383
00384
00385 serial_info.flags = ASYNC_SPD_CUST | ASYNC_LOW_LATENCY;
00386 serial_info.custom_divisor = (int)((float)24000000.0/(float)_baud + 0.5);
00387 if ( _debug )
00388 printf( "Custom divisor = %d\n", serial_info.custom_divisor );
00389
00390 if ( ioctl( _fd, TIOCSSERIAL, &serial_info ) < 0)
00391 {
00392 perror("config_serial_port: ioctl TIOCSSERIAL");
00393 return(-1);
00394 }
00395 }
00396
00397 _fd_blocking = false;
00398
00399 if ( _debug )
00400 printf( "InitRobot\n" );
00401 fflush(stdout);
00402 if(InitRobot() < 0)
00403 {
00404 printf("failed to initialize robot\n");
00405 close(this->_fd);
00406 this->_fd = -1;
00407 return(-1);
00408 }
00409
00410
00411 if((flags = fcntl(this->_fd, F_GETFL)) < 0)
00412 {
00413 printf("fcntl() failed: %s\n", strerror(errno));
00414 close(this->_fd);
00415 this->_fd = -1;
00416 return(-1);
00417 }
00418
00419 if(fcntl(this->_fd, F_SETFL, flags ^ O_NONBLOCK) < 0)
00420 {
00421 printf("fcntl() failed: %s\n", strerror(errno));
00422 close(this->_fd);
00423 this->_fd = -1;
00424 return(-1);
00425 }
00426 _fd_blocking = true;
00427
00428 _usCycleTime = 154;
00429
00430 unsigned char ret[4];
00431 if( sendCmd0( LEFT_MOTOR, GETSAMPLETIME, 4,ret ) < 0)
00432 {
00433 printf("failed to get cycle time\n");
00434 return -1;
00435 }
00436 _usCycleTime = BytesToInt16( &(ret[2]) );
00437
00438 _velocityK = (GEAR_RATIO * MOTOR_TICKS_PER_REV * _usCycleTime * 65536)/(WHEEL_CIRC * 1000000);
00439
00440 SetMicrosteps();
00441
00442
00443 if ( (sendCmd16( LEFT_MOTOR, SETOUTPUTMODE, 1, 2, ret ) < 0 ) ||
00444 (sendCmd16( RIGHT_MOTOR, SETOUTPUTMODE, 1, 2, ret ) < 0 ))
00445 {
00446 printf( "Error setting sign-magnitude mode\n" );
00447 }
00448
00449
00450 if ( _debug )
00451 printf( "ResetRawPositions\n" );
00452 fflush( stdout );
00453 ResetRawPositions();
00454
00455 if ( _debug )
00456 printf( "SetAccelerationProfile\n" );
00457 SetAccelerationProfile();
00458 UpdateM3();
00459
00460
00461 if ( _debug )
00462 printf( "Starting Thread...\n" );
00463 StartThread();
00464 return(0);
00465 }
00466
00467 int wbr914::InitRobot()
00468 {
00469
00470
00471 unsigned char buf[6];
00472 usleep( DELAY_US);
00473
00474 if ( (sendCmd0( LEFT_MOTOR, RESET, 2, buf )<0 ) ||
00475 (sendCmd0( RIGHT_MOTOR, RESET, 2, buf )<0 ))
00476 {
00477 printf( "Error Resetting motors\n" );
00478 }
00479
00480 if ( _debug )
00481 printf( "GetVersion\n" );
00482 if( (sendCmd0( LEFT_MOTOR, GETVERSION, 6, buf ) < 0)||
00483 (sendCmd0( RIGHT_MOTOR, GETVERSION, 6, buf )<0 ))
00484 {
00485 printf("Cannot get version\n");
00486 return -1;
00487 }
00488
00489 _stopped = true;
00490 return(0);
00491 }
00492
00493
00494 int wbr914::Shutdown()
00495 {
00496 if( this->_fd == -1 )
00497 return(0);
00498
00499
00500 StopThread();
00501
00502
00503 StopRobot();
00504
00505 EnableMotors( false );
00506
00507
00508 int fd = _fd;
00509 this->_fd = -1;
00510 close( fd );
00511
00512 puts( "914 has been shut down" );
00513
00514 return(0);
00515 }
00516
00517 int wbr914::Subscribe( player_devaddr_t id )
00518 {
00519
00520 int rc = Driver::Subscribe(id);
00521
00522 if( rc == 0)
00523 {
00524
00525 if(Device::MatchDeviceAddress(id, this->position_id))
00526 {
00527 this->position_subscriptions++;
00528 }
00529 else if(Device::MatchDeviceAddress(id, this->ir_id))
00530 {
00531 this->ir_subscriptions++;
00532 }
00533 else if(Device::MatchDeviceAddress(id, this->aio_id))
00534 {
00535 this->aio_subscriptions++;
00536 }
00537 else if(Device::MatchDeviceAddress(id, this->dio_id))
00538 {
00539 this->dio_subscriptions++;
00540 }
00541 }
00542
00543 return( rc );
00544 }
00545
00546 int wbr914::Unsubscribe( player_devaddr_t id )
00547 {
00548 int shutdownResult = Driver::Unsubscribe(id);
00549
00550
00551
00552 if( shutdownResult == 0 )
00553 {
00554 if(Device::MatchDeviceAddress(id, this->position_id))
00555 {
00556 this->position_subscriptions--;
00557 assert(this->position_subscriptions >= 0);
00558 }
00559 else if(Device::MatchDeviceAddress(id, this->ir_id))
00560 {
00561 this->ir_subscriptions--;
00562 assert(this->ir_subscriptions >= 0);
00563 }
00564 else if(Device::MatchDeviceAddress(id, this->aio_id))
00565 {
00566 this->aio_subscriptions--;
00567 assert(this->aio_subscriptions >= 0);
00568 }
00569 else if(Device::MatchDeviceAddress(id, this->dio_id))
00570 {
00571 this->dio_subscriptions--;
00572 assert(this->dio_subscriptions >= 0);
00573 }
00574 }
00575
00576 return(shutdownResult);
00577 }
00578
00579 void wbr914::PublishData(void)
00580 {
00581
00582
00583 if ( position_subscriptions )
00584 {
00585
00586 this->Publish(this->position_id,
00587 PLAYER_MSGTYPE_DATA,
00588 PLAYER_POSITION2D_DATA_STATE,
00589 (void*)&(this->_data.position),
00590 sizeof(player_position2d_data_t),
00591 NULL);
00592 }
00593
00594 if ( ir_subscriptions )
00595 {
00596
00597 this->Publish(this->ir_id,
00598 PLAYER_MSGTYPE_DATA,
00599 PLAYER_IR_DATA_RANGES,
00600 (void*)&(_data.ir),
00601 sizeof(_data.ir),
00602 NULL);
00603 }
00604
00605 if ( aio_subscriptions )
00606 {
00607
00608 this->Publish(this->aio_id,
00609 PLAYER_MSGTYPE_DATA,
00610 PLAYER_AIO_DATA_STATE,
00611 (void*)&(_data.aio),
00612 sizeof(_data.aio),
00613 NULL);
00614 }
00615
00616 if ( dio_subscriptions )
00617 {
00618
00619 this->Publish(this->dio_id,
00620 PLAYER_MSGTYPE_DATA,
00621 PLAYER_DIO_DATA_VALUES,
00622 (void*)&(_data.dio),
00623 sizeof(_data.dio),
00624 NULL);
00625 }
00626 }
00627
00628 void wbr914::Main()
00629 {
00630 int last_position_subscrcount=0;
00631
00632 if ( _debug )
00633 PLAYER_MSG0( 0, "Main\n" );
00634
00635 for(;;)
00636 {
00637 pthread_testcancel();
00638
00639
00640
00641
00642 if(!last_position_subscrcount && this->position_subscriptions)
00643 {
00644 this->EnableMotors( false );
00645 this->ResetRawPositions();
00646 }
00647 else if(last_position_subscrcount && !(this->position_subscriptions))
00648 {
00649
00650 if ( _debug )
00651 PLAYER_MSG0( 0, "enabling motors\n" );
00652 this->EnableMotors( true );
00653 }
00654 last_position_subscrcount = this->position_subscriptions;
00655
00656 this->Unlock();
00657
00658
00659 if(!this->InQueue->Empty())
00660 {
00661 if ( _debug )
00662 PLAYER_MSG0( 0, "processing messages\n" );
00663 ProcessMessages();
00664 }
00665 else
00666 {
00667
00668
00669
00670 }
00671
00672 if ( _debug )
00673 PLAYER_MSG0( 0, "GetAllData\n" );
00674
00675 GetAllData();
00676
00677 if ( _debug )
00678 PLAYER_MSG0( 0, "PublishData\n" );
00679
00680 PublishData();
00681 }
00682 }
00683
00684 int wbr914::ProcessMessage(QueuePointer &resp_queue,
00685 player_msghdr * hdr,
00686 void * data)
00687 {
00688
00689 if(hdr->type == PLAYER_MSGTYPE_REQ)
00690 return(this->HandleConfig(resp_queue,hdr,data));
00691 else if(hdr->type == PLAYER_MSGTYPE_CMD)
00692 return(this->HandleCommand(hdr,data));
00693
00694
00695 return(-1);
00696 }
00697
00698 int wbr914::HandleConfig(QueuePointer &resp_queue,
00699 player_msghdr * hdr,
00700 void * data)
00701 {
00702 if ( _debug )
00703 printf( "HandleConfig\n" );
00704
00705
00706 if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
00707 PLAYER_POSITION2D_REQ_SET_ODOM,
00708 this->position_id))
00709 {
00710 if(hdr->size != sizeof(player_position2d_set_odom_req_t))
00711 {
00712 PLAYER_WARN("Arg to odometry set requests wrong size; ignoring");
00713 return(-1);
00714 }
00715
00716 SetOdometry( (player_position2d_set_odom_req_t*)data );
00717 Publish( position_id, resp_queue,
00718 PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_SET_ODOM);
00719 UpdateM3();
00720 return(0);
00721 }
00722 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
00723 PLAYER_POSITION2D_REQ_MOTOR_POWER,
00724 this->position_id))
00725 {
00726
00727
00728
00729
00730 if(hdr->size != sizeof(player_position2d_power_config_t))
00731 {
00732 PLAYER_WARN("Arg to motor state change request wrong size; ignoring");
00733 return(-1);
00734 }
00735 player_position2d_power_config_t* power_config =
00736 (player_position2d_power_config_t*)data;
00737 this->EnableMotors( power_config->state == 1 );
00738
00739 this->Publish(this->position_id, resp_queue,
00740 PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_MOTOR_POWER);
00741 UpdateM3();
00742 return(0);
00743 }
00744 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
00745 PLAYER_POSITION2D_REQ_RESET_ODOM,
00746 this->position_id))
00747 {
00748
00749 if(hdr->size != 0)
00750 {
00751 PLAYER_WARN("Arg to reset position request is wrong size; ignoring");
00752 return(-1);
00753 }
00754 ResetRawPositions();
00755
00756 this->Publish(this->position_id, resp_queue,
00757 PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_RESET_ODOM);
00758 UpdateM3();
00759 return(0);
00760 }
00761 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
00762 PLAYER_POSITION2D_REQ_GET_GEOM,
00763 this->position_id))
00764 {
00765
00766 if(hdr->size != 0)
00767 {
00768 PLAYER_WARN("Arg get robot geom is wrong size; ignoring");
00769 return(-1);
00770 }
00771
00772 Publish(this->position_id, resp_queue,
00773 PLAYER_MSGTYPE_RESP_ACK,
00774 PLAYER_POSITION2D_REQ_GET_GEOM,
00775 (void*)&_robot2d_geom, sizeof(_robot2d_geom), NULL);
00776 return(0);
00777 }
00778 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
00779 PLAYER_IR_REQ_POSE,
00780 ir_id))
00781 {
00782
00783 Publish( ir_id, resp_queue,
00784 PLAYER_MSGTYPE_RESP_ACK,
00785 hdr->subtype,
00786 (void*)&_ir_geom, sizeof( _ir_geom ), NULL);
00787 return(0);
00788 }
00789 else
00790 {
00791 PLAYER_WARN("unknown config request to wbr914 driver");
00792 return(-1);
00793 }
00794 }
00795
00796 int wbr914::HandleCommand(player_msghdr * hdr, void* data)
00797 {
00798 if(Message::MatchMessage(hdr,
00799 PLAYER_MSGTYPE_CMD,
00800 PLAYER_POSITION2D_CMD_VEL,
00801 this->position_id))
00802 {
00803
00804
00805
00806
00807
00808
00809 HandleVelocityCommand( (player_position2d_cmd_vel_t*)data );
00810 UpdateM3();
00811 return(0);
00812 }
00813 else if ( Message::MatchMessage(hdr,
00814 PLAYER_MSGTYPE_CMD,
00815 PLAYER_DIO_CMD_VALUES,
00816 this->dio_id))
00817 {
00818 HandleDigitalOutCommand( (player_dio_data_t*)data );
00819 return(0);
00820 }
00821
00822
00823 return(-1);
00824 }
00825
00826 void wbr914::HandleVelocityCommand(player_position2d_cmd_vel_t* velcmd)
00827 {
00828
00829 float trans = velcmd->vel.px;
00830 float rot = velcmd->vel.pa * DEFAULT_AXLE_LENGTH/2.0;
00831 float l = trans - rot;
00832 float r = trans + rot;
00833
00834
00835
00836
00837
00838
00839 if ( fabs( l ) > MOTOR_DEF_MAX_SPEED )
00840 {
00841 float dir = l/fabs(l);
00842 float scale = l/MOTOR_DEF_MAX_SPEED;
00843 l = dir*MOTOR_DEF_MAX_SPEED;
00844 r = r/fabs(scale);
00845 }
00846
00847 if ( fabs( r ) > MOTOR_DEF_MAX_SPEED )
00848 {
00849 float dir = r/fabs(r);
00850 float scale = r/MOTOR_DEF_MAX_SPEED;
00851 r = dir*MOTOR_DEF_MAX_SPEED;
00852 l = l/fabs(scale);
00853 }
00854
00855 int32_t leftvel = MPS2Vel( l );
00856 int32_t rightvel = MPS2Vel( r );
00857
00858
00859
00860 SetContourMode( VelocityContouringProfile );
00861
00862
00863 if ( this->_motorsEnabled )
00864 {
00865 SetVelocityInTicks( leftvel, rightvel );
00866 }
00867 else
00868 {
00869 SetVelocityInTicks( 0, 0 );
00870 printf( "Motors not enabled\n" );
00871 }
00872 }
00873
00874 void wbr914::HandleDigitalOutCommand( player_dio_data_t* doutCmd )
00875 {
00876 SetDigitalData( doutCmd );
00877 }
00878
00879 void wbr914::GetAllData( void )
00880 {
00881
00882 if ( position_subscriptions )
00883 {
00884 GetPositionData( &_data.position );
00885 }
00886
00887 if ( ir_subscriptions )
00888 {
00889 GetIRData( &_data.ir );
00890 }
00891
00892 if ( aio_subscriptions )
00893 {
00894 GetAnalogData( &_data.aio );
00895 }
00896
00897 if ( dio_subscriptions )
00898 {
00899 GetDigitalData( &_data.dio );
00900 }
00901 }
00902
00903 void wbr914::GetPositionData( player_position2d_data_t* d )
00904 {
00905
00906 int32_t left_pos = -57;
00907 int32_t right_pos = -57;
00908 const double TWOPI = 2.0*M_PI;
00909
00910 GetPositionInTicks( &left_pos, &right_pos );
00911
00912 int32_t change_left = left_pos - last_lpos;
00913 int32_t change_right = right_pos - last_rpos;
00914
00915 last_lpos = left_pos;
00916 last_rpos = right_pos;
00917
00918
00919
00920
00921 double transchange = Ticks2Meters( (change_left + change_right)>>1 );
00922 double rotchange = Ticks2Meters( (change_left - change_right)>>1 );
00923
00924
00925 double r = DEFAULT_AXLE_LENGTH/2.0;
00926
00927
00928 _yaw += rotchange/r;
00929 if ( _yaw < 0 )
00930 _yaw += TWOPI;
00931
00932 if ( _yaw > TWOPI )
00933 _yaw -= TWOPI;
00934
00935
00936 _x += ( transchange * cos( _yaw ));
00937 _y += ( transchange * sin( _yaw ));
00938
00939
00940
00941 int32_t left_vel, right_vel;
00942
00943 GetVelocityInTicks( &left_vel, &right_vel );
00944
00945 double lv = Vel2MPS( left_vel );
00946 double rv = Vel2MPS( right_vel );
00947 double trans_vel = (lv + rv)/2;
00948 double rot_vel = (lv - rv)/2;
00949 double rot_vel_rad = rot_vel/(r);
00950
00951 d->pos.px = _x;
00952 d->pos.py = _y;
00953 d->pos.pa = _yaw;
00954 d->vel.px = trans_vel;
00955 d->vel.pa = rot_vel_rad;
00956 }
00957
00958
00959
00960
00961 void wbr914::GetIRData(player_ir_data_t * d)
00962 {
00963
00964
00965
00966
00967
00968
00969 float adcLo = 0.0;
00970 float adcHi = 5.0;
00971 float vPerCount = (adcHi-adcLo)/1023.0;
00972
00973
00974
00975
00976
00977 for (uint32_t i=0; i < d->ranges_count; i++)
00978 {
00979 int16_t val = 0;
00980
00981 GetAnalogSensor( i+8, &val );
00982 float voltage = (float)val*vPerCount;
00983 d->voltages[ i ] = voltage;
00984
00985
00986
00987 if ( val < 80 )
00988 {
00989 val = 80;
00990 }
00991
00992
00993 float meters;
00994
00995
00996
00997 if ( i == 5 || i == 7 )
00998 {
00999
01000
01001 meters = ((16933.0/((float)val - 8.0)) - 13.0)/100.0;
01002 }
01003 else
01004 {
01005
01006 meters = ((6787.0/((float)val - 3.0)) - 4.0)/100.0;
01007 }
01008 d->ranges[ i ] = meters;
01009 }
01010 }
01011
01012
01013
01014
01015
01016
01017
01018 void wbr914::GetAnalogData(player_aio_data_t * d)
01019 {
01020
01021 d->voltages_count = 8;
01022
01023 float adcLo = 0.0;
01024 float adcHi = 5.0;
01025 float vPerCount = (adcHi-adcLo)/1023.0;
01026
01027 for (uint32_t i=0; i < d->voltages_count; i++)
01028 {
01029 int16_t val = 0;
01030
01031 GetAnalogSensor( i, &val );
01032 float voltage = (float)val*vPerCount;
01033 d->voltages[ i ] = voltage;
01034 }
01035 }
01036
01037
01038
01039
01040
01041
01042
01043 void wbr914::GetDigitalData(player_dio_data_t * d)
01044 {
01045
01046 uint16_t din;
01047
01048 d->count = 16;
01049 GetDigitalIn( &din );
01050
01051
01052
01053 d->bits = (uint32_t)( (din>>8) | (din<<8));
01054 }
01055
01056
01057
01058
01059
01060
01061
01062 void wbr914::SetDigitalData( player_dio_data_t * d )
01063 {
01064
01065 uint16_t data = d->bits & 0xFFFF;
01066
01067
01068
01069
01070 if ( d->count < 16 )
01071 {
01072
01073 uint16_t mask = (0xffff << d->count);
01074 uint16_t oldPart = _lastDigOut & mask;
01075
01076
01077 mask = mask ^ 0xFFFF;
01078 data &= mask;
01079
01080
01081 data |= oldPart;
01082 }
01083
01084 _lastDigOut = data;
01085
01086
01087
01088 data = ( (data>>8) | (data<<8) );
01089
01090
01091 SetDigitalOut( data );
01092 }
01093
01094
01095
01096
01097 const char* wbr914::GetPMDErrorString( int rc )
01098 {
01099 static const char* errorStrings[] =
01100 {
01101 "Success",
01102 "Reset",
01103 "Invalid Instruction",
01104 "Invalid Axis",
01105 "Invalid Parameter",
01106 "Trace Running",
01107 "Flash",
01108 "Block Out of Bounds",
01109 "Trace buffer zero",
01110 "Bad checksum",
01111 "Not primary port",
01112 "Invalid negative value",
01113 "Invalid parameter change",
01114 "Limit event pending",
01115 "Invalid move into limit"
01116 };
01117 static char bogusRC[ 80 ];
01118
01119 if ( rc < (int)sizeof( errorStrings ) )
01120 {
01121 return errorStrings[ rc ];
01122 }
01123
01124 sprintf( bogusRC, "Unknown error %d", rc );
01125 return bogusRC;
01126 }
01127
01128 int wbr914::ResetRawPositions()
01129 {
01130 if ( _debug )
01131 printf("Reset Odometry\n");
01132 int Values[2];
01133 Values[0] = 0;
01134 Values[1] = 0;
01135
01136 if ( _debug )
01137 printf( "SetActualPositionInTicks\n" );
01138 SetActualPositionInTicks( 0, 0 );
01139 UpdateM3();
01140
01141 last_lpos = 0;
01142 last_rpos = 0;
01143
01144
01145
01146
01147
01148 _x = 0;
01149 _y = 0;
01150 _yaw = 0;
01151 return 0;
01152 }
01153
01154 bool wbr914::RecvBytes( unsigned char*s, int len )
01155 {
01156 int nbytes;
01157 int bytesRead = 0;
01158
01159
01160 for ( int i=0; i<10; i++ )
01161 {
01162 nbytes = read( _fd, s+bytesRead, len-bytesRead );
01163 if ( nbytes < 0 )
01164 {
01165 if ( errno != EAGAIN )
01166 {
01167 printf( "M3 Read error: %s\n", strerror( errno ));
01168 return false;
01169 }
01170 else
01171 {
01172 nbytes = 0;
01173 }
01174 }
01175
01176 bytesRead += nbytes;
01177 if ( bytesRead == len )
01178 {
01179 return true;
01180 }
01181
01182
01183
01184
01185 int t = ( len-bytesRead )*11*1000/_baud;
01186 usleep( t*1000 );
01187 }
01188
01189 printf( "Read timeout; Got %d bytes, expected %d\n",
01190 bytesRead, len );
01191
01192 return false;
01193 }
01194
01195 int wbr914::ReadBuf(unsigned char* s, size_t len)
01196 {
01197
01198 bool rc = RecvBytes( s, 1 );
01199 if ( !rc )
01200 {
01201 return -1;
01202 }
01203
01204
01205 if ( *s != 0 && *s != 1 )
01206 {
01207 const char* err = GetPMDErrorString( *s );
01208 printf( "Cmd error: %s\n", err );
01209 return( -(*s) );
01210 }
01211
01212
01213 rc = RecvBytes( s+1, len-1 );
01214 if ( !rc )
01215 {
01216 return -1;
01217 }
01218
01219 uint8_t chksum = 0;
01220
01221
01222 for ( unsigned i=0; i<len; i++ )
01223 {
01224 chksum += *(s+i);
01225 }
01226 if ( chksum != 0 )
01227 {
01228 printf( "Read checksum error\n" );
01229 return -1;
01230 }
01231
01232 return len;
01233
01234 #ifdef FOO
01235
01236 while ( numread < (int)len )
01237 {
01238 if ( ( newread = read( this->_fd, s, len )) == -1 )
01239 {
01240 if( !_fd_blocking && errno == EAGAIN)
01241 {
01242 if ( readSlipped == false )
01243 printf( "read() slipped\n" );
01244 else
01245 {
01246 printf("read() failed: %s\n", strerror(errno));
01247 return(-1);
01248 }
01249
01250 readSlipped = true;
01251
01252 usleep( DELAY_US);
01253 continue;
01254 }
01255
01256 printf("read() failed: %s\n", strerror(errno));
01257 return(-1);
01258 }
01259 else
01260 {
01261 numread += newread;
01262 if ( _fd_blocking )
01263 {
01264 break;
01265 }
01266 }
01267 }
01268
01269 #ifdef DEBUG
01270 printf("read: %d of %d bytes - ", numread, len );
01271 ssize_t i;
01272 for( i=0; i<numread; i++)
01273 {
01274 printf( "0x%02x ", s[i] );
01275 }
01276 printf( "\n" );
01277 #endif
01278
01279 uint8_t chksum = 0;
01280
01281
01282 for ( i=0; i<numread; i++ )
01283 {
01284 chksum += s[i];
01285 }
01286 if ( chksum != 0 )
01287 {
01288 printf( "Read checksum error\n" );
01289 }
01290
01291
01292 if ( s[0] != 0 && s[0] != 1 )
01293 {
01294 const char* err = GetPMDErrorString( s[0] );
01295 printf( "Cmd error: %s\n", err );
01296 return( -s[0] );
01297 }
01298
01299 return( numread );
01300 #endif
01301 }
01302
01303 int wbr914::WriteBuf(unsigned char* s, size_t len)
01304 {
01305 size_t numwritten;
01306 int thisnumwritten;
01307 numwritten=0;
01308
01309 #ifdef DEBUG
01310 printf("write: %d bytes - ", len );
01311 size_t i;
01312 for( i=0; i<len; i++)
01313 {
01314 printf( "0x%02x ", s[i] );
01315 }
01316 printf( "\n" );
01317 #endif
01318
01319 for ( int i=0; i<10; i++ )
01320 {
01321 thisnumwritten = write( _fd, s+numwritten, len-numwritten);
01322 numwritten += thisnumwritten;
01323
01324 if ( numwritten == len )
01325 {
01326 return numwritten;
01327 }
01328 else if ( thisnumwritten < 0 )
01329 {
01330 printf( "Write error; %s\n", strerror( errno ));
01331 return -1;
01332 }
01333 }
01334
01335 printf( "Write timeout; wrote %ld bytes, tried to write %ld\n",
01336 numwritten, len );
01337
01338 return numwritten;
01339
01340 #ifdef FOO
01341 while(numwritten < len)
01342 {
01343 if((thisnumwritten = write(this->_fd,s+numwritten,len-numwritten)) < 0)
01344 {
01345 if(!this->_fd_blocking && errno == EAGAIN)
01346 {
01347 printf( "write() slipped\n" );
01348 usleep( DELAY_US);
01349 continue;
01350 }
01351 printf("write() failed: %s\n", strerror(errno));
01352 return(-1);
01353 }
01354 numwritten += thisnumwritten;
01355 }
01356
01357
01358 #endif
01359
01360 return numwritten;
01361 }
01362
01363 int wbr914::sendCmdCom( unsigned char address, unsigned char c,
01364 int cmd_num, unsigned char* arg,
01365 int ret_num, unsigned char * ret )
01366 {
01367 assert( cmd_num<=4 );
01368
01369 unsigned char cmd[8];
01370
01371 unsigned char savecs;
01372
01373 cmd[0] = address;
01374 cmd[1] = 0;
01375 cmd[2] = 0x00;
01376 cmd[3] = c;
01377
01378
01379 int i;
01380 for ( i=0; i<cmd_num; i++ )
01381 {
01382 cmd[4+i] = arg[i];
01383 }
01384
01385
01386 int chk = 0;
01387 for ( i=0; i<cmd_num+4; i++ )
01388 {
01389 chk += cmd[i];
01390 }
01391
01392
01393 int cs = -chk;
01394 cmd[1] = (unsigned char) (cs & 0xff);
01395 savecs = cmd[1];
01396
01397 int result;
01398
01399
01400 tcflush( _fd, TCIFLUSH );
01401
01402 result = WriteBuf( cmd, 4+cmd_num );
01403
01404 if( result != 4+cmd_num )
01405 {
01406 printf( "failed to send command %d\n", (int)c );
01407 return( -1 );
01408 }
01409
01410
01411 if( ret != NULL && ret_num > 0 )
01412 {
01413
01414 usleep( DELAY_US );
01415
01416 int rc;
01417 if( (rc = ReadBuf( ret, ret_num )) < 0 )
01418 {
01419
01420 result = -1;
01421 }
01422 }
01423
01424
01425
01426 return result;
01427 }
01428
01429 int wbr914::sendCmd0( unsigned char address, unsigned char c,
01430 int ret_num, unsigned char * ret )
01431 {
01432 return sendCmdCom( address, c, 0, NULL, ret_num, ret );
01433 }
01434
01435 int wbr914::sendCmd16( unsigned char address, unsigned char c,
01436 int16_t arg, int ret_num, unsigned char * ret )
01437 {
01438
01439 unsigned char args[2];
01440 uint16_t a = htons( arg );
01441
01442 args[1] = (a >> 8) & 0xFF;
01443 args[0] = (a >> 0) & 0xFF;
01444
01445 return sendCmdCom( address, c, 2, args, ret_num, ret );
01446 }
01447
01448 int wbr914::sendCmd32( unsigned char address, unsigned char c,
01449 int32_t arg, int ret_num, unsigned char * ret )
01450 {
01451 unsigned char args[4];
01452 uint32_t a = htonl( arg );
01453 args[3] = (a >> 24) & 0xFF;
01454 args[2] = (a >> 16) & 0xFF;
01455 args[1] = (a >> 8 ) & 0xFF;
01456 args[0] = (a >> 0 ) & 0xFF;
01457
01458 return sendCmdCom( address, c, 4, args, ret_num, ret );
01459 }
01460
01461
01462 void wbr914::SetOdometry( player_position2d_set_odom_req_t* od )
01463 {
01464 unsigned char ret[2];
01465
01466 _x = od->pose.px;
01467 _y = od->pose.py;
01468 _yaw = od->pose.pa;
01469
01470 int32_t leftPos = Meters2Ticks( _x );
01471 int32_t rightPos = Meters2Ticks( _y );
01472
01473 if ( (sendCmd32( LEFT_MOTOR, SETACTUALPOS, leftPos, 2, ret )<0)||
01474 (sendCmd32( LEFT_MOTOR, SETACTUALPOS, rightPos, 2, ret )<0 ))
01475 {
01476 printf( "Error setting actual position\n" );
01477 }
01478 }
01479
01480 int wbr914::GetAnalogSensor(int s, short * val )
01481 {
01482 unsigned char ret[6];
01483
01484 if ( sendCmd16( s / 8, READANALOG, s % 8, 4, ret )<0 )
01485 {
01486 printf( "Error reading Analog values\n" );
01487 }
01488
01489
01490
01491 uint16_t v = ( (uint16_t)BytesToInt16( &(ret[2]) ) >> 6) & 0x03ff;
01492
01493 if ( _debug )
01494 printf( "sensor %d value: 0x%hx\n", s, v );
01495
01496 *val = (uint16_t)v;
01497
01498 return 0;
01499 }
01500
01501
01502 void wbr914::GetDigitalIn( uint16_t* d )
01503 {
01504 unsigned char ret[6];
01505
01506 if ( sendCmd16( 0, READDIGITAL, 0, 4, ret )<0)
01507 {
01508 printf( "Error reading Digital input values\n" );
01509 }
01510
01511 *d = (uint16_t)BytesToInt16( &(ret[2]) );
01512 }
01513
01514 void wbr914::SetDigitalOut( uint16_t d )
01515 {
01516 unsigned char ret[2];
01517
01518 if ( sendCmd32( 0, WRITEDIGITAL, d, 2, ret ) < 0 )
01519 {
01520 printf( "Error setting Digital output values\n" );
01521 }
01522 }
01523
01524
01525
01526
01527
01528 void wbr914::UpdateM3()
01529 {
01530 unsigned char ret[2];
01531
01532 if ( (sendCmd0( LEFT_MOTOR, UPDATE, 2, ret )<0 ) ||
01533 (sendCmd0( RIGHT_MOTOR, UPDATE, 2, ret )<0 ))
01534 {
01535 printf( "Error updating M3\n" );
01536 }
01537 }
01538
01539 void wbr914::SetVelocity( uint8_t chan, float mps )
01540 {
01541 uint8_t ret[2];
01542 int flip = 1;
01543 if ( chan == LEFT_MOTOR )
01544 {
01545 flip = -1;
01546 }
01547 if ( sendCmd32( chan, SETVEL, MPS2Vel( mps )*flip, 2, ret )<0 )
01548 {
01549 printf( "Error setting velocity\n" );
01550 }
01551 }
01552
01553 void wbr914::SetVelocity( float mpsL, float mpsR )
01554 {
01555 uint8_t ret[2];
01556
01557 if ( (sendCmd32( LEFT_MOTOR, SETVEL, -MPS2Vel( mpsL ), 2, ret )<0)||
01558 (sendCmd32( RIGHT_MOTOR, SETVEL, MPS2Vel( mpsR ), 2, ret )<0))
01559 {
01560 printf( "Error setting L/R velocity\n" );
01561 }
01562 }
01563
01564 void wbr914::SetVelocityInTicks( int32_t left, int32_t right )
01565 {
01566 uint8_t ret[2];
01567 if ( (sendCmd32( LEFT_MOTOR, SETVEL, -left, 2, ret )<0)||
01568 (sendCmd32( RIGHT_MOTOR, SETVEL, right, 2, ret )<0))
01569 {
01570 printf( "Error setting velocity in ticks\n" );
01571 }
01572 }
01573
01574 void wbr914::Move( uint8_t chan, float meters )
01575 {
01576 uint8_t ret[6];
01577 int flip = 1;
01578
01579 if ( chan == LEFT_MOTOR )
01580 {
01581 flip = -1;
01582 }
01583
01584 if ( sendCmd0( chan, GETCMDPOS, 6, ret )< 0 )
01585 {
01586 printf( "Error getting actual position\n" );
01587 }
01588 int32_t loc = BytesToInt32( &ret[2] );
01589 loc += (flip*Meters2Ticks( meters ));
01590 if ( ( sendCmd32( chan, SETPOS, loc, 2, ret )<0))
01591 {
01592 printf( "Error setting actual position for Move\n" );
01593 }
01594 }
01595
01596 void wbr914::Move( float metersL, float metersR )
01597 {
01598 Move( LEFT_MOTOR, metersL );
01599 Move( RIGHT_MOTOR, metersR );
01600 }
01601
01602 void wbr914::SetPosition( uint8_t chan, float meters )
01603 {
01604 uint8_t ret[6];
01605 int flip = 1;
01606 if ( chan == LEFT_MOTOR )
01607 {
01608 flip = -1;
01609 }
01610
01611 if ( sendCmd32( chan, SETPOS, flip*Meters2Ticks( meters ), 2, ret )<0)
01612 {
01613 printf( "Error issuing SetPosition\n" );
01614 }
01615 }
01616
01617 void wbr914::SetPosition( float metersL, float metersR )
01618 {
01619 SetPosition( LEFT_MOTOR, metersL );
01620 SetPosition( RIGHT_MOTOR, metersR );
01621 }
01622
01623 void wbr914::SetActualPositionInTicks( int32_t left, int32_t right )
01624 {
01625 uint8_t ret[6];
01626 if ( (sendCmd32( LEFT_MOTOR, SETACTUALPOS, -left, 2, ret )<0)||
01627 (sendCmd32( RIGHT_MOTOR, SETACTUALPOS, right, 2, ret )<0))
01628 {
01629 printf( "Error in SetActualPositionInTicks\n" );
01630 }
01631 }
01632
01633 void wbr914::SetActualPosition( float metersL, float metersR )
01634 {
01635 uint8_t ret[6];
01636 if ( (sendCmd32( LEFT_MOTOR, SETACTUALPOS, -Meters2Ticks( metersL ), 2, ret )<0)||
01637 (sendCmd32( RIGHT_MOTOR, SETACTUALPOS, Meters2Ticks( metersL ), 2, ret )<0))
01638 {
01639 printf( "Error in L/R SetActualPosition\n" );
01640 }
01641 }
01642
01643 void wbr914::GetPositionInTicks( int32_t* left, int32_t* right )
01644 {
01645 uint8_t ret[6];
01646 if ( sendCmd0( LEFT_MOTOR, GETCMDPOS, 6, ret )<0)
01647 {
01648 printf( "Error in Left GetPositionInTicks\n" );
01649 }
01650 *left = -BytesToInt32( &ret[2] );
01651 if ( sendCmd0( RIGHT_MOTOR, GETCMDPOS, 6, ret )<0 )
01652 {
01653 printf( "Error in Right GetPositionInTicks\n" );
01654 }
01655 *right = BytesToInt32( &ret[2] );
01656 }
01657
01658 void wbr914::GetVelocityInTicks( int32_t* left, int32_t* right )
01659 {
01660 uint8_t ret[6];
01661 if ( sendCmd0( LEFT_MOTOR, GETCMDVEL, 6, ret )<0 )
01662 {
01663 printf( "Error in Left GetVelocityInTicks\n" );
01664 }
01665 *left = -BytesToInt32( &ret[2] );
01666 if ( sendCmd0( RIGHT_MOTOR, GETCMDVEL, 6, ret )<0 )
01667 {
01668 printf( "Error in Left GetVelocityInTicks\n" );
01669 }
01670 *right = BytesToInt32( &ret[2] );
01671 }
01672
01673 void wbr914::SetAccelerationProfile()
01674 {
01675 uint8_t ret[2];
01676
01677
01678
01679 if ( (sendCmd32( LEFT_MOTOR, SETACCEL, ACCELERATION_DEFAULT, 2, ret )<0)||
01680 (sendCmd32( RIGHT_MOTOR, SETACCEL, ACCELERATION_DEFAULT, 2, ret )<0))
01681 {
01682 printf( "Error setting Accelleration profile\n" );
01683 }
01684 if ((sendCmd32( LEFT_MOTOR, SETDECEL, DECELERATION_DEFAULT, 2, ret )<0)||
01685 (sendCmd32( RIGHT_MOTOR, SETDECEL, DECELERATION_DEFAULT, 2, ret )<0))
01686 {
01687 printf( "Error setting Decelleration profile\n" );
01688 }
01689 SetContourMode( TrapezoidalProfile );
01690 }
01691
01692 void wbr914::Stop( int StopMode ) {
01693
01694 unsigned char ret[8];
01695
01696 if ( _debug )
01697 printf( "Stop\n" );
01698
01699
01700 _stopped = true;
01701
01702 if( StopMode == FULL_STOP )
01703 {
01704 if (sendCmd16( LEFT_MOTOR, RESETEVENTSTATUS, 0x0000, 2, ret )<0 )
01705 {
01706 printf( "Error resetting event status\n" );
01707 }
01708 if ( sendCmd16( LEFT_MOTOR, SETSTOPMODE, AbruptStopMode, 2, ret )<0 )
01709 {
01710 printf( "Error setting stop mode\n" );
01711 }
01712 if ( sendCmd32( LEFT_MOTOR, SETVEL, 0, 2, ret )<0)
01713 {
01714 printf( "Error resetting motor velocity\n" );
01715 }
01716 if ( sendCmd32( LEFT_MOTOR, SETACCEL, 0, 2, ret )<0 )
01717 {
01718 printf( "Error resetting acceleration\n" );
01719 }
01720 if ( sendCmd32( LEFT_MOTOR, SETDECEL, 0, 2, ret )<0 )
01721 {
01722 printf( "Error resetting deceleration\n" );
01723 }
01724
01725
01726 if ( sendCmd16( RIGHT_MOTOR, RESETEVENTSTATUS, 0x0000, 2, ret )<0 )
01727 {
01728 printf( "Error resetting event status\n" );
01729 }
01730 if ( sendCmd16( RIGHT_MOTOR, SETSTOPMODE, AbruptStopMode, 2, ret )<0 )
01731 {
01732 printf( "Error setting stop mode\n" );
01733 }
01734 if ( sendCmd32( RIGHT_MOTOR, SETVEL, 0, 2, ret )<0 )
01735 {
01736 printf( "Error resetting motor velocity\n" );
01737 }
01738 if ( sendCmd32( RIGHT_MOTOR, SETACCEL, 0, 2, ret )<0 )
01739 {
01740 printf( "Error resetting acceleration\n" );
01741 }
01742 if ( sendCmd32( RIGHT_MOTOR, SETDECEL, 0, 2, ret )<0 )
01743 {
01744 printf( "Error resetting deceleration\n" );
01745 }
01746
01747 SetContourMode( VelocityContouringProfile );
01748
01749 EnableMotors( false );
01750 UpdateM3();
01751
01752 if ((sendCmd0( LEFT_MOTOR, RESET, 2, ret )<0)||
01753 (sendCmd0( RIGHT_MOTOR, RESET, 2, ret )<0))
01754 {
01755 printf( "Error resetting motor\n" );
01756 }
01757
01758 }
01759 else
01760 {
01761 if ( sendCmd16( LEFT_MOTOR, RESETEVENTSTATUS, 0x0700, 2, ret )<0 )
01762 {
01763 printf( "Error resetting event status\n" );
01764 }
01765 if ( sendCmd32( LEFT_MOTOR, SETVEL, 0, 2, ret )<0 )
01766 {
01767 printf( "Error resetting motor velocity\n" );
01768 }
01769
01770 if ( sendCmd16( RIGHT_MOTOR, RESETEVENTSTATUS, 0x0700, 2, ret )<0 )
01771 {
01772 printf( "Error resetting event status\n" );
01773 }
01774 if ( sendCmd32( RIGHT_MOTOR, SETVEL, 0, 2, ret )<0)
01775 {
01776 printf( "Error resetting motor velocity\n" );
01777 }
01778
01779 UpdateM3();
01780
01781 if ((sendCmd0( LEFT_MOTOR, RESET, 2, ret )<0)||
01782 (sendCmd0( RIGHT_MOTOR, RESET, 2, ret )<0))
01783 {
01784 printf( "Error resetting motor\n" );
01785 }
01786 }
01787 }
01788
01789
01790 void wbr914::StopRobot()
01791 {
01792 Stop( FULL_STOP );
01793 }
01794
01795
01796 bool wbr914::EnableMotors( bool enable )
01797 {
01798 unsigned char ret[2];
01799 long torque = 0;
01800
01801 if ( enable )
01802 {
01803 torque = _percentTorque*0x8000/100;
01804 if ( torque > 0x8000 )
01805 torque = 0x8000;
01806 }
01807
01808
01809 if ( ( sendCmd16( LEFT_MOTOR, SETMOTORMODE, 0, 2, ret )<0)||
01810 ( sendCmd16( RIGHT_MOTOR, SETMOTORMODE, 0, 2, ret )<0))
01811 {
01812 printf( "Error resetting motor mode\n" );
01813 }
01814
01815 if ((sendCmd16( LEFT_MOTOR, SETMOTORCMD, (short)torque, 2, ret )<0)||
01816 (sendCmd16( RIGHT_MOTOR, SETMOTORCMD, (short)torque, 2, ret )<0))
01817 {
01818 printf( "Error setting motor mode\n" );
01819 }
01820
01821
01822 UpdateM3();
01823
01824 if ( enable )
01825 {
01826 if ((sendCmd16( LEFT_MOTOR, SETMOTORMODE, 1, 2, ret )<0)||
01827 (sendCmd16( RIGHT_MOTOR, SETMOTORMODE, 1, 2, ret )<0))
01828 {
01829 printf( "Error setting motor mode\n" );
01830 }
01831 }
01832
01833 _motorsEnabled = enable;
01834
01835 return ( true );
01836 }
01837
01838 void wbr914::SetContourMode( ProfileMode_t prof )
01839 {
01840 uint8_t ret[2];
01841
01842 if ( (sendCmd16( LEFT_MOTOR, SETPROFILEMODE, prof, 2, ret)<0)||
01843 (sendCmd16( RIGHT_MOTOR, SETPROFILEMODE, prof, 2, ret)<0))
01844 {
01845 printf( "Error setting profile mode\n" );
01846 }
01847 }
01848
01849
01850 void wbr914::SetMicrosteps()
01851 {
01852 uint8_t ret[2];
01853
01854 if ( (sendCmd16( LEFT_MOTOR, SETPHASECOUNTS, (short)MOTOR_TICKS_PER_STEP*4, 2, ret)<0)||
01855 (sendCmd16( RIGHT_MOTOR, SETPHASECOUNTS, (short)MOTOR_TICKS_PER_STEP*4, 2, ret)<0))
01856 {
01857 printf( "Error setting phase counts\n" );
01858 }
01859 }
01860
01861
01862 int32_t wbr914::Meters2Ticks( float meters )
01863 {
01864 return (int32_t)( (double)meters * GEAR_RATIO * MOTOR_TICKS_PER_REV / WHEEL_CIRC);
01865 }
01866
01867 float wbr914::Ticks2Meters( int32_t ticks )
01868 {
01869 return (float)( WHEEL_CIRC*((double)ticks/GEAR_RATIO)/ MOTOR_TICKS_PER_REV );
01870 }
01871
01872 int32_t wbr914::MPS2Vel( float mps )
01873 {
01874 return (int32_t)( (double)mps * _velocityK );
01875
01876 }
01877
01878 float wbr914::Vel2MPS( int32_t count )
01879 {
01880 return (float)( (double)count/_velocityK );
01881
01882 }
01883
01884 int32_t wbr914::BytesToInt32(unsigned char *ptr)
01885 {
01886 unsigned char char0,char1,char2,char3;
01887 int32_t data = 0;
01888
01889 char0 = ptr[3];
01890 char1 = ptr[2];
01891 char2 = ptr[1];
01892 char3 = ptr[0];
01893
01894 data |= ((int)char0) & 0x000000FF;
01895 data |= (((int)char1) << 8) & 0x0000FF00;
01896 data |= (((int)char2) << 16) & 0x00FF0000;
01897 data |= (((int)char3) << 24) & 0xFF000000;
01898
01899
01900
01901 return data;
01902 }
01903
01904 int16_t wbr914::BytesToInt16(unsigned char *ptr)
01905 {
01906 unsigned char char0,char1;
01907 int16_t data = 0;
01908
01909 char0 = ptr[1];
01910 char1 = ptr[0];
01911
01912 data |= ((int)char0) & 0x000000FF;
01913 data |= (((int)char1) << 8) & 0x0000FF00;
01914
01915
01916
01917 return data;
01918 }