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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00148 #include <fcntl.h>
00149 #include <signal.h>
00150 #include <sys/stat.h>
00151 #include <sys/types.h>
00152 #include <stdio.h>
00153 #include <string.h>
00154 #include <termios.h>
00155 #include <unistd.h>
00156 #include <math.h>
00157 #include <stdlib.h>
00158 #include <netinet/in.h>
00159 #include <ctype.h>
00160
00161 #include <reb.h>
00162
00163 #include <error.h>
00164 #include <playertime.h>
00165 extern PlayerTime* GlobalTime;
00166
00167
00168
00169 #include <devicetable.h>
00170 extern int global_playerport;
00171
00172
00173
00174
00175 #define DEBUG_CONFIG
00176
00177
00178 #define DEG2RAD(x) (((double)(x))*0.01745329251994)
00179 #define RAD2DEG(x) (((double)(x))*57.29577951308232)
00180
00181
00182
00183 #define DEG2RAD_FIX(x) ((x) * 174)
00184 #define RAD2DEG_FIX(x) ((x) * 572958)
00185
00186
00187
00188
00189
00190 Driver*
00191 REB_Init(ConfigFile *cf, int section)
00192 {
00193 return (Driver *) new REB( cf, section);
00194 }
00195
00196
00197
00198
00199
00200 void
00201 REB_Register(DriverTable *table)
00202 {
00203 table->AddDriver("reb", REB_Init);
00204 }
00205
00206 REB::REB(ConfigFile *cf, int section)
00207 : Driver(cf,section)
00208 {
00209
00210 memset(&this->position_id, 0, sizeof(player_device_id_t));
00211 memset(&this->ir_id, 0, sizeof(player_device_id_t));
00212 memset(&this->power_id, 0, sizeof(player_device_id_t));
00213
00214 last_trans_command=last_rot_command=0;
00215 leftvel=rightvel=0;
00216 leftpos=rightpos=0;
00217
00218
00219 this->position_subscriptions = 0;
00220 this->ir_subscriptions = 0;
00221
00222
00223 if(cf->ReadDeviceId(&(this->position_id), section, "provides",
00224 PLAYER_POSITION2D_CODE, -1, NULL) == 0)
00225 {
00226 if(this->AddInterface(this->position_id, PLAYER_ALL_MODE) != 0)
00227 {
00228 this->SetError(-1);
00229 return;
00230 }
00231 }
00232
00233
00234 if(cf->ReadDeviceId(&(this->ir_id), section, "provides",
00235 PLAYER_IR_CODE, -1, NULL) == 0)
00236 {
00237 if(this->AddInterface(this->ir_id, PLAYER_READ_MODE) != 0)
00238 {
00239 this->SetError(-1);
00240 return;
00241 }
00242 }
00243
00244
00245 if(cf->ReadDeviceId(&(this->power_id), section, "provides",
00246 PLAYER_POWER_CODE, -1, NULL) == 0)
00247 {
00248 if(this->AddInterface(this->power_id, PLAYER_READ_MODE) != 0)
00249 {
00250 this->SetError(-1);
00251 return;
00252 }
00253 }
00254
00255
00256 initialize_reb_params();
00257
00258
00259
00260
00261 strncpy(reb_serial_port,REB_DEFAULT_SERIAL_PORT,sizeof(reb_serial_port));
00262 reb_fd = -1;
00263 param_index = 0;
00264
00265
00266
00267 write_pfd.events = POLLOUT;
00268 read_pfd.events = POLLIN;
00269
00270
00271 strncpy(reb_serial_port, cf->ReadString(section, "port", reb_serial_port),
00272 sizeof(reb_serial_port));
00273
00274 char subclass[32] = "slow";
00275 strncpy(subclass, cf->ReadString(section, "subclass", subclass),
00276 strlen(subclass));
00277 if (!strcmp(subclass, "fast")) {
00278 param_index = 1;
00279 } else {
00280 param_index = 0;
00281 }
00282
00283
00284 last_lpos = 0;
00285 last_rpos = 0;
00286 last_x_f=0;
00287 last_y_f=0;
00288 last_theta = 0.0;
00289 }
00290
00291
00292
00293
00294
00295 int
00296 REB::Setup()
00297 {
00298 struct termios oldtio;
00299 struct termios params;
00300
00301
00302 printf("REB: connection initializing (%s)...\n", this->reb_serial_port);
00303 fflush(stdout);
00304
00305 if ((this->reb_fd = open(this->reb_serial_port, O_RDWR | O_NOCTTY)) == -1) {
00306 perror("REB::Setup():open()");
00307 return(1);
00308 }
00309
00310
00311 write_pfd.fd = reb_fd;
00312 read_pfd.fd = reb_fd;
00313
00314 memset(¶ms, 0, sizeof(params));
00315 tcgetattr(this->reb_fd, &oldtio);
00316 params.c_cflag = REB_BAUDRATE | CS8 | CLOCAL | CREAD | CSTOPB;
00317 params.c_iflag = 0;
00318 params.c_oflag = 0;
00319 params.c_lflag = ICANON;
00320
00321 params.c_cc[VMIN] = 0;
00322 params.c_cc[VTIME] = 0;
00323
00324 tcflush(this->reb_fd, TCIFLUSH);
00325 tcsetattr(this->reb_fd, TCSANOW, ¶ms);
00326
00327
00328
00329
00330 SetIRState(REB_IR_STOP);
00331
00332 refresh_last_position = false;
00333 motors_enabled = false;
00334 velocity_mode = true;
00335 direct_velocity_control = false;
00336
00337 desired_heading = 0;
00338
00339
00340
00341
00342
00343
00344
00345 StartThread();
00346 return(0);
00347 }
00348
00349
00350 int
00351 REB::Shutdown()
00352 {
00353 printf("REB: SHUTDOWN\n");
00354
00355 StopThread();
00356
00357 SetSpeed(REB_MOTOR_LEFT, 0);
00358 SetSpeed(REB_MOTOR_RIGHT, 0);
00359
00360 SetIRState(REB_IR_STOP);
00361
00362 close(reb_fd);
00363 reb_fd = -1;
00364 return(0);
00365 }
00366
00367 int
00368 REB::Subscribe(player_device_id_t id)
00369 {
00370 int setupResult;
00371
00372
00373 if((setupResult = Driver::Subscribe(id)) == 0)
00374 {
00375
00376 switch(id.code)
00377 {
00378 case PLAYER_POSITION2D_CODE:
00379 this->position_subscriptions++;
00380 break;
00381 case PLAYER_IR_CODE:
00382 this->ir_subscriptions++;
00383 break;
00384 }
00385 }
00386
00387 return(setupResult);
00388 }
00389
00390 int
00391 REB::Unsubscribe(player_device_id_t id)
00392 {
00393 int shutdownResult;
00394
00395
00396 if((shutdownResult = Driver::Unsubscribe(id)) == 0)
00397 {
00398
00399 switch(id.code)
00400 {
00401 case PLAYER_POSITION2D_CODE:
00402 assert(--this->position_subscriptions >= 0);
00403 break;
00404 case PLAYER_IR_CODE:
00405 assert(--this->ir_subscriptions >= 0);
00406 break;
00407 }
00408 }
00409
00410 return(shutdownResult);
00411 }
00412
00413
00414 void
00415 REB::Main()
00416 {
00417 int last_ir_subscrcount=0;
00418 int last_position_subscrcount=0;
00419
00420
00421 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
00422
00423 while (1) {
00424
00425
00426 if(!last_ir_subscrcount && this->ir_subscriptions)
00427 {
00428
00429 SetIRState(REB_IR_START);
00430
00431
00432
00433 player_ir_data_t ir_data;
00434 memset(&ir_data,0,sizeof(player_ir_data_t));
00435 PutMsg(this->ir_id,NULL, PLAYER_MSGTYPE_DATA, 0,(unsigned char*)&ir_data,
00436 sizeof(player_ir_data_t),NULL);
00437 }
00438 else if(last_ir_subscrcount && !this->ir_subscriptions)
00439 {
00440
00441 SetIRState(REB_IR_STOP);
00442 }
00443 last_ir_subscrcount = this->ir_subscriptions;
00444
00445
00446
00447
00448 if(!last_position_subscrcount && this->position_subscriptions)
00449 {
00450 printf("REB: first pos sub. turn off and reset\n");
00451
00452 SetSpeed(REB_MOTOR_LEFT, 0);
00453 SetSpeed(REB_MOTOR_RIGHT, 0);
00454
00455 SetOdometry(0,0,0);
00456
00457
00458 ConfigSpeedPID(0, 1000, 0, 10);
00459 ConfigSpeedPID(2, 1000, 0, 10);
00460 ConfigPosPID(0, 100, 0, 10);
00461 ConfigPosPID(2, 100, 0, 10);
00462
00463
00464 int spd = (int) rint(100.0 *
00465 PlayerUBotRobotParams[this->param_index].PulsesPerMMMS);
00466
00467
00468 int acc = (int) rint(100.0 *
00469 PlayerUBotRobotParams[this->param_index].PulsesPerMMMS);
00470
00471 if (acc > REB_MAX_ACC) {
00472 acc = REB_MAX_ACC;
00473 } else if (acc == 0) {
00474 acc = REB_MIN_ACC;
00475 }
00476 ConfigSpeedProfile(0, spd, acc);
00477 ConfigSpeedProfile(2, spd, acc);
00478
00479 }
00480 else if(last_position_subscrcount && !this->position_subscriptions)
00481 {
00482
00483 printf("REB: last pos sub gone\n");
00484 SetSpeed(REB_MOTOR_LEFT, 0);
00485 SetSpeed(REB_MOTOR_RIGHT, 0);
00486
00487
00488 player_position_cmd_t position_cmd;
00489 memset(&position_cmd,0,sizeof(position_cmd));
00490
00491
00492 ProcessCommand(&position_cmd);
00493 }
00494 last_position_subscrcount = this->position_subscriptions;
00495
00496
00497
00498 ProcessMessages();
00499
00500 pthread_testcancel();
00501
00502
00503 UpdateData();
00504
00505 pthread_testcancel();
00506
00507 }
00508 pthread_exit(NULL);
00509 }
00510
00511 int REB::ProcessCommand(player_position_cmd_t * poscmd)
00512 {
00513 player_position_cmd_t & cmd = * poscmd;
00514 if(this->position_subscriptions)
00515 {
00516 bool newtrans = false, newrot = false, newheading=false;
00517 bool newposcommand=false;
00518 short trans_command, rot_command, heading_command;
00519
00520 if ((trans_command = (short)ntohl(cmd.xspeed)) !=
00521 last_trans_command) {
00522 newtrans = true;
00523 last_trans_command = trans_command;
00524 }
00525
00526 if ((rot_command = (short) ntohl(cmd.yawspeed)) !=
00527 last_rot_command) {
00528 newrot = true;
00529 last_rot_command = rot_command;
00530 }
00531
00532 if ((heading_command = (short) ntohl(cmd.yaw)) !=
00533 this->desired_heading) {
00534 newheading = true;
00535 this->desired_heading = heading_command;
00536 }
00537
00538 if (this->velocity_mode) {
00539
00540
00541 if (!this->direct_velocity_control) {
00542
00543
00544
00545 int diff = this->desired_heading - this->current_heading;
00546
00547
00548 if (diff > 180) {
00549 diff += -360;
00550 } else if (diff < -180) {
00551 diff += 360;
00552 }
00553
00554 int trans_long = (int) trans_command;
00555 int rot_long = (int) rot_command;
00556
00557
00558
00559 int err_ratio = diff*REB_FIXED_FACTOR / 180;
00560
00561
00562
00563 trans_long = (REB_FIXED_FACTOR - ABS(err_ratio))*trans_long;
00564
00565
00566
00567
00568
00569 trans_long /= REB_FIXED_FACTOR;
00570
00571
00572
00573
00574
00575 rot_long = err_ratio*3*rot_long;
00576 rot_long /= REB_FIXED_FACTOR;
00577
00578
00579
00580
00581 trans_command = (short)trans_long;
00582 rot_command = (short) rot_long;
00583
00584 #ifdef DEBUG_POS
00585 printf("REB: PD: diff=%d err=%d des=%d curr=%d trans=%d rot=%d\n",
00586 diff, err_ratio, this->desired_heading, this->current_heading,
00587 trans_command, rot_command);
00588 #endif
00589
00590 if (ABS(last_trans_command) - ABS(trans_command) < 0) {
00591
00592
00593 trans_command = SGN(trans_command)* last_trans_command;
00594 }
00595
00596 if (ABS(last_rot_command) - ABS(rot_command) < 0) {
00597 rot_command = SGN(rot_command)*last_rot_command;
00598 }
00599 }
00600
00601
00602
00603 long rot_term_fixed = rot_command *
00604 PlayerUBotRobotParams[this->param_index].RobotAxleLength / 2;
00605
00606 rot_term_fixed = DEG2RAD_FIX(rot_term_fixed);
00607
00608 leftvel = trans_command*REB_FIXED_FACTOR - rot_term_fixed;
00609 rightvel = trans_command*REB_FIXED_FACTOR + rot_term_fixed;
00610
00611
00612 leftvel /= REB_FIXED_FACTOR;
00613 rightvel /= REB_FIXED_FACTOR;
00614
00615 int max_trans = PlayerUBotRobotParams[this->param_index].MaxVelocity;
00616
00617 if (ABS(leftvel) > max_trans) {
00618 if (leftvel > 0) {
00619 leftvel = max_trans;
00620 rightvel *= max_trans/leftvel;
00621 } else {
00622 leftvel = -max_trans;
00623 rightvel *= -max_trans/leftvel;
00624 }
00625
00626 fprintf(stderr, "REB: left wheel velocity clipped\n");
00627 }
00628
00629 if (ABS(rightvel) > max_trans) {
00630 if (rightvel > 0) {
00631 rightvel = max_trans;
00632 leftvel *= max_trans/rightvel;
00633 } else {
00634 rightvel = -max_trans;
00635 leftvel *= -max_trans/rightvel;
00636 }
00637
00638 fprintf(stderr, "REB: right wheel velocity clipped\n");
00639 }
00640
00641
00642
00643
00644
00645
00646 long lvf = leftvel * PlayerUBotRobotParams[this->param_index].PulsesPerMMMSF +
00647 (REB_FIXED_FACTOR/2);
00648 long rvf = -(rightvel * PlayerUBotRobotParams[this->param_index].PulsesPerMMMSF +
00649 (REB_FIXED_FACTOR/2));
00650
00651 lvf /= REB_FIXED_FACTOR;
00652 rvf /= REB_FIXED_FACTOR;
00653
00654
00655
00656
00657
00658
00659
00660
00661 leftvel = lvf;
00662 rightvel = rvf;
00663
00664
00665 #ifdef DEBUG_POS
00666 printf("REB: [%sABLED] VEL %s: lv=%d rv=%d trans=%d rot=%d\n",
00667 this->motors_enabled ? "EN" : "DIS",
00668 this->direct_velocity_control ?
00669 "DIRECT" : "PD", leftvel, rightvel, trans_command, rot_command);
00670 #endif
00671
00672
00673 if (this->motors_enabled) {
00674 SetSpeed(REB_MOTOR_LEFT, leftvel);
00675 SetSpeed(REB_MOTOR_RIGHT, rightvel);
00676 } else {
00677 SetSpeed(REB_MOTOR_LEFT, 0);
00678 SetSpeed(REB_MOTOR_RIGHT, 0);
00679 }
00680 } else {
00681
00682
00683 double lp, rp;
00684
00685
00686
00687
00688 newposcommand = false;
00689
00690
00691 if (newtrans) {
00692
00693 lp = (double) trans_command;
00694 lp *= PlayerUBotRobotParams[this->param_index].PulsesPerMM;
00695 leftpos = (int)rint(lp);
00696
00697 rp = (double) trans_command;
00698 rp *= PlayerUBotRobotParams[this->param_index].PulsesPerMM;
00699 rightpos = (int) rint(rp);
00700
00701 newposcommand = true;
00702 } else if (newrot) {
00703
00704
00705 lp = -DEG2RAD((double)rot_command)*
00706 PlayerUBotRobotParams[this->param_index].RobotAxleLength/2.0 *
00707 PlayerUBotRobotParams[this->param_index].PulsesPerMM;
00708 rp = -lp;
00709
00710 leftpos = (int) rint(lp);
00711 rightpos = (int) rint(rp);
00712
00713 newposcommand = true;
00714 }
00715
00716 #ifdef DEBUG_POS
00717 printf("REB: [%sABLED] POSITION leftpos=%d rightpos=%d\n",
00718 this->motors_enabled ? "EN" : "DIS", leftpos, rightpos);
00719 #endif
00720
00721
00722
00723
00724 if (this->motors_enabled && newposcommand) {
00725 printf("REB: SENDING POS COMMAND l=%d r=%d\n", leftpos, rightpos);
00726
00727 SetPosCounter(REB_MOTOR_LEFT, 0);
00728 SetPosCounter(REB_MOTOR_RIGHT, 0);
00729 SetPos(REB_MOTOR_LEFT, leftpos);
00730 SetPos(REB_MOTOR_RIGHT, -rightpos);
00731 }
00732 }
00733 }
00734 return 0;
00735 }
00736
00737
00738 int REB::ProcessMessage(ClientData * client, player_msghdr * hdr, uint8_t * data, uint8_t * resp_data, size_t * resp_len)
00739 {
00740 assert(hdr);
00741 assert(data);
00742 assert(resp_data);
00743 assert(resp_len);
00744
00745 if (MatchMessage(hdr, PLAYER_MSGTYPE_CMD, 0, position_id))
00746 {
00747 assert(hdr->size == sizeof(player_position_cmd_t));
00748 ProcessCommand(reinterpret_cast<player_position_cmd_t *> (data));
00749 *resp_len = 0;
00750 return 0;
00751 }
00752
00753 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_IR_REQ_POWER, ir_id))
00754 {
00755 assert(hdr->size == sizeof(player_ir_power_req_t));
00756 player_ir_power_req_t * powreq = reinterpret_cast<player_ir_power_req_t *> (data);
00757
00758 if (powreq->state)
00759 SetIRState(REB_IR_START);
00760 else
00761 SetIRState(REB_IR_STOP);
00762
00763 *resp_len = 0;
00764 return PLAYER_MSGTYPE_RESP_ACK;
00765 }
00766
00767 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_IR_REQ_POSE, ir_id))
00768 {
00769 assert(*resp_len >= sizeof(player_ir_pose_t));
00770 player_ir_pose_t & irpose = *reinterpret_cast<player_ir_pose_t *> (resp_data);
00771
00772 uint16_t numir = PlayerUBotRobotParams[param_index].NumberIRSensors;
00773 irpose.pose_count = htons(numir);
00774 for (int i =0; i < numir; i++) {
00775 int16_t *irp = PlayerUBotRobotParams[param_index].ir_pose[i];
00776 for (int j =0; j < 3; j++) {
00777 irpose.poses[i][j] = htons(irp[j]);
00778 }
00779 }
00780
00781 *resp_len = sizeof(player_ir_pose_t);
00782 return PLAYER_MSGTYPE_RESP_ACK;
00783 }
00784
00785 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER2D_POSITION_REQ_GET_GEOM, position_id))
00786 {
00787
00788
00789 assert(*resp_len >= sizeof(player_position_geom_t));
00790 player_position_geom_t & geom = *reinterpret_cast<player_position_geom_t *> (resp_data);
00791
00792 geom.pose[0] = htons(0);
00793 geom.pose[1] = htons(0);
00794 geom.pose[2] = htons(0);
00795 geom.size[0] = geom.size[1] =
00796 htons( (short) (2 * PlayerUBotRobotParams[this->param_index].RobotRadius));
00797
00798 *resp_len = sizeof(player_position_geom_t);
00799 return PLAYER_MSGTYPE_RESP_ACK;
00800 }
00801
00802 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_MOTOR_POWER, position_id))
00803 {
00804 assert(hdr->size == sizeof(player_position_power_config_t));
00805 player_position_power_config_t * mpowreq = reinterpret_cast<player_position_power_config_t *> (data);
00806
00807 if (mpowreq->value) {
00808 this->motors_enabled = true;
00809 } else {
00810 this->motors_enabled = false;
00811 }
00812
00813 *resp_len = 0;
00814 return PLAYER_MSGTYPE_RESP_ACK;
00815 }
00816
00817
00818
00819
00820 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_VELOCITY_MODE, position_id))
00821 {
00822 assert(hdr->size == sizeof(player_position_velocitymode_config_t));
00823 player_position_velocitymode_config_t * velcont = reinterpret_cast<player_position_velocitymode_config_t *> (data);
00824
00825 if (!velcont->value) {
00826 this->direct_velocity_control = true;
00827 } else {
00828 this->direct_velocity_control = false;
00829 }
00830
00831
00832 this->velocity_mode = true;
00833
00834 *resp_len = 0;
00835 return PLAYER_MSGTYPE_RESP_ACK;
00836 }
00837
00838 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_RESET_ODOM, position_id))
00839 {
00840 SetOdometry(0,0,0);
00841
00842 *resp_len = 0;
00843 return PLAYER_MSGTYPE_RESP_ACK;
00844 }
00845
00846 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_POSITION_MODE, position_id))
00847 {
00848 assert(hdr->size == sizeof(player_position_position_mode_req_t));
00849 player_position_position_mode_req_t * posmode = reinterpret_cast<player_position_position_mode_req_t *> (data);
00850
00851 if (posmode->state) {
00852 this->velocity_mode = false;
00853 } else {
00854 this->velocity_mode = true;
00855 }
00856
00857 *resp_len = 0;
00858 return PLAYER_MSGTYPE_RESP_ACK;
00859 }
00860
00861 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_SET_ODOM, position_id))
00862 {
00863 assert(hdr->size == sizeof(player_position_set_odom_req_t));
00864 player_position_set_odom_req_t * req = reinterpret_cast<player_position_set_odom_req_t *> (data);
00865
00866 #ifdef DEBUG_CONFIG
00867 int x,y;
00868 short theta;
00869 x = ntohl(req->x);
00870 y = ntohl(req->y);
00871 theta = ntohs(req->theta);
00872
00873 printf("REB: SET_ODOM_REQ x=%d y=%d theta=%d\n", x, y, theta);
00874 #endif
00875 SetOdometry(req->x, req->y, req->theta);
00876
00877 *resp_len = 0;
00878 return PLAYER_MSGTYPE_RESP_ACK;
00879 }
00880
00881 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_SPEED_PID, position_id))
00882 {
00883 assert(hdr->size == sizeof(player_position_speed_pid_req_t));
00884 player_position_speed_pid_req_t * pid = reinterpret_cast<player_position_speed_pid_req_t *> (data);
00885
00886 int kp = ntohl(pid->kp);
00887 int ki = ntohl(pid->ki);
00888 int kd = ntohl(pid->kd);
00889
00890 #ifdef DEBUG_CONFIG
00891 printf("REB: SPEED_PID_REQ kp=%d ki=%d kd=%d\n", kp, ki, kd);
00892 #endif
00893
00894 ConfigSpeedPID(REB_MOTOR_LEFT, kp, ki, kd);
00895 ConfigSpeedPID(REB_MOTOR_RIGHT, kp, ki, kd);
00896
00897 *resp_len = 0;
00898 return PLAYER_MSGTYPE_RESP_ACK;
00899 }
00900
00901 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_POSITION_PID, position_id))
00902 {
00903 assert(hdr->size == sizeof(player_position_position_pid_req_t));
00904 player_position_position_pid_req_t * pid = reinterpret_cast<player_position_position_pid_req_t *> (data);
00905
00906 int kp = ntohl(pid->kp);
00907 int ki = ntohl(pid->ki);
00908 int kd = ntohl(pid->kd);
00909
00910 #ifdef DEBUG_CONFIG
00911 printf("REB: POS_PID_REQ kp=%d ki=%d kd=%d\n", kp, ki, kd);
00912 #endif
00913
00914 ConfigPosPID(REB_MOTOR_LEFT, kp, ki, kd);
00915 ConfigPosPID(REB_MOTOR_RIGHT, kp, ki, kd);
00916
00917 *resp_len = 0;
00918 return PLAYER_MSGTYPE_RESP_ACK;
00919 }
00920
00921 if (MatchMessage(hdr, PLAYER_MSGTYPE_REQ, PLAYER_POSITION2D_REQ_SPEED_PROF, position_id))
00922 {
00923 assert(hdr->size == sizeof(player_position_speed_prof_req_t));
00924 player_position_speed_prof_req_t * prof = reinterpret_cast<player_position_speed_prof_req_t *> (data);
00925
00926 int spd = ntohs(prof->speed);
00927 int acc = ntohs(prof->acc);
00928
00929 #ifdef DEBUG_CONFIG
00930 printf("REB: SPEED_PROF_REQ: spd=%d acc=%d spdu=%g accu=%g\n", spd, acc,
00931 spd*PlayerUBotRobotParams[this->param_index].PulsesPerMMMS,
00932 acc*PlayerUBotRobotParams[this->param_index].PulsesPerMMMS);
00933 #endif
00934
00935 spd = (int) rint((double)spd *
00936 PlayerUBotRobotParams[this->param_index].PulsesPerMMMS);
00937
00938
00939 acc = (int) rint((double)acc *
00940 PlayerUBotRobotParams[this->param_index].PulsesPerMMMS);
00941
00942
00943
00944 if (acc > REB_MAX_ACC) {
00945 acc = REB_MAX_ACC;
00946 } else if (acc == 0) {
00947 acc = REB_MIN_ACC;
00948 }
00949
00950 #ifdef DEBUG_CONFIG
00951 printf("REB: SPEED_PROF_REQ: SPD=%d ACC=%d\n", spd, acc);
00952 ConfigSpeedProfile(REB_MOTOR_LEFT, spd, acc);
00953 ConfigSpeedProfile(REB_MOTOR_RIGHT, spd, acc);
00954 #endif
00955
00956 *resp_len = 0;
00957 return PLAYER_MSGTYPE_RESP_ACK;
00958 }
00959
00960 *resp_len = 0;
00961 return -1;
00962 }
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389 void
01390 REB::UpdateData()
01391 {
01392 player_position_data_t position_data;
01393 player_ir_data_t ir_data;
01394 player_power_data_t power_data;
01395
01396 UpdateIRData(&ir_data);
01397 PutMsg(this->ir_id, NULL, PLAYER_MSGTYPE_DATA, 0,
01398 (void*)&ir_data,
01399 sizeof(player_ir_data_t),
01400 NULL);
01401
01402 UpdatePowerData(&power_data);
01403 PutMsg(this->power_id, NULL, PLAYER_MSGTYPE_DATA, 0,
01404 (void*)&power_data,
01405 sizeof(player_power_data_t),
01406 NULL);
01407
01408 UpdatePosData(&position_data);
01409 PutMsg(this->position_id, NULL, PLAYER_MSGTYPE_DATA, 0,
01410 (void*)&position_data,
01411 sizeof(player_position_data_t),
01412 NULL);
01413 }
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423 void
01424 REB::UpdateIRData(player_ir_data_t * d)
01425 {
01426
01427 uint16_t volts[PLAYER_IR_MAX_SAMPLES];
01428
01429 ReadAllIR(volts);
01430
01431 for (int i =0; i < PLAYER_IR_MAX_SAMPLES; i++) {
01432
01433
01434 volts[i] *= 4;
01435 d->voltages[i] = htons(volts[i]);
01436 }
01437
01438 }
01439
01440
01441
01442
01443
01444 void
01445 REB::UpdatePowerData(player_power_data_t *d)
01446 {
01447
01448 uint16_t volt = (uint16_t)ReadAD(REB_BATTERY_CHANNEL);
01449
01450
01451 volt *= 20;
01452 d->charge = htons(volt);
01453 }
01454
01455
01456
01457
01458
01459
01460 void
01461 REB::UpdatePosData(player_position_data_t *d)
01462 {
01463
01464 double x=0, y=0, theta;
01465 long x_f, y_f;
01466 unsigned char target_status =0;
01467 int lreading=0, rreading=0;
01468 long mmpp_f = PlayerUBotRobotParams[this->param_index].MMPerPulsesF;
01469
01470 int x_rem=0, y_rem=0;
01471
01472
01473 if (this->refresh_last_position) {
01474 GlobalTime->GetTime(&(this->last_position));
01475 this->refresh_last_position = false;
01476 }
01477
01478
01479
01480
01481
01482
01483
01484
01485 theta = last_theta;
01486
01487
01488
01489 x_f = last_x_f;
01490 y_f = last_y_f;
01491
01492
01493 struct timeval curr;
01494 GlobalTime->GetTime(&curr);
01495
01496 double v, theta_dot;
01497 long v_f=0;
01498
01499 if (this->velocity_mode) {
01500 int lpos=0, rpos=0, lp, rp;
01501
01502 lpos = ReadPos(REB_MOTOR_LEFT);
01503
01504
01505 rpos = -ReadPos(REB_MOTOR_RIGHT);
01506
01507 lreading = lpos;
01508 rreading = rpos;
01509
01510
01511 long t_f = (curr.tv_sec - this->last_position.tv_sec)*100 +
01512 (curr.tv_usec - this->last_position.tv_usec)/10000;
01513
01514 lp = lpos-last_lpos;
01515 rp = rpos-last_rpos;
01516
01517 last_lpos = lpos;
01518 last_rpos = rpos;
01519
01520
01521 v_f = (rp+lp) * REB_FIXED_FACTOR / 2;
01522 v_f /= t_f;
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532 theta_dot = (rp - lp) /
01533 (PlayerUBotRobotParams[param_index].RobotAxleLength *
01534 PlayerUBotRobotParams[param_index].PulsesPerMM * (double)t_f);
01535
01536 theta += theta_dot * t_f;
01537
01538
01539 theta_dot *= 100.0;
01540
01541
01542 long x_dot_f = (long) (v_f * cos(theta));
01543 long y_dot_f = (long) (v_f * sin(theta));
01544
01545
01546
01547
01548
01549
01550 int base = (mmpp_f * t_f);
01551 x_rem = base * (x_dot_f /100);
01552 assert(ABS(x_rem) <= 0x7FFFFFFF);
01553 x_rem /= 100;
01554
01555 y_rem = base * (y_dot_f / 100);
01556 assert(ABS(y_rem) <= 0x7FFFFFFF);
01557 y_rem /= 100;
01558
01559 x_f += x_rem;
01560 y_f += y_rem;
01561
01562 last_x_f = x_f;
01563 last_y_f = y_f;
01564 last_theta = theta;
01565
01566
01567
01568
01569 x_f /= REB_FIXED_FACTOR;
01570 y_f /= REB_FIXED_FACTOR;
01571 } else {
01572
01573 int rpos=0, lpos=0;
01574 uint8_t rtar;
01575 int mode, error;
01576
01577 v = theta_dot= 0.0;
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587 rtar = ReadStatus(REB_MOTOR_RIGHT, &mode, &error);
01588
01589 target_status = rtar;
01590
01591
01592
01593
01594 lpos = ReadPos(REB_MOTOR_LEFT);
01595 rpos = -ReadPos(REB_MOTOR_RIGHT);
01596
01597 lreading = lpos;
01598 rreading = rpos;
01599 double p;
01600
01601
01602 p = (lpos + rpos) /2.0;
01603
01604
01605 p *= PlayerUBotRobotParams[this->param_index].MMPerPulses;
01606
01607
01608 theta_dot = (rpos - lpos) *
01609 PlayerUBotRobotParams[this->param_index].MMPerPulses /
01610 PlayerUBotRobotParams[this->param_index].RobotAxleLength;
01611
01612
01613 theta += theta_dot;
01614
01615
01616 x += p * cos(theta);
01617 y += p * sin(theta);
01618
01619 x_f = (long) rint(x);
01620 y_f = (long) rint(y);
01621
01622 }
01623
01624 this->current_heading = (int) rint(RAD2DEG(theta));
01625
01626
01627 int rtd = (int) rint(RAD2DEG(theta_dot));
01628
01629
01630
01631
01632 long rv = (v_f/REB_FIXED_FACTOR) *100 * mmpp_f + (REB_FIXED_FACTOR/2);
01633 rv/= REB_FIXED_FACTOR;
01634
01635
01636 this->current_heading %= 360;
01637
01638
01639 if (this->current_heading < 0) {
01640 this->current_heading += 360;
01641 }
01642
01643 #ifdef DEBUG_POS
01644 printf("REB: l%s=%d r%s=%d x=%d y=%d theta=%d trans=%d rot=%d target=%02x\n",
01645 this->velocity_mode ? "vel" : "pos", lreading,
01646 this->velocity_mode ? "vel" : "pos", rreading,
01647 x_f, y_f, this->current_heading, rv, rtd, target_status);
01648 #endif
01649
01650
01651 d->xpos = htonl(x_f);
01652 d->ypos = htonl(y_f);
01653 d->yaw = htonl(this->current_heading);
01654 d->xspeed = htonl(rv);
01655 d->yawspeed = htonl( rtd);
01656 d->stall = target_status;
01657
01658
01659
01660
01661 this->last_position = curr;
01662 }
01663
01664
01665
01666
01667
01668
01669 void
01670 REB::SetOdometry(int x, int y, short theta)
01671 {
01672
01673 SetPosCounter(REB_MOTOR_LEFT, 0);
01674 SetPosCounter(REB_MOTOR_RIGHT, 0);
01675
01676 last_lpos = 0;
01677 last_rpos = 0;
01678
01679 last_x_f = ntohl(x)*REB_FIXED_FACTOR;
01680 last_y_f = ntohl(y)*REB_FIXED_FACTOR;
01681
01682 last_theta = (double) DEG2RAD(ntohs(theta));
01683
01684 player_position_data_t position_data;
01685 memset(&position_data,0,sizeof(player_position_data_t));
01686 PutMsg(this->position_id,NULL, PLAYER_MSGTYPE_DATA, 0,
01687 (void*)&position_data, sizeof(player_position_data_t), NULL);
01688 }
01689
01690
01691
01692
01693
01694 int
01695 REB::write_serial(char *buf, int len)
01696 {
01697 int num, t,i, pret;
01698
01699 #ifdef DEBUG_SERIAL
01700 printf("WRITE: len=%d: ", len);
01701 for (i =0; i < len; i++) {
01702 if (isspace(buf[i])) {
01703 if (buf[i] == ' ') {
01704 printf("%c", ' ');
01705 } else {
01706 printf("'%02x'", buf[i]);
01707 }
01708 } else {
01709 printf("%c", buf[i]);
01710 }
01711 }
01712 printf("\n");
01713 #endif
01714
01715 num = 0;
01716 while (num < len) {
01717
01718
01719 pret = poll(&write_pfd, 1, 1000);
01720
01721 if (pret < 0) {
01722 fprintf(stderr, "REB: write_serial: poll returned error\n");
01723 perror("write_serial");
01724 exit(-1);
01725 } else if (pret == 0) {
01726 fprintf(stderr, "REB: write_serial: poll timed out!\n");
01727 return -1;
01728 }
01729
01730 t = write(this->reb_fd, buf+num, len-num);
01731 if (t < 0) {
01732 switch(errno) {
01733 case EBADF:
01734 fprintf(stderr, "bad file descriptor!!\n");
01735 break;
01736 }
01737
01738 fprintf(stderr, "error writing\n");
01739 for (i = 0; i < len; i++) {
01740 fprintf(stderr, "%c (%02x) ", isprint(buf[i]) ? buf[i] : ' ',
01741 buf[i]);
01742 }
01743 fprintf(stderr, "\n");
01744 return -1;
01745 }
01746
01747 #ifdef _DEBUG
01748 printf("WRITES: wrote %d of %d\n", t, len);
01749 #endif
01750
01751 num += t;
01752 }
01753 return len;
01754 }
01755
01756
01757
01758
01759
01760
01761 int
01762 REB::read_serial_until(char *buf, int len, char *flag, int flen)
01763 {
01764 int num=0,t, pret;
01765
01766 int timeout;
01767
01768 if (velocity_mode) {
01769 timeout = 500;
01770 } else {
01771 timeout = 1500;
01772 }
01773 #ifdef DEBUG_SERIAL
01774 printf("RSU before while flag len=%d len=%d\n", flen, len);
01775 #endif
01776
01777 while (num < len-1) {
01778
01779
01780 pret = poll(&read_pfd, 1, timeout);
01781
01782 if (pret < 0) {
01783 perror("read_serial_until");
01784 exit(-1);
01785 } else if (pret == 0) {
01786 fprintf(stderr, "REB: read_serial_until timed out!\n");
01787 return -1;
01788 }
01789
01790
01791
01792 t = read(this->reb_fd, buf+num, 1);
01793
01794 #ifdef DEBUG_SERIAL
01795 printf("RSU: %c (%02x)\n", isspace(buf[num]) ? ' ' : buf[num], buf[num]);
01796 #endif
01797
01798 if (t < 0) {
01799 fprintf(stderr, "error!!!\n");
01800 switch(errno) {
01801 case EAGAIN:
01802 t = 0;
01803 break;
01804 case EINTR:
01805 return -1;
01806 default:
01807 return -1;
01808 }
01809 }
01810
01811 num ++;
01812 buf[num] = '\0';
01813 if (num >= flen) {
01814
01815 if (!strcmp(buf+num-flen, flag)) {
01816 return 0;
01817 }
01818 }
01819
01820 if (num>= 2) {
01821 buf[num] = '\0';
01822 if (strcmp(buf+num-2, "\r\n") == 0) {
01823 num =0;
01824 #ifdef DEBUG_SERIAL
01825 printf("RSU: MATCHED CRLF\n");
01826 #endif
01827 }
01828 }
01829 }
01830
01831 buf[num] = '\0';
01832 return num;
01833 }
01834
01835
01836
01837
01838
01839
01840
01841
01842 int
01843 REB::write_command(char *buf, int len, int maxsize)
01844 {
01845 static int total=0;
01846 int ret;
01847 char rbuf[256];
01848 int rcount=0;
01849 assert(maxsize < 256);
01850
01851 while (1) {
01852 ret = read_serial_until(rbuf, 256, REB_COMMAND_PROMPT, strlen(REB_COMMAND_PROMPT));
01853
01854 total += write_serial(buf, len);
01855
01856 do {
01857 rcount=0;
01858 ret = read_serial_until(rbuf, maxsize, CRLF, strlen(CRLF));
01859 if (ret < 0) {
01860 Restart();
01861 }
01862 } while (rbuf[0] != tolower(buf[0]) && rcount++ < 2 );
01863
01864 if (ret < 0) {
01865 Restart();
01866 continue;
01867 }
01868
01869 total += ret;
01870 break;
01871 }
01872
01873 memcpy(buf, rbuf, maxsize);
01874 return ret;
01875 }
01876
01877
01878
01879
01880
01881 void
01882 REB::Restart()
01883 {
01884 char buf;
01885 int ret=0,pret=0;
01886
01887 struct pollfd pfd;
01888
01889 pfd.fd = this->reb_fd;
01890 pfd.events = POLLIN;
01891
01892 printf("REB: flushing read channel: ");
01893 fflush(stdout);
01894 do {
01895 pret = poll(&pfd, 1, 2000);
01896
01897 if (pret) {
01898 ret = read(this->reb_fd, &buf, 1);
01899 if (ret) {
01900 if (isalnum(buf)) {
01901 printf("%c", buf);
01902 } else {
01903 printf("%02x", buf);
01904 }
01905 }
01906 } else {
01907 printf("timed out");
01908 break;
01909 }
01910 } while (ret);
01911 printf("\n");
01912
01913
01914
01915 printf("REB: sending restart...");
01916
01917 fflush(stdout);
01918 write_serial("\r", strlen("\r"));
01919
01920 printf("done\n");
01921 }
01922
01923
01924
01925
01926
01927
01928 void
01929 REB::SetIRState(int action)
01930 {
01931 char buf[64];
01932
01933 sprintf(buf, "Y,%c\r", action ? '1' : '0');
01934
01935 write_command(buf, strlen(buf), sizeof(buf));
01936 }
01937
01938
01939
01940
01941
01942
01943 void
01944 REB::ConfigAD(int channel, int action)
01945 {
01946 char buf[64];
01947
01948 sprintf(buf, "Q,%d,%c\r", channel, '0'+action);
01949
01950 write_command(buf, strlen(buf), sizeof(buf));
01951 }
01952
01953
01954
01955
01956
01957 unsigned short
01958 REB::ReadAD(int channel)
01959 {
01960 char buf[64];
01961
01962 sprintf(buf, "I,%d\r", channel);
01963 write_command(buf, strlen(buf), sizeof(buf));
01964
01965 return atoi(&buf[2]);
01966 }
01967
01968
01969
01970
01971
01972
01973 void
01974 REB::ReadAllIR(uint16_t *ir)
01975 {
01976 char buf[64];
01977 int ret;
01978
01979 sprintf(buf, "W\r");
01980 ret = write_command(buf, strlen(buf), sizeof(buf));
01981
01982 int p=0;
01983 for (int i =0; i < PLAYER_IR_MAX_SAMPLES; i++) {
01984
01985 while (buf[p++] != ',') {
01986 if (p >= (int) strlen(buf)) {
01987 return;
01988 }
01989 }
01990 ir[i] = atoi(&buf[p]);
01991 }
01992 }
01993
01994
01995
01996
01997
01998 void
01999 REB::SetSpeed(int mn, int speed)
02000 {
02001 char buf[64];
02002
02003 sprintf(buf, "D,%c,%d\r", '0'+mn, speed);
02004
02005 write_command(buf, strlen(buf), sizeof(buf));
02006 }
02007
02008
02009
02010
02011
02012 int
02013 REB::ReadSpeed(int mn)
02014 {
02015 char buf[64];
02016
02017 sprintf(buf, "E,%c\r", '0'+mn);
02018
02019 write_command(buf, strlen(buf), sizeof(buf));
02020
02021 return atoi(&buf[2]);
02022 }
02023
02024
02025
02026
02027
02028 void
02029 REB::SetPos(int mn, int pos)
02030 {
02031 char buf[64];
02032
02033 sprintf(buf,"C,%c,%d\r", '0'+mn,pos);
02034
02035 write_command(buf, strlen(buf), sizeof(buf));
02036 }
02037
02038
02039
02040
02041
02042 void
02043 REB::SetPosCounter(int mn, int pos)
02044 {
02045 char buf[64];
02046
02047 sprintf(buf,"G,%c,%d\r", '0'+mn,pos);
02048 write_command(buf, strlen(buf), sizeof(buf));
02049 }
02050
02051
02052
02053
02054
02055
02056 int
02057 REB::ReadPos(int mn)
02058 {
02059 char buf[64];
02060
02061 sprintf(buf, "H,%c\r", '0'+mn);
02062 write_command(buf, strlen(buf), sizeof(buf));
02063
02064 return atoi(&buf[2]);
02065 }
02066
02067
02068
02069
02070
02071
02072 void
02073 REB::ConfigPosPID(int mn, int kp, int ki, int kd)
02074 {
02075 char buf[64];
02076
02077 sprintf(buf, "F,%c,%d,%d,%d\r", '0'+mn, kp,ki,kd);
02078 write_command(buf, strlen(buf), sizeof(buf));
02079 }
02080
02081
02082
02083
02084
02085 void
02086 REB::ConfigSpeedPID(int mn, int kp, int ki, int kd)
02087 {
02088 char buf[64];
02089
02090 sprintf(buf, "A,%c,%d,%d,%d\r", '0'+mn, kp,ki,kd);
02091
02092 write_command(buf, strlen(buf), sizeof(buf));
02093 }
02094
02095
02096
02097
02098
02099
02100 void
02101 REB::ConfigSpeedProfile(int mn, int speed, int acc)
02102 {
02103 char buf[64];
02104
02105 sprintf(buf, "J,%c,%d,%d\r", '0'+mn, speed,acc);
02106 write_command(buf, strlen(buf), sizeof(buf));
02107 }
02108
02109
02110
02111
02112
02113
02114
02115 unsigned char
02116 REB::ReadStatus(int mn, int *mode, int *error)
02117 {
02118 char buf[64];
02119
02120 sprintf(buf, "K,%c\r", '0'+mn);
02121 write_command(buf, strlen(buf), sizeof(buf));
02122
02123
02124 int target;
02125
02126 sscanf(buf, "k,%d,%d,%d", &target, mode, error);
02127
02128 return (unsigned char)target;
02129 }