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
00308 #ifdef HAVE_CONFIG_H
00309 #include "config.h"
00310 #endif
00311
00312 #include "p2os.h"
00313 #include <libplayerxdr/playerxdr.h>
00314
00315 #include <fcntl.h>
00316 #include <signal.h>
00317 #include <sys/stat.h>
00318 #include <sys/types.h>
00319 #include <stddef.h>
00320 #include <stdio.h>
00321 #include <string.h>
00322 #include <strings.h>
00323 #include <unistd.h>
00324 #include <math.h>
00325 #include <stdlib.h>
00326 #include <netinet/in.h>
00327 #include <termios.h>
00328 #include <sys/socket.h>
00329 #include <netinet/tcp.h>
00330 #include <netdb.h>
00331
00332 Driver*
00333 P2OS_Init(ConfigFile* cf, int section)
00334 {
00335 return (Driver*)(new P2OS(cf,section));
00336 }
00337
00338 void P2OS_Register(DriverTable* table)
00339 {
00340 table->AddDriver("p2os", P2OS_Init);
00341 }
00342
00343 P2OS::P2OS(ConfigFile* cf, int section)
00344 : Driver(cf,section,true,PLAYER_MSGQUEUE_DEFAULT_MAXLEN)
00345 {
00346
00347 memset(&this->position_id, 0, sizeof(player_devaddr_t));
00348 memset(&this->sonar_id, 0, sizeof(player_devaddr_t));
00349 memset(&this->aio_id, 0, sizeof(player_devaddr_t));
00350 memset(&this->dio_id, 0, sizeof(player_devaddr_t));
00351 memset(&this->gripper_id, 0, sizeof(player_devaddr_t));
00352 memset(&this->bumper_id, 0, sizeof(player_devaddr_t));
00353 memset(&this->power_id, 0, sizeof(player_devaddr_t));
00354 memset(&this->compass_id, 0, sizeof(player_devaddr_t));
00355 memset(&this->gyro_id, 0, sizeof(player_devaddr_t));
00356 memset(&this->blobfinder_id, 0, sizeof(player_devaddr_t));
00357 memset(&this->audio_id, 0, sizeof(player_devaddr_t));
00358 memset(&this->actarray_id, 0, sizeof(player_devaddr_t));
00359 memset(&this->limb_id, 0, sizeof(player_devaddr_t));
00360
00361 this->position_subscriptions = this->sonar_subscriptions = this->actarray_subscriptions = 0;
00362 this->pulse = -1;
00363
00364
00365 sippacket = NULL;
00366
00367
00368 if(cf->ReadDeviceAddr(&(this->position_id), section, "provides",
00369 PLAYER_POSITION2D_CODE, -1, NULL) == 0)
00370 {
00371 if(this->AddInterface(this->position_id) != 0)
00372 {
00373 this->SetError(-1);
00374 return;
00375 }
00376 }
00377
00378
00379 if(cf->ReadDeviceAddr(&(this->compass_id), section, "provides",
00380 PLAYER_POSITION2D_CODE, -1, "compass") == 0)
00381 {
00382 if(this->AddInterface(this->compass_id) != 0)
00383 {
00384 this->SetError(-1);
00385 return;
00386 }
00387 }
00388
00389
00390 if(cf->ReadDeviceAddr(&(this->gyro_id), section, "provides",
00391 PLAYER_POSITION2D_CODE, -1, "gyro") == 0)
00392 {
00393 if(this->AddInterface(this->gyro_id) != 0)
00394 {
00395 this->SetError(-1);
00396 return;
00397 }
00398 }
00399
00400
00401
00402 if(cf->ReadDeviceAddr(&(this->sonar_id), section, "provides",
00403 PLAYER_SONAR_CODE, -1, NULL) == 0)
00404 {
00405 if(this->AddInterface(this->sonar_id) != 0)
00406 {
00407 this->SetError(-1);
00408 return;
00409 }
00410 }
00411
00412
00413
00414 if(cf->ReadDeviceAddr(&(this->aio_id), section, "provides",
00415 PLAYER_AIO_CODE, -1, NULL) == 0)
00416 {
00417 if(this->AddInterface(this->aio_id) != 0)
00418 {
00419 this->SetError(-1);
00420 return;
00421 }
00422 }
00423
00424
00425 if(cf->ReadDeviceAddr(&(this->dio_id), section, "provides",
00426 PLAYER_DIO_CODE, -1, NULL) == 0)
00427 {
00428 if(this->AddInterface(this->dio_id) != 0)
00429 {
00430 this->SetError(-1);
00431 return;
00432 }
00433 }
00434
00435
00436 if(cf->ReadDeviceAddr(&(this->gripper_id), section, "provides",
00437 PLAYER_GRIPPER_CODE, -1, "gripper") == 0)
00438 {
00439 if(this->AddInterface(this->gripper_id) != 0)
00440 {
00441 this->SetError(-1);
00442 return;
00443 }
00444 }
00445
00446
00447 if(cf->ReadDeviceAddr(&(this->lift_id), section, "provides",
00448 PLAYER_ACTARRAY_CODE, -1, "lift") == 0)
00449 {
00450 if(this->AddInterface(this->lift_id) != 0)
00451 {
00452 this->SetError(-1);
00453 return;
00454 }
00455 }
00456
00457
00458 if(cf->ReadDeviceAddr(&(this->bumper_id), section, "provides",
00459 PLAYER_BUMPER_CODE, -1, NULL) == 0)
00460 {
00461 if(this->AddInterface(this->bumper_id) != 0)
00462 {
00463 this->SetError(-1);
00464 return;
00465 }
00466 }
00467
00468
00469 if(cf->ReadDeviceAddr(&(this->power_id), section, "provides",
00470 PLAYER_POWER_CODE, -1, NULL) == 0)
00471 {
00472 if(this->AddInterface(this->power_id) != 0)
00473 {
00474 this->SetError(-1);
00475 return;
00476 }
00477 }
00478
00479
00480 if(cf->ReadDeviceAddr(&(this->blobfinder_id), section, "provides",
00481 PLAYER_BLOBFINDER_CODE, -1, NULL) == 0)
00482 {
00483 if(this->AddInterface(this->blobfinder_id) != 0)
00484 {
00485 this->SetError(-1);
00486 return;
00487 }
00488 }
00489
00490
00491 if(cf->ReadDeviceAddr(&(this->audio_id), section, "provides",
00492 PLAYER_AUDIO_CODE, -1, NULL) == 0)
00493 {
00494 if(this->AddInterface(this->audio_id) != 0)
00495 {
00496 this->SetError(-1);
00497 return;
00498 }
00499 }
00500
00501
00502 if(cf->ReadDeviceAddr(&(this->limb_id), section, "provides", PLAYER_LIMB_CODE, -1, NULL) == 0)
00503 {
00504 if(this->AddInterface(this->limb_id) != 0)
00505 {
00506 this->SetError(-1);
00507 return;
00508 }
00509
00510 kineCalc = new KineCalc;
00511 }
00512 else
00513 kineCalc = NULL;
00514
00515
00516 if(cf->ReadDeviceAddr(&(this->armgripper_id), section, "provides", PLAYER_GRIPPER_CODE, -1, "armgrip") == 0)
00517 {
00518 if(this->AddInterface(this->armgripper_id) != 0)
00519 {
00520 this->SetError(-1);
00521 return;
00522 }
00523 }
00524
00525
00526
00527 if((cf->ReadDeviceAddr(&(this->actarray_id), section, "provides", PLAYER_ACTARRAY_CODE, -1, "arm") == 0) ||
00528 this->limb_id.interf || this->armgripper_id.interf)
00529 {
00530 if(this->AddInterface(this->actarray_id) != 0)
00531 {
00532 this->SetError(-1);
00533 return;
00534 }
00535
00536 this->InQueue->AddReplaceRule (this->actarray_id, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_POS, false);
00537 this->InQueue->AddReplaceRule (this->actarray_id, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_SPEED, false);
00538 this->InQueue->AddReplaceRule (this->actarray_id, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_HOME, false);
00539 }
00540
00541
00542 ::initialize_robot_params();
00543
00544
00545 this->bumpstall = cf->ReadInt(section,"bumpstall",-1);
00546 this->pulse = cf->ReadFloat(section,"pulse",-1);
00547 this->rot_kp = cf->ReadInt(section, "rot_kp", -1);
00548 this->rot_kv = cf->ReadInt(section, "rot_kv", -1);
00549 this->rot_ki = cf->ReadInt(section, "rot_ki", -1);
00550 this->trans_kp = cf->ReadInt(section, "trans_kp", -1);
00551 this->trans_kv = cf->ReadInt(section, "trans_kv", -1);
00552 this->trans_ki = cf->ReadInt(section, "trans_ki", -1);
00553
00554 this->psos_serial_port = cf->ReadString(section,"port",DEFAULT_P2OS_PORT);
00555
00556 this->psos_use_tcp = cf->ReadInt(section, "use_tcp", 0);
00557 this->psos_tcp_host = cf->ReadString(section, "tcp_remote_host", DEFAULT_P2OS_TCP_REMOTE_HOST);
00558 this->psos_tcp_port = cf->ReadInt(section, "tcp_remote_port", DEFAULT_P2OS_TCP_REMOTE_PORT);
00559 this->radio_modemp = cf->ReadInt(section, "radio", 0);
00560 this->joystickp = cf->ReadInt(section, "joystick", 0);
00561 this->direct_wheel_vel_control =
00562 cf->ReadInt(section, "direct_wheel_vel_control", 1);
00563 this->motor_max_speed = (int)rint(1e3 * cf->ReadLength(section,
00564 "max_xspeed",
00565 MOTOR_DEF_MAX_SPEED));
00566 this->motor_max_turnspeed = (int)rint(RTOD(cf->ReadAngle(section,
00567 "max_yawspeed",
00568 MOTOR_DEF_MAX_TURNSPEED)));
00569 this->motor_max_trans_accel = (short)rint(1e3 *
00570 cf->ReadLength(section,
00571 "max_xaccel", 0));
00572 this->motor_max_trans_decel = (short)rint(1e3 *
00573 cf->ReadLength(section,
00574 "max_xdecel", 0));
00575 this->motor_max_rot_accel = (short)rint(RTOD(cf->ReadAngle(section,
00576 "max_yawaccel",
00577 0)));
00578 this->motor_max_rot_decel = (short)rint(RTOD(cf->ReadAngle(section,
00579 "max_yawdecel",
00580 0)));
00581
00582 this->use_vel_band = cf->ReadInt(section, "use_vel_band", 0);
00583
00584
00585 gripperPose.px = cf->ReadTupleFloat(section, "gripper_pose", 0, 0.0f);
00586 gripperPose.py = cf->ReadTupleFloat(section, "gripper_pose", 1, 0.0f);
00587 gripperPose.pz = cf->ReadTupleFloat(section, "gripper_pose", 2, 0.0f);
00588 gripperPose.proll = cf->ReadTupleFloat(section, "gripper_pose", 3, 0.0f);
00589 gripperPose.ppitch = cf->ReadTupleFloat(section, "gripper_pose", 4, 0.0f);
00590 gripperPose.pyaw = cf->ReadTupleFloat(section, "gripper_pose", 5, 0.0f);
00591 gripperOuterSize.sw = cf->ReadTupleFloat(section, "gripper_outersize", 0, 0.315f);
00592 gripperOuterSize.sl = cf->ReadTupleFloat(section, "gripper_outersize", 1, 0.195f);
00593 gripperOuterSize.sh = cf->ReadTupleFloat(section, "gripper_outersize", 2, 0.035f);
00594 gripperInnerSize.sw = cf->ReadTupleFloat(section, "gripper_innersize", 0, 0.205f);
00595 gripperInnerSize.sl = cf->ReadTupleFloat(section, "gripper_innersize", 1, 0.095f);
00596 gripperInnerSize.sh = cf->ReadTupleFloat(section, "gripper_innersize", 2, 0.035f);
00597
00598
00599 armGripperOuterSize.sw = cf->ReadTupleFloat(section, "armgrip_outersize", 0, 0.09f);
00600 armGripperOuterSize.sl = cf->ReadTupleFloat(section, "armgrip_outersize", 1, 0.09f);
00601 armGripperOuterSize.sh = cf->ReadTupleFloat(section, "armgrip_outersize", 2, 0.041f);
00602 armGripperInnerSize.sw = cf->ReadTupleFloat(section, "armgrip_innersize", 0, 0.054f);
00603 armGripperInnerSize.sl = cf->ReadTupleFloat(section, "armgrip_innersize", 1, 0.025f);
00604 armGripperInnerSize.sh = cf->ReadTupleFloat(section, "armgrip_innersize", 2, 1.0f);
00605
00606
00607
00608 aaLengths[0] = cf->ReadTupleFloat(section, "aa_offsets", 1, 0.06875f);
00609 aaLengths[1] = cf->ReadTupleFloat(section, "aa_offsets", 2, 0.16f);
00610 aaLengths[2] = cf->ReadTupleFloat(section, "aa_offsets", 3, 0.0925f);
00611 aaLengths[3] = cf->ReadTupleFloat(section, "aa_offsets", 4, 0.05f);
00612 aaLengths[4] = cf->ReadTupleFloat(section, "aa_offsets", 5, 0.085f);
00613 aaLengths[5] = cf->ReadTupleFloat(section, "aa_offsets", 0, 0.0f);
00614
00615 for (int ii = 0; ii < 18; ii++)
00616 {
00617 aaOrients[ii] = cf->ReadTupleFloat(section, "aa_orients", ii, 0.0f);
00618 }
00619
00620 aaAxes[0] = cf->ReadTupleFloat(section, "aa_axes", 0, 0.0f);
00621 aaAxes[1] = cf->ReadTupleFloat(section, "aa_axes", 1, 0.0f);
00622 aaAxes[2] = cf->ReadTupleFloat(section, "aa_axes", 2, -1.0f);
00623
00624 aaAxes[3] = cf->ReadTupleFloat(section, "aa_axes", 3, 0.0f);
00625 aaAxes[4] = cf->ReadTupleFloat(section, "aa_axes", 4, -1.0f);
00626 aaAxes[5] = cf->ReadTupleFloat(section, "aa_axes", 5, 0.0f);
00627
00628 aaAxes[6] = cf->ReadTupleFloat(section, "aa_axes", 6, 0.0f);
00629 aaAxes[7] = cf->ReadTupleFloat(section, "aa_axes", 7, -1.0f);
00630 aaAxes[8] = cf->ReadTupleFloat(section, "aa_axes", 8, 0.0f);
00631
00632 aaAxes[9] = cf->ReadTupleFloat(section, "aa_axes", 9, 1.0f);
00633 aaAxes[10] = cf->ReadTupleFloat(section, "aa_axes", 10, 0.0f);
00634 aaAxes[11] = cf->ReadTupleFloat(section, "aa_axes", 11, 0.0f);
00635
00636 aaAxes[12] = cf->ReadTupleFloat(section, "aa_axes", 12, 0.0f);
00637 aaAxes[13] = cf->ReadTupleFloat(section, "aa_axes", 13, 1.0f);
00638 aaAxes[14] = cf->ReadTupleFloat(section, "aa_axes", 14, 0.0f);
00639
00640 aaAxes[15] = cf->ReadTupleFloat(section, "aa_axes", 15, 0.0f);
00641 aaAxes[16] = cf->ReadTupleFloat(section, "aa_axes", 16, 0.0f);
00642 aaAxes[17] = cf->ReadTupleFloat(section, "aa_axes", 17, 1.0f);
00643
00644 aaBasePos.px = cf->ReadTupleFloat(section, "aa_basepos", 0, 0.105f);
00645 aaBasePos.py = cf->ReadTupleFloat(section, "aa_basepos", 1, 0.0f);
00646 aaBasePos.pz = cf->ReadTupleFloat(section, "aa_basepos", 2, 0.3185f);
00647 aaBaseOrient.proll = cf->ReadTupleFloat(section, "aa_baseorient", 0, 0.0f);
00648 aaBaseOrient.ppitch = cf->ReadTupleFloat(section, "aa_baseorient", 1, 0.0f);
00649 aaBaseOrient.pyaw = cf->ReadTupleFloat(section, "aa_baseorient", 2, 0.0f);
00650
00651 if(kineCalc)
00652 {
00653 limb_data.state = PLAYER_LIMB_STATE_IDLE;
00654 armOffsetX = cf->ReadTupleFloat(section, "limb_pos", 0, 0.105f);
00655 armOffsetY = cf->ReadTupleFloat(section, "limb_pos", 1, 0.0f);
00656 armOffsetZ = cf->ReadTupleFloat(section, "limb_pos", 2, 0.3185f);
00657 double temp1 = cf->ReadTupleFloat(section, "limb_links", 0, 0.06875f);
00658 double temp2 = cf->ReadTupleFloat(section, "limb_links", 1, 0.16f);
00659 double temp3 = cf->ReadTupleFloat(section, "limb_links", 2, 0.0f);
00660 double temp4 = cf->ReadTupleFloat(section, "limb_links", 3, 0.13775f);
00661 double temp5 = cf->ReadTupleFloat(section, "limb_links", 4, 0.11321f);
00662 kineCalc->SetLinkLengths (temp1, temp2, temp3, temp4, temp5);
00663 kineCalc->SetOffset (0, cf->ReadTupleFloat(section, "limb_offsets", 0, 0.0f));
00664 kineCalc->SetOffset (0, cf->ReadTupleFloat(section, "limb_offsets", 1, 0.0f));
00665 kineCalc->SetOffset (0, cf->ReadTupleFloat(section, "limb_offsets", 2, 0.0f));
00666 kineCalc->SetOffset (0, cf->ReadTupleFloat(section, "limb_offsets", 3, 0.0f));
00667 kineCalc->SetOffset (0, cf->ReadTupleFloat(section, "limb_offsets", 4, 0.0f));
00668 }
00669
00670 this->psos_fd = -1;
00671
00672 sentGripperCmd = false;
00673 sentArmGripperCmd = true;
00674 lastGripperCmd = lastLiftCmd = lastArmGripperCmd = lastActArrayCmd = 255;
00675 memset (&lastLiftPosCmd, 0, sizeof (player_actarray_position_cmd_t));
00676 memset (&lastActArrayPosCmd, 0, sizeof (player_actarray_position_cmd_t));
00677 }
00678
00679 int P2OS::Setup()
00680 {
00681 int i;
00682
00683
00684
00685
00686 int bauds[] = {B9600, B38400, B19200, B115200, B57600};
00687 int numbauds = sizeof(bauds);
00688 int currbaud = 0;
00689
00690 struct termios term;
00691 unsigned char command;
00692 P2OSPacket packet, receivedpacket;
00693 int flags=0;
00694 bool sent_close = false;
00695 enum
00696 {
00697 NO_SYNC,
00698 AFTER_FIRST_SYNC,
00699 AFTER_SECOND_SYNC,
00700 READY
00701 } psos_state;
00702
00703 psos_state = NO_SYNC;
00704
00705 char name[20], type[20], subtype[20];
00706 int cnt;
00707
00708
00709 if(this->psos_use_tcp)
00710 {
00711
00712
00713
00714 printf("P2OS connecting to remote host (%s:%d)... ", this->psos_tcp_host, this->psos_tcp_port);
00715 fflush(stdout);
00716 if( (this->psos_fd = socket(PF_INET, SOCK_STREAM, 0)) < 0)
00717 {
00718 perror("P2OS::Setup():socket():");
00719 return(1);
00720 }
00721
00722 struct hostent* h = gethostbyname(this->psos_tcp_host);
00723 if(!h)
00724 {
00725 perror("Error looking up hostname or address %s:");
00726 return(1);
00727 }
00728 struct sockaddr_in addr;
00729 assert((size_t)h->h_length <= sizeof(addr.sin_addr));
00730
00731 memcpy(&(addr.sin_addr), h->h_addr, h->h_length);
00732
00733 addr.sin_family = AF_INET;
00734 addr.sin_port = htons(this->psos_tcp_port);
00735 printf("Found host address, connecting...");
00736 fflush(stdout);
00737 if(connect(this->psos_fd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
00738 {
00739 perror("Error Connecting to remote host (P2OS::Setup()::connect()):");
00740 return(1);
00741 }
00742 fcntl(this->psos_fd, F_SETFL, O_SYNC | O_NONBLOCK);
00743 if((flags = fcntl(this->psos_fd, F_GETFL)) < 0)
00744 {
00745 perror("P2OS::Setup():fcntl()");
00746 close(this->psos_fd);
00747 this->psos_fd = -1;
00748 return(1);
00749 }
00750 assert(flags & O_NONBLOCK);
00751 printf("TCP socket connection is OK... ");
00752 fflush(stdout);
00753 }
00754 else
00755 {
00756
00757
00758
00759 printf("P2OS connection opening serial port %s...",this->psos_serial_port);
00760 fflush(stdout);
00761
00762 if((this->psos_fd = open(this->psos_serial_port,
00763 O_RDWR | O_SYNC | O_NONBLOCK, S_IRUSR | S_IWUSR )) < 0 )
00764 {
00765 perror("P2OS::Setup():open():");
00766 return(1);
00767 }
00768
00769 if(tcgetattr( this->psos_fd, &term ) < 0 )
00770 {
00771 perror("P2OS::Setup():tcgetattr():");
00772 close(this->psos_fd);
00773 this->psos_fd = -1;
00774 return(1);
00775 }
00776
00777 cfmakeraw( &term );
00778 cfsetispeed(&term, bauds[currbaud]);
00779 cfsetospeed(&term, bauds[currbaud]);
00780
00781 #if defined (__APPLE__)
00782
00783
00784 term.c_cflag |= (CLOCAL | CREAD);
00785
00786
00787
00788
00789
00790 term.c_cflag &= ~PARENB;
00791 term.c_cflag &= ~CSTOPB;
00792 term.c_cflag &= ~CSIZE;
00793 term.c_cflag |= CS8;
00794
00795
00796
00797 term.c_iflag |= (IGNPAR | IGNBRK);
00798
00799
00800 term.c_oflag = 0;
00801
00802
00803
00804
00805 term.c_iflag &= ~(IXON | IXOFF | IXANY);
00806
00807
00808 term.c_lflag = 0;
00809
00810
00811 tcflush(this->psos_fd, TCIOFLUSH);
00812 if (tcsetattr(this->psos_fd, TCSANOW, &term) < 0) {
00813 perror("P2OS::Setup():tcsetattr()");
00814 close(this->psos_fd);
00815 this->psos_fd = -1;
00816 return(1);
00817 }
00818 #else
00819 if(tcsetattr(this->psos_fd, TCSAFLUSH, &term ) < 0)
00820 {
00821 perror("P2OS::Setup():tcsetattr():");
00822 close(this->psos_fd);
00823 this->psos_fd = -1;
00824 return(1);
00825 }
00826
00827 if(tcflush(this->psos_fd, TCIOFLUSH ) < 0)
00828 {
00829 perror("P2OS::Setup():tcflush():");
00830 close(this->psos_fd);
00831 this->psos_fd = -1;
00832 return(1);
00833 }
00834
00835 if((flags = fcntl(this->psos_fd, F_GETFL)) < 0)
00836 {
00837 perror("P2OS::Setup():fcntl()");
00838 close(this->psos_fd);
00839 this->psos_fd = -1;
00840 return(1);
00841 }
00842 #endif
00843
00844
00845
00846 if(this->radio_modemp)
00847 {
00848 puts("Initializing radio modem...");
00849 write(this->psos_fd, "WMS2\r", 5);
00850
00851 usleep(50000);
00852 char modem_buf[50];
00853 int buf_len = read(this->psos_fd, modem_buf, 5);
00854 modem_buf[buf_len]='\0';
00855 printf("wireless modem response = %s\n", modem_buf);
00856
00857 usleep(10000);
00858
00859 buf_len = read(this->psos_fd, modem_buf, 14);
00860 modem_buf[buf_len]='\0';
00861 printf("wireless modem response = %s\n", modem_buf);
00862
00863
00864 int modem_connect_try = 10;
00865 while(strstr(modem_buf, "ected to addres") == NULL)
00866 {
00867 puts("Initializing radio modem...");
00868 write(this->psos_fd, "WMS2\r", 5);
00869
00870 usleep(50000);
00871 char modem_buf[50];
00872 int buf_len = read(this->psos_fd, modem_buf, 5);
00873 modem_buf[buf_len]='\0';
00874 printf("wireless modem response = %s\n", modem_buf);
00875
00876 if(modem_buf[2] == 'P')
00877 {
00878 printf("Please reset partner modem and try again\n");
00879 return(1);
00880 }
00881
00882 if(modem_buf[0] == 'P')
00883 {
00884 printf("Please check partner modem and try again\n");
00885 return(1);
00886 }
00887 if(modem_connect_try-- == 0)
00888 {
00889 usleep(300000);
00890 buf_len = read(this->psos_fd, modem_buf, 40);
00891 modem_buf[buf_len]='\0';
00892 printf("wireless modem response = %s\n", modem_buf);
00893
00894 if(modem_buf[2] == 'P')
00895 {
00896 printf("Please reset partner modem and try again\n");
00897 return(1);
00898 }
00899
00900 if(modem_buf[0] == 'P')
00901 {
00902 printf("Please check partner modem and try again\n");
00903 return(1);
00904 }
00905 if(modem_connect_try-- == 0)
00906 {
00907 puts("Failed to connect radio modem, Trying direct connection...");
00908 break;
00909 }
00910 }
00911 }
00912 }
00913 printf("Connected to robot device, handshaking with P2OS...");
00914 fflush(stdout);
00915 }
00916
00917
00918
00919 int num_sync_attempts = 3;
00920 while(psos_state != READY)
00921 {
00922 switch(psos_state)
00923 {
00924 case NO_SYNC:
00925 command = SYNC0;
00926 packet.Build(&command, 1);
00927 packet.Send(this->psos_fd);
00928 usleep(P2OS_CYCLETIME_USEC);
00929 break;
00930 case AFTER_FIRST_SYNC:
00931 printf("turning off NONBLOCK mode...\n");
00932 if(fcntl(this->psos_fd, F_SETFL, flags ^ O_NONBLOCK) < 0)
00933 {
00934 perror("P2OS::Setup():fcntl()");
00935 close(this->psos_fd);
00936 this->psos_fd = -1;
00937 return(1);
00938 }
00939 command = SYNC1;
00940 packet.Build(&command, 1);
00941 packet.Send(this->psos_fd);
00942 break;
00943 case AFTER_SECOND_SYNC:
00944 command = SYNC2;
00945 packet.Build(&command, 1);
00946 packet.Send(this->psos_fd);
00947 break;
00948 default:
00949 puts("P2OS::Setup():shouldn't be here...");
00950 break;
00951 }
00952 usleep(P2OS_CYCLETIME_USEC);
00953
00954 if(receivedpacket.Receive(this->psos_fd))
00955 {
00956 if((psos_state == NO_SYNC) && (num_sync_attempts >= 0))
00957 {
00958 num_sync_attempts--;
00959 usleep(P2OS_CYCLETIME_USEC);
00960 continue;
00961 }
00962 else
00963 {
00964
00965 if(++currbaud < numbauds)
00966 {
00967 cfsetispeed(&term, bauds[currbaud]);
00968 cfsetospeed(&term, bauds[currbaud]);
00969 if( tcsetattr(this->psos_fd, TCSAFLUSH, &term ) < 0 )
00970 {
00971 perror("P2OS::Setup():tcsetattr():");
00972 close(this->psos_fd);
00973 this->psos_fd = -1;
00974 return(1);
00975 }
00976
00977 if(tcflush(this->psos_fd, TCIOFLUSH ) < 0 )
00978 {
00979 perror("P2OS::Setup():tcflush():");
00980 close(this->psos_fd);
00981 this->psos_fd = -1;
00982 return(1);
00983 }
00984 num_sync_attempts = 3;
00985 continue;
00986 }
00987 else
00988 {
00989
00990 break;
00991 }
00992 }
00993 }
00994
00995 switch(receivedpacket.packet[3])
00996 {
00997 case SYNC0:
00998 psos_state = AFTER_FIRST_SYNC;
00999 break;
01000 case SYNC1:
01001 psos_state = AFTER_SECOND_SYNC;
01002 break;
01003 case SYNC2:
01004 psos_state = READY;
01005 break;
01006 default:
01007
01008
01009 if(!sent_close)
01010 {
01011
01012 command = CLOSE;
01013 packet.Build( &command, 1);
01014 packet.Send(this->psos_fd);
01015 sent_close = true;
01016 usleep(2*P2OS_CYCLETIME_USEC);
01017 tcflush(this->psos_fd,TCIFLUSH);
01018 psos_state = NO_SYNC;
01019 }
01020 break;
01021 }
01022 usleep(P2OS_CYCLETIME_USEC);
01023 }
01024
01025 if(psos_state != READY)
01026 {
01027 if(this->psos_use_tcp)
01028 printf("Couldn't synchronize with P2OS.\n"
01029 " Most likely because the robot is not connected %s %s\n",
01030 this->psos_use_tcp ? "to the ethernet-serial bridge device " : "to the serial port",
01031 this->psos_use_tcp ? this->psos_tcp_host : this->psos_serial_port);
01032 close(this->psos_fd);
01033 this->psos_fd = -1;
01034 return(1);
01035 }
01036
01037 cnt = 4;
01038 cnt += sprintf(name, "%s", &receivedpacket.packet[cnt]);
01039 cnt++;
01040 cnt += sprintf(type, "%s", &receivedpacket.packet[cnt]);
01041 cnt++;
01042 cnt += sprintf(subtype, "%s", &receivedpacket.packet[cnt]);
01043 cnt++;
01044
01045
01046 command = OPEN;
01047 packet.Build(&command, 1);
01048 packet.Send(this->psos_fd);
01049 usleep(P2OS_CYCLETIME_USEC);
01050
01051 command = PULSE;
01052 packet.Build(&command, 1);
01053 packet.Send(this->psos_fd);
01054 usleep(P2OS_CYCLETIME_USEC);
01055
01056 printf("Done.\n Connected to %s, a %s %s\n", name, type, subtype);
01057
01058
01059 for(i=0;i<PLAYER_NUM_ROBOT_TYPES;i++)
01060 {
01061 if(!strcasecmp(PlayerRobotParams[i].Class,type) &&
01062 !strcasecmp(PlayerRobotParams[i].Subclass,subtype))
01063 {
01064 param_idx = i;
01065 break;
01066 }
01067 }
01068 if(i == PLAYER_NUM_ROBOT_TYPES)
01069 {
01070 fputs("P2OS: Warning: couldn't find parameters for this robot; "
01071 "using defaults\n",stderr);
01072 param_idx = 0;
01073 }
01074
01075
01076 if(!this->sippacket)
01077 this->sippacket = new SIP(param_idx);
01078
01079 this->sippacket->x_offset = 0;
01080 this->sippacket->y_offset = 0;
01081 this->sippacket->angle_offset = 0;
01082
01083 SendReceive((P2OSPacket*)NULL,false);
01084
01085
01086 this->ToggleSonarPower(0);
01087
01088 if(this->joystickp)
01089 {
01090
01091 P2OSPacket js_packet;
01092 unsigned char js_command[4];
01093 js_command[0] = JOYDRIVE;
01094 js_command[1] = ARGINT;
01095 js_command[2] = 1;
01096 js_command[3] = 0;
01097 js_packet.Build(js_command, 4);
01098 this->SendReceive(&js_packet,false);
01099 }
01100
01101 if(this->blobfinder_id.interf)
01102 CMUcamReset(false);
01103
01104 if(this->gyro_id.interf)
01105 {
01106
01107 P2OSPacket gyro_packet;
01108 unsigned char gyro_command[4];
01109 gyro_command[0] = GYRO;
01110 gyro_command[1] = ARGINT;
01111 gyro_command[2] = 1;
01112 gyro_command[3] = 0;
01113 gyro_packet.Build(gyro_command, 4);
01114 this->SendReceive(&gyro_packet,false);
01115 }
01116
01117 if (this->actarray_id.interf)
01118 {
01119
01120 P2OSPacket aaPacket;
01121 unsigned char aaCmd[4];
01122 aaCmd[0] = ARM_STATUS;
01123 aaCmd[1] = ARGINT;
01124 aaCmd[2] = 2;
01125 aaCmd[3] = 0;
01126 aaPacket.Build (aaCmd, 4);
01127 SendReceive (&aaPacket,false);
01128
01129 aaCmd[0] = ARM_INFO;
01130 aaPacket.Build (aaCmd, 1);
01131 SendReceive (&aaPacket,false);
01132 }
01133
01134
01135 P2OSPacket accel_packet;
01136 unsigned char accel_command[4];
01137 if(this->motor_max_trans_accel > 0)
01138 {
01139 accel_command[0] = SETA;
01140 accel_command[1] = ARGINT;
01141 accel_command[2] = this->motor_max_trans_accel & 0x00FF;
01142 accel_command[3] = (this->motor_max_trans_accel & 0xFF00) >> 8;
01143 accel_packet.Build(accel_command, 4);
01144 this->SendReceive(&accel_packet,false);
01145 }
01146
01147 if(this->motor_max_trans_decel < 0)
01148 {
01149 accel_command[0] = SETA;
01150 accel_command[1] = ARGNINT;
01151 accel_command[2] = abs(this->motor_max_trans_decel) & 0x00FF;
01152 accel_command[3] = (abs(this->motor_max_trans_decel) & 0xFF00) >> 8;
01153 accel_packet.Build(accel_command, 4);
01154 this->SendReceive(&accel_packet,false);
01155 }
01156 if(this->motor_max_rot_accel > 0)
01157 {
01158 accel_command[0] = SETRA;
01159 accel_command[1] = ARGINT;
01160 accel_command[2] = this->motor_max_rot_accel & 0x00FF;
01161 accel_command[3] = (this->motor_max_rot_accel & 0xFF00) >> 8;
01162 accel_packet.Build(accel_command, 4);
01163 this->SendReceive(&accel_packet,false);
01164 }
01165 if(this->motor_max_rot_decel < 0)
01166 {
01167 accel_command[0] = SETRA;
01168 accel_command[1] = ARGNINT;
01169 accel_command[2] = abs(this->motor_max_rot_decel) & 0x00FF;
01170 accel_command[3] = (abs(this->motor_max_rot_decel) & 0xFF00) >> 8;
01171 accel_packet.Build(accel_command, 4);
01172 this->SendReceive(&accel_packet,false);
01173 }
01174
01175
01176
01177 P2OSPacket pid_packet;
01178 unsigned char pid_command[4];
01179 if(this->rot_kp >= 0)
01180 {
01181 pid_command[0] = ROTKP;
01182 pid_command[1] = ARGINT;
01183 pid_command[2] = this->rot_kp & 0x00FF;
01184 pid_command[3] = (this->rot_kp & 0xFF00) >> 8;
01185 pid_packet.Build(pid_command, 4);
01186 this->SendReceive(&pid_packet);
01187 }
01188 if(this->rot_kv >= 0)
01189 {
01190 pid_command[0] = ROTKV;
01191 pid_command[1] = ARGINT;
01192 pid_command[2] = this->rot_kv & 0x00FF;
01193 pid_command[3] = (this->rot_kv & 0xFF00) >> 8;
01194 pid_packet.Build(pid_command, 4);
01195 this->SendReceive(&pid_packet);
01196 }
01197 if(this->rot_ki >= 0)
01198 {
01199 pid_command[0] = ROTKI;
01200 pid_command[1] = ARGINT;
01201 pid_command[2] = this->rot_ki & 0x00FF;
01202 pid_command[3] = (this->rot_ki & 0xFF00) >> 8;
01203 pid_packet.Build(pid_command, 4);
01204 this->SendReceive(&pid_packet);
01205 }
01206 if(this->trans_kp >= 0)
01207 {
01208 pid_command[0] = TRANSKP;
01209 pid_command[1] = ARGINT;
01210 pid_command[2] = this->trans_kp & 0x00FF;
01211 pid_command[3] = (this->trans_kp & 0xFF00) >> 8;
01212 pid_packet.Build(pid_command, 4);
01213 this->SendReceive(&pid_packet);
01214 }
01215 if(this->trans_kv >= 0)
01216 {
01217 pid_command[0] = TRANSKV;
01218 pid_command[1] = ARGINT;
01219 pid_command[2] = this->trans_kv & 0x00FF;
01220 pid_command[3] = (this->trans_kv & 0xFF00) >> 8;
01221 pid_packet.Build(pid_command, 4);
01222 this->SendReceive(&pid_packet);
01223 }
01224 if(this->trans_ki >= 0)
01225 {
01226 pid_command[0] = TRANSKI;
01227 pid_command[1] = ARGINT;
01228 pid_command[2] = this->trans_ki & 0x00FF;
01229 pid_command[3] = (this->trans_ki & 0xFF00) >> 8;
01230 pid_packet.Build(pid_command, 4);
01231 this->SendReceive(&pid_packet);
01232 }
01233
01234
01235
01236
01237
01238
01239
01240 if(this->bumpstall >= 0)
01241 {
01242 if(this->bumpstall > 3)
01243 PLAYER_ERROR1("ignoring bumpstall value %d; should be 0, 1, 2, or 3",
01244 this->bumpstall);
01245 else
01246 {
01247 PLAYER_MSG1(1, "setting bumpstall to %d", this->bumpstall);
01248 P2OSPacket bumpstall_packet;;
01249 unsigned char bumpstall_command[4];
01250 bumpstall_command[0] = BUMP_STALL;
01251 bumpstall_command[1] = ARGINT;
01252 bumpstall_command[2] = (unsigned char)this->bumpstall;
01253 bumpstall_command[3] = 0;
01254 bumpstall_packet.Build(bumpstall_command, 4);
01255 this->SendReceive(&bumpstall_packet,false);
01256 }
01257 }
01258
01259
01260
01261 #if 0
01262
01263 player_position_cmd_t zero;
01264 memset(&zero,0,sizeof(player_position_cmd_t));
01265 this->PutCommand(this->position_id,(void*)&zero,
01266 sizeof(player_position_cmd_t),NULL);
01267 #endif
01268
01269
01270 this->StartThread();
01271 return(0);
01272 }
01273
01274 int P2OS::Shutdown()
01275 {
01276 unsigned char command[20],buffer[20];
01277 P2OSPacket packet;
01278
01279 memset(buffer,0,20);
01280
01281 if(this->psos_fd == -1)
01282 return(0);
01283
01284 this->StopThread();
01285
01286 command[0] = STOP;
01287 packet.Build(command, 1);
01288 packet.Send(this->psos_fd);
01289 usleep(P2OS_CYCLETIME_USEC);
01290
01291 command[0] = CLOSE;
01292 packet.Build(command, 1);
01293 packet.Send(this->psos_fd);
01294 usleep(P2OS_CYCLETIME_USEC);
01295
01296 close(this->psos_fd);
01297 this->psos_fd = -1;
01298 puts("P2OS has been shutdown");
01299 delete this->sippacket;
01300 this->sippacket = NULL;
01301
01302 return(0);
01303 }
01304
01305 P2OS::~P2OS (void)
01306 {
01307 player_position2d_data_t_cleanup(&p2os_data.position);
01308 player_sonar_data_t_cleanup (&p2os_data.sonar);
01309 player_gripper_data_t_cleanup (&p2os_data.gripper);
01310 player_gripper_data_t_cleanup (&p2os_data.armGripper);
01311 player_power_data_t_cleanup (&p2os_data.power);
01312 player_bumper_data_t_cleanup (&p2os_data.bumper);
01313 player_dio_data_t_cleanup (&p2os_data.dio);
01314 player_aio_data_t_cleanup (&p2os_data.aio);
01315 player_blobfinder_data_t_cleanup (&p2os_data.blobfinder);
01316 player_position2d_data_t_cleanup (&p2os_data.compass);
01317 player_position2d_data_t_cleanup (&p2os_data.gyro);
01318 player_actarray_data_t_cleanup (&p2os_data.lift);
01319 player_actarray_data_t_cleanup (&p2os_data.actArray);
01320
01321 if (kineCalc)
01322 {
01323 delete kineCalc;
01324 kineCalc = NULL;
01325 }
01326 }
01327
01328 int
01329 P2OS::Subscribe(player_devaddr_t id)
01330 {
01331 int setupResult;
01332
01333
01334 if((setupResult = Driver::Subscribe(id)) == 0)
01335 {
01336
01337 if(Device::MatchDeviceAddress(id, this->position_id))
01338 this->position_subscriptions++;
01339 else if(Device::MatchDeviceAddress(id, this->sonar_id))
01340 this->sonar_subscriptions++;
01341 else if(Device::MatchDeviceAddress(id, this->actarray_id) ||
01342 Device::MatchDeviceAddress(id, this->limb_id) ||
01343 Device::MatchDeviceAddress(id, this->armgripper_id))
01344
01345
01346 this->actarray_subscriptions++;
01347 }
01348
01349 return(setupResult);
01350 }
01351
01352 int
01353 P2OS::Unsubscribe(player_devaddr_t id)
01354 {
01355 int shutdownResult;
01356
01357
01358 if((shutdownResult = Driver::Unsubscribe(id)) == 0)
01359 {
01360
01361 if(Device::MatchDeviceAddress(id, this->position_id))
01362 {
01363 this->position_subscriptions--;
01364 assert(this->position_subscriptions >= 0);
01365 }
01366 else if(Device::MatchDeviceAddress(id, this->sonar_id))
01367 {
01368 this->sonar_subscriptions--;
01369 assert(this->sonar_subscriptions >= 0);
01370 }
01371 else if(Device::MatchDeviceAddress(id, this->actarray_id) ||
01372 Device::MatchDeviceAddress(id, this->limb_id) ||
01373 Device::MatchDeviceAddress(id, this->armgripper_id))
01374 {
01375
01376
01377 this->actarray_subscriptions--;
01378 assert(this->actarray_subscriptions >= 0);
01379 }
01380 }
01381
01382 return(shutdownResult);
01383 }
01384
01385 void
01386 P2OS::StandardSIPPutData(double timestampStandardSIP)
01387 {
01388
01389 this->Publish(this->position_id,
01390 PLAYER_MSGTYPE_DATA,
01391 PLAYER_POSITION2D_DATA_STATE,
01392 (void*)&(this->p2os_data.position),
01393 sizeof(player_position2d_data_t),
01394 ×tampStandardSIP);
01395
01396
01397 this->Publish(this->sonar_id,
01398 PLAYER_MSGTYPE_DATA,
01399 PLAYER_SONAR_DATA_RANGES,
01400 (void*)&(this->p2os_data.sonar),
01401 sizeof(player_sonar_data_t),
01402 ×tampStandardSIP);
01403 delete this->p2os_data.sonar.ranges;
01404
01405
01406 this->Publish(this->aio_id,
01407 PLAYER_MSGTYPE_DATA,
01408 PLAYER_AIO_DATA_STATE,
01409 (void*)&(this->p2os_data.aio),
01410 sizeof(player_aio_data_t),
01411 ×tampStandardSIP);
01412
01413
01414 this->Publish(this->dio_id,
01415 PLAYER_MSGTYPE_DATA,
01416 PLAYER_DIO_DATA_VALUES,
01417 (void*)&(this->p2os_data.dio),
01418 sizeof(player_dio_data_t),
01419 ×tampStandardSIP);
01420
01421
01422 this->Publish(this->gripper_id,
01423 PLAYER_MSGTYPE_DATA,
01424 PLAYER_GRIPPER_DATA_STATE,
01425 (void*)&(this->p2os_data.gripper),
01426 sizeof(player_gripper_data_t),
01427 ×tampStandardSIP);
01428
01429
01430 this->Publish(this->lift_id,
01431 PLAYER_MSGTYPE_DATA,
01432 PLAYER_ACTARRAY_DATA_STATE,
01433 (void*)&(this->p2os_data.lift),
01434 sizeof(player_actarray_data_t),
01435 ×tampStandardSIP);
01436
01437
01438 this->Publish(this->bumper_id,
01439 PLAYER_MSGTYPE_DATA,
01440 PLAYER_BUMPER_DATA_STATE,
01441 (void*)&(this->p2os_data.bumper),
01442 sizeof(player_bumper_data_t),
01443 ×tampStandardSIP);
01444
01445
01446 this->Publish(this->power_id,
01447 PLAYER_MSGTYPE_DATA,
01448 PLAYER_POWER_DATA_STATE,
01449 (void*)&(this->p2os_data.power),
01450 sizeof(player_power_data_t),
01451 ×tampStandardSIP);
01452
01453
01454 this->Publish(this->compass_id,
01455 PLAYER_MSGTYPE_DATA,
01456 PLAYER_POSITION2D_DATA_STATE,
01457 (void*)&(this->p2os_data.compass),
01458 sizeof(player_position2d_data_t),
01459 ×tampStandardSIP);
01460 }
01461
01462 void
01463 P2OS::GyroPutData(double timestampGyro)
01464 {
01465
01466 this->Publish(this->gyro_id,
01467 PLAYER_MSGTYPE_DATA,
01468 PLAYER_POSITION2D_DATA_STATE,
01469 (void*)&(this->p2os_data.gyro),
01470 sizeof(player_position2d_data_t),
01471 ×tampGyro);
01472 }
01473
01474 void
01475 P2OS::BlobfinderPutData(double timestampSERAUX)
01476 {
01477
01478 this->Publish(this->blobfinder_id,
01479 PLAYER_MSGTYPE_DATA,
01480 PLAYER_BLOBFINDER_DATA_BLOBS,
01481 (void*)&(this->p2os_data.blobfinder),
01482 sizeof(player_blobfinder_data_t),
01483 ×tampSERAUX);
01484 }
01485
01486 void
01487 P2OS::ActarrayPutData(double timestampArm)
01488 {
01489
01490 this->Publish(this->actarray_id,
01491 PLAYER_MSGTYPE_DATA,
01492 PLAYER_ACTARRAY_DATA_STATE,
01493 (void*)&(this->p2os_data.actArray),
01494 sizeof(player_actarray_data_t),
01495 ×tampArm);
01496 delete[] this->p2os_data.actArray.actuators;
01497
01498
01499 this->Publish(this->limb_id,
01500 PLAYER_MSGTYPE_DATA,
01501 PLAYER_LIMB_DATA_STATE,
01502 (void*)&(this->limb_data),
01503 sizeof(player_limb_data_t),
01504 ×tampArm);
01505
01506
01507 this->Publish(this->armgripper_id,
01508 PLAYER_MSGTYPE_DATA,
01509 PLAYER_GRIPPER_DATA_STATE,
01510 (void*)&(this->p2os_data.armGripper),
01511 sizeof(player_gripper_data_t),
01512 ×tampArm);
01513 }
01514
01515 void
01516 P2OS::Main()
01517 {
01518 int last_sonar_subscrcount=0;
01519 int last_position_subscrcount=0;
01520 int last_actarray_subscrcount=0;
01521 double currentTime;
01522 struct timeval timeVal;
01523
01524 for(;;)
01525 {
01526 pthread_testcancel();
01527
01528
01529
01530 this->Lock();
01531 if(!last_sonar_subscrcount && this->sonar_subscriptions)
01532 this->ToggleSonarPower(1);
01533 else if(last_sonar_subscrcount && !(this->sonar_subscriptions))
01534 this->ToggleSonarPower(0);
01535 last_sonar_subscrcount = this->sonar_subscriptions;
01536
01537
01538 if(!last_actarray_subscrcount && this->actarray_subscriptions)
01539 this->ToggleActArrayPower(1, false);
01540 else if(last_actarray_subscrcount && !(this->actarray_subscriptions))
01541 this->ToggleActArrayPower(0, false);
01542 last_actarray_subscrcount = this->actarray_subscriptions;
01543
01544
01545
01546
01547 if(!last_position_subscrcount && this->position_subscriptions)
01548 {
01549 this->ToggleMotorPower(0);
01550 this->ResetRawPositions();
01551 }
01552 else if(last_position_subscrcount && !(this->position_subscriptions))
01553 {
01554
01555 this->ToggleMotorPower(1);
01556 }
01557 last_position_subscrcount = this->position_subscriptions;
01558 this->Unlock();
01559
01560
01561
01562 if(this->blobfinder_id.interf)
01563 {
01564 struct timeval now_tv;
01565 GlobalTime->GetTime(&now_tv);
01566 if (now_tv.tv_sec > lastblob_tv.tv_sec)
01567 {
01568 P2OSPacket cam_packet;
01569 unsigned char cam_command[4];
01570
01571 cam_command[0] = GETAUX2;
01572 cam_command[1] = ARGINT;
01573 cam_command[2] = 0;
01574 cam_command[3] = 0;
01575 cam_packet.Build(cam_command, 4);
01576 SendReceive(&cam_packet);
01577
01578 cam_command[0] = GETAUX2;
01579 cam_command[1] = ARGINT;
01580 cam_command[2] = CMUCAM_MESSAGE_LEN * 2 -1;
01581 cam_command[3] = 0;
01582 cam_packet.Build(cam_command, 4);
01583 SendReceive(&cam_packet);
01584 GlobalTime->GetTime(&lastblob_tv);
01585 }
01586 }
01587
01588
01589 if(!this->InQueue->Empty())
01590 {
01591 ProcessMessages();
01592 }
01593
01594
01595 if (this->pulse != -1)
01596 {
01597 gettimeofday (&timeVal, NULL);
01598 currentTime = static_cast<double> (timeVal.tv_sec) + (static_cast<double> (timeVal.tv_usec) / 1e6);
01599 if ((currentTime - lastPulseTime) > this->pulse)
01600 {
01601 SendPulse ();
01602
01603 lastPulseTime = currentTime;
01604 }
01605 }
01606
01607
01608
01609
01610 SendReceive (NULL, true);
01611 }
01612 }
01613
01614
01615 int
01616 P2OS::SendReceive(P2OSPacket* pkt, bool publish_data)
01617 {
01618 P2OSPacket packet;
01619
01620
01621
01622 memset(&(this->p2os_data),0,sizeof(player_p2os_data_t));
01623 if((this->psos_fd >= 0) && this->sippacket)
01624 {
01625 if(pkt)
01626 pkt->Send(this->psos_fd);
01627
01628
01629 pthread_testcancel();
01630 if(packet.Receive(this->psos_fd))
01631 {
01632 puts("RunPsosThread(): Receive errored");
01633 pthread_exit(NULL);
01634 }
01635
01636 if(packet.packet[0] == 0xFA && packet.packet[1] == 0xFB &&
01637 (packet.packet[3] == 0x30 || packet.packet[3] == 0x31) ||
01638 (packet.packet[3] == 0x32 || packet.packet[3] == 0x33) ||
01639 (packet.packet[3] == 0x34))
01640 {
01641
01642
01643 this->sippacket->ParseStandard( &packet.packet[3] );
01644 this->sippacket->FillStandard(&(this->p2os_data));
01645
01646 if(publish_data)
01647 this->StandardSIPPutData(packet.timestamp);
01648 }
01649 else if(packet.packet[0] == 0xFA && packet.packet[1] == 0xFB &&
01650 packet.packet[3] == SERAUX)
01651 {
01652
01653 }
01654 else if(packet.packet[0] == 0xFA && packet.packet[1] == 0xFB &&
01655 packet.packet[3] == SERAUX2)
01656 {
01657
01658
01659 if(blobfinder_id.interf)
01660 {
01661
01662
01663 this->sippacket->ParseSERAUX( &packet.packet[2] );
01664 this->sippacket->FillSERAUX(&(this->p2os_data));
01665
01666 if(publish_data)
01667 this->BlobfinderPutData(packet.timestamp);
01668
01669 P2OSPacket cam_packet;
01670 unsigned char cam_command[4];
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680 cam_command[0] = GETAUX2;
01681 cam_command[1] = ARGINT;
01682 cam_command[2] = 0;
01683 cam_command[3] = 0;
01684 cam_packet.Build(cam_command, 4);
01685 this->SendReceive(&cam_packet,publish_data);
01686
01687
01688 cam_command[0] = GETAUX2;
01689 cam_command[1] = ARGINT;
01690
01691 cam_command[2] = CMUCAM_MESSAGE_LEN * 2 -1;
01692 cam_command[3] = 0;
01693 cam_packet.Build(cam_command, 4);
01694 this->SendReceive(&cam_packet,publish_data);
01695 GlobalTime->GetTime(&lastblob_tv);
01696 }
01697 }
01698 else if(packet.packet[0] == 0xFA && packet.packet[1] == 0xFB &&
01699 (packet.packet[3] == 0x50 || packet.packet[3] == 0x80) ||
01700
01701 (packet.packet[3] == 0xC0) ||
01702 (packet.packet[3] == 0xD0 || packet.packet[3] == 0xE0))
01703 {
01704
01705
01706
01707 }
01708 else if(packet.packet[0] == 0xFA && packet.packet[1] == 0xFB &&
01709 packet.packet[3] == GYROPAC)
01710 {
01711 if(this->gyro_id.interf)
01712 {
01713
01714 this->sippacket->ParseGyro(&packet.packet[2]);
01715 this->sippacket->FillGyro(&(this->p2os_data));
01716
01717 if(publish_data)
01718 this->GyroPutData(packet.timestamp);
01719
01720
01721
01722
01723
01724
01725
01726 this->SendReceive(NULL,publish_data);
01727 }
01728 }
01729 else if(packet.packet[0] == 0xFA && packet.packet[1] == 0xFB &&
01730 (packet.packet[3] == 0x20))
01731 {
01732
01733 }
01734 else if (packet.packet[0] == 0xFA && packet.packet[1] == 0xFB && packet.packet[3] == ARMPAC)
01735 {
01736 if (actarray_id.interf)
01737 {
01738
01739 double joints[6];
01740 sippacket->ParseArm (&packet.packet[2]);
01741 for (int ii = 0; ii < 6; ii++)
01742 {
01743 sippacket->armJointPosRads[ii] = TicksToRadians (ii, sippacket->armJointPos[ii]);
01744 joints[ii] = sippacket->armJointPosRads[ii];
01745 }
01746 sippacket->FillArm(&p2os_data);
01747 if(kineCalc)
01748 {
01749 kineCalc->CalculateFK (joints);
01750 limb_data.position.px = kineCalc->GetP ().x + armOffsetX;
01751 limb_data.position.py = kineCalc->GetP ().y + armOffsetY;
01752 limb_data.position.pz = kineCalc->GetP ().z + armOffsetZ;
01753 limb_data.approach.px = kineCalc->GetA ().x;
01754 limb_data.approach.py = kineCalc->GetA ().y;
01755 limb_data.approach.pz = kineCalc->GetA ().z;
01756 limb_data.orientation.px = kineCalc->GetO ().x;
01757 limb_data.orientation.py = kineCalc->GetO ().y;
01758 limb_data.orientation.pz = kineCalc->GetO ().z;
01759 if (limb_data.state != PLAYER_LIMB_STATE_OOR && limb_data.state != PLAYER_LIMB_STATE_COLL)
01760 {
01761 if (sippacket->armJointMoving[0] || sippacket->armJointMoving[1] || sippacket->armJointMoving[2] ||
01762 sippacket->armJointMoving[3] || sippacket->armJointMoving[4])
01763 {
01764 limb_data.state = PLAYER_LIMB_STATE_MOVING;
01765 }
01766 else
01767 limb_data.state = PLAYER_LIMB_STATE_IDLE;
01768 }
01769 }
01770 if(publish_data)
01771 this->ActarrayPutData(packet.timestamp);
01772 }
01773
01774
01775 SendReceive(NULL,publish_data);
01776 }
01777 else if (packet.packet[0] == 0xFA && packet.packet[1] == 0xFB && packet.packet[3] == ARMINFOPAC)
01778 {
01779
01780 if (actarray_id.interf)
01781 {
01782 sippacket->ParseArmInfo (&packet.packet[2]);
01783
01784 if (kineCalc)
01785 {
01786 for (int ii = 0; ii < 5; ii++)
01787 kineCalc->SetJointRange (ii, TicksToRadians (ii, sippacket->armJoints[ii].min), TicksToRadians (ii, sippacket->armJoints[ii].max));
01788
01789 }
01790
01791 SendReceive(NULL,publish_data);
01792 }
01793 }
01794 else
01795 {
01796 packet.PrintHex();
01797 }
01798 }
01799
01800 return(0);
01801 }
01802
01803 void
01804 P2OS::ResetRawPositions()
01805 {
01806 P2OSPacket pkt;
01807 unsigned char p2oscommand[4];
01808
01809 if(this->sippacket)
01810 {
01811 this->sippacket->rawxpos = 0;
01812 this->sippacket->rawypos = 0;
01813 this->sippacket->xpos = 0;
01814 this->sippacket->ypos = 0;
01815 p2oscommand[0] = SETO;
01816 p2oscommand[1] = ARGINT;
01817 pkt.Build(p2oscommand, 2);
01818 this->SendReceive(&pkt,false);
01819 }
01820 }
01821
01822
01823
01824
01825
01826
01827
01828 void P2OS::CMUcamReset(bool doLock)
01829 {
01830 CMUcamStopTracking(doLock);
01831
01832 P2OSPacket cam_packet;
01833 unsigned char cam_command[8];
01834
01835 printf("Resetting the CMUcam...\n");
01836 cam_command[0] = TTY3;
01837 cam_command[1] = ARGSTR;
01838 sprintf((char*)&cam_command[3], "RS\r");
01839 cam_command[2] = strlen((char *)&cam_command[3]);
01840 cam_packet.Build(cam_command, (int)cam_command[2]+3);
01841 this->SendReceive(&cam_packet,doLock);
01842
01843
01844 printf("Setting raw mode...\n");
01845 cam_command[0] = TTY3;
01846 cam_command[1] = ARGSTR;
01847 sprintf((char*)&cam_command[3], "RM 3\r");
01848 cam_command[2] = strlen((char *)&cam_command[3]);
01849 cam_packet.Build(cam_command, (int)cam_command[2]+3);
01850 this->SendReceive(&cam_packet,doLock);
01851 usleep(100000);
01852
01853 printf("Flushing serial buffer...\n");
01854 cam_command[0] = GETAUX2;
01855 cam_command[1] = ARGINT;
01856 cam_command[2] = 0;
01857 cam_command[3] = 0;
01858 cam_packet.Build(cam_command, 4);
01859 this->SendReceive(&cam_packet,doLock);
01860
01861 sleep(1);
01862
01863 this->CMUcamStartTracking(false);
01864 }
01865
01866
01867
01868
01869
01870
01871
01872
01873 void P2OS::CMUcamTrack(int rmin, int rmax,
01874 int gmin, int gmax,
01875 int bmin, int bmax)
01876 {
01877 this->CMUcamStopTracking();
01878
01879 P2OSPacket cam_packet;
01880 unsigned char cam_command[50];
01881
01882 if (!rmin && !rmax && !gmin && !gmax && !bmin && !bmax)
01883 {
01884 CMUcamStartTracking();
01885 }
01886 else if (rmin<0 || rmax<0 || gmin<0 || gmax<0 || bmin<0 || bmax<0)
01887 {
01888 printf("Activating CMUcam color tracking (AUTO-mode)...\n");
01889 cam_command[0] = TTY3;
01890 cam_command[1] = ARGSTR;
01891 sprintf((char*)&cam_command[3], "TW\r");
01892 cam_command[2] = strlen((char *)&cam_command[3]);
01893 cam_packet.Build(cam_command, (int)cam_command[2]+3);
01894 this->SendReceive(&cam_packet);
01895 }
01896 else
01897 {
01898 printf("Activating CMUcam color tracking (MANUAL-mode)...\n");
01899
01900
01901 cam_command[0] = TTY3;
01902 cam_command[1] = ARGSTR;
01903 sprintf((char*)&cam_command[3], "TC %d %d %d %d %d %d\r",
01904 rmin, rmax, gmin, gmax, bmin, bmax);
01905 cam_command[2] = strlen((char *)&cam_command[3]);
01906 cam_packet.Build(cam_command, (int)cam_command[2]+3);
01907 this->SendReceive(&cam_packet);
01908 }
01909
01910 cam_command[0] = GETAUX2;
01911 cam_command[1] = ARGINT;
01912 cam_command[2] = CMUCAM_MESSAGE_LEN * 2 -1;
01913 cam_command[3] = 0;
01914 cam_packet.Build(cam_command, 4);
01915 this->SendReceive(&cam_packet);
01916 }
01917
01918
01919
01920
01921 void P2OS::CMUcamStartTracking(bool doLock)
01922 {
01923 P2OSPacket cam_packet;
01924 unsigned char cam_command[50];
01925
01926
01927 cam_command[0] = TTY3;
01928 cam_command[1] = ARGSTR;
01929 sprintf((char*)&cam_command[3], "TC\r");
01930 cam_command[2] = strlen((char *)&cam_command[3]);
01931 cam_packet.Build(cam_command, (int)cam_command[2]+3);
01932 this->SendReceive(&cam_packet,false);
01933 }
01934
01935
01936
01937
01938
01939
01940 void P2OS::CMUcamStopTracking(bool doLock)
01941 {
01942 P2OSPacket cam_packet;
01943 unsigned char cam_command[50];
01944
01945
01946 cam_command[0] = TTY3;
01947 cam_command[1] = ARGSTR;
01948 sprintf((char*)&cam_command[3], "\r");
01949 cam_command[2] = strlen((char *)&cam_command[3]);
01950 cam_packet.Build(cam_command, (int)cam_command[2]+3);
01951 this->SendReceive(&cam_packet,doLock);
01952 }
01953
01954
01955 void
01956 P2OS::ToggleSonarPower(unsigned char val)
01957 {
01958 unsigned char command[4];
01959 P2OSPacket packet;
01960
01961 command[0] = SONAR;
01962 command[1] = ARGINT;
01963 command[2] = val;
01964 command[3] = 0;
01965 packet.Build(command, 4);
01966 SendReceive(&packet,false);
01967 }
01968
01969
01970 void
01971 P2OS::ToggleMotorPower(unsigned char val)
01972 {
01973 unsigned char command[4];
01974 P2OSPacket packet;
01975
01976 command[0] = ENABLE;
01977 command[1] = ARGINT;
01978 command[2] = val;
01979 command[3] = 0;
01980 packet.Build(command, 4);
01981 SendReceive(&packet,false);
01982 }
01983
01985
01987
01988
01989 inline double P2OS::TicksToDegrees (int joint, unsigned char ticks)
01990 {
01991 if ((joint < 0) || (joint >= sippacket->armNumJoints))
01992 return 0;
01993
01994 double result;
01995 int pos = ticks - sippacket->armJoints[joint].centre;
01996 result = 90.0 / static_cast<double> (sippacket->armJoints[joint].ticksPer90);
01997 result = result * pos;
01998 if ((joint >= 0) && (joint <= 2))
01999 result = -result;
02000
02001 return result;
02002 }
02003
02004
02005 inline unsigned char P2OS::DegreesToTicks (int joint, double degrees)
02006 {
02007 double val;
02008
02009 if ((joint < 0) || (joint >= sippacket->armNumJoints))
02010 return 0;
02011
02012 val = static_cast<double> (sippacket->armJoints[joint].ticksPer90) * degrees / 90.0;
02013 val = round (val);
02014 if ((joint >= 0) && (joint <= 2))
02015 val = -val;
02016 val += sippacket->armJoints[joint].centre;
02017
02018 if (val < sippacket->armJoints[joint].min)
02019 return sippacket->armJoints[joint].min;
02020 else if (val > sippacket->armJoints[joint].max)
02021 return sippacket->armJoints[joint].max;
02022 else
02023 return static_cast<int> (round (val));
02024 }
02025
02026 inline double P2OS::TicksToRadians (int joint, unsigned char ticks)
02027 {
02028 double result = DTOR (TicksToDegrees (joint, ticks));
02029 return result;
02030 }
02031
02032 inline unsigned char P2OS::RadiansToTicks (int joint, double rads)
02033 {
02034 unsigned char result = static_cast<unsigned char> (DegreesToTicks (joint, RTOD (rads)));
02035 return result;
02036 }
02037
02038 inline double P2OS::RadsPerSectoSecsPerTick (int joint, double speed)
02039 {
02040 double degs = RTOD (speed);
02041 double ticksPerDeg = static_cast<double> (sippacket->armJoints[joint].ticksPer90) / 90.0f;
02042 double ticksPerSec = degs * ticksPerDeg;
02043 double secsPerTick = 1000.0f / ticksPerSec;
02044
02045 if (secsPerTick > 127)
02046 return 127;
02047 else if (secsPerTick < 1)
02048 return 1;
02049 return secsPerTick;
02050 }
02051
02052 inline double P2OS::SecsPerTicktoRadsPerSec (int joint, double msecs)
02053 {
02054 double ticksPerSec = 1.0 / (static_cast<double> (msecs) / 1000.0);
02055 double ticksPerDeg = static_cast<double> (sippacket->armJoints[joint].ticksPer90) / 90.0f;
02056 double degs = ticksPerSec / ticksPerDeg;
02057 double rads = DTOR (degs);
02058
02059 return rads;
02060 }
02061
02062 void P2OS::ToggleActArrayPower (unsigned char value, bool lock)
02063 {
02064 unsigned char command[4];
02065 P2OSPacket packet;
02066
02067 command[0] = ARM_POWER;
02068 command[1] = ARGINT;
02069 command[2] = value;
02070 command[3] = 0;
02071 packet.Build (command, 4);
02072 SendReceive (&packet, lock);
02073 }
02074
02075 void P2OS::SetActArrayJointSpeed (int joint, double speed)
02076 {
02077 unsigned char command[4];
02078 P2OSPacket packet;
02079
02080 command[0] = ARM_SPEED;
02081 command[1] = ARGINT;
02082 command[2] = static_cast<int> (round (speed));
02083 command[3] = joint;
02084 packet.Build (command, 4);
02085 SendReceive (&packet);
02086 }
02087
02089
02091
02092
02093 int
02094 P2OS::ProcessMessage(QueuePointer & resp_queue,
02095 player_msghdr * hdr,
02096 void * data)
02097 {
02098
02099 HANDLE_CAPABILITY_REQUEST (position_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_CAPABILTIES_REQ);
02100 HANDLE_CAPABILITY_REQUEST (actarray_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_CAPABILTIES_REQ);
02101 HANDLE_CAPABILITY_REQUEST (lift_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_CAPABILTIES_REQ);
02102 HANDLE_CAPABILITY_REQUEST (limb_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_CAPABILTIES_REQ);
02103 HANDLE_CAPABILITY_REQUEST (gripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_CAPABILTIES_REQ);
02104 HANDLE_CAPABILITY_REQUEST (armgripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_CAPABILTIES_REQ);
02105
02106 HANDLE_CAPABILITY_REQUEST (position_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_POSITION2D_CMD_VEL);
02107
02108 HANDLE_CAPABILITY_REQUEST (actarray_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_POS);
02109 HANDLE_CAPABILITY_REQUEST (actarray_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_MULTI_POS);
02110 HANDLE_CAPABILITY_REQUEST (actarray_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_HOME);
02111 HANDLE_CAPABILITY_REQUEST (actarray_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_POWER);
02112 HANDLE_CAPABILITY_REQUEST (actarray_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_GET_GEOM);
02113 HANDLE_CAPABILITY_REQUEST (actarray_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_SPEED);
02114
02115 HANDLE_CAPABILITY_REQUEST (lift_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_POS);
02116 HANDLE_CAPABILITY_REQUEST (lift_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_HOME);
02117 HANDLE_CAPABILITY_REQUEST (lift_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_ACTARRAY_REQ_GET_GEOM);
02118
02119 HANDLE_CAPABILITY_REQUEST (limb_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_LIMB_CMD_HOME);
02120 HANDLE_CAPABILITY_REQUEST (limb_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_LIMB_CMD_STOP);
02121 HANDLE_CAPABILITY_REQUEST (limb_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_LIMB_CMD_SETPOSE);
02122 HANDLE_CAPABILITY_REQUEST (limb_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_LIMB_REQ_POWER);
02123 HANDLE_CAPABILITY_REQUEST (limb_id, resp_queue, hdr, data, PLAYER_MSGTYPE_REQ, PLAYER_LIMB_REQ_GEOM);
02124
02125 HANDLE_CAPABILITY_REQUEST (gripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_OPEN);
02126 HANDLE_CAPABILITY_REQUEST (gripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_CLOSE);
02127 HANDLE_CAPABILITY_REQUEST (gripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_STOP);
02128
02129 HANDLE_CAPABILITY_REQUEST (armgripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_OPEN);
02130 HANDLE_CAPABILITY_REQUEST (armgripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_CLOSE);
02131 HANDLE_CAPABILITY_REQUEST (armgripper_id, resp_queue, hdr, data, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_STOP);
02132
02133
02134 if(hdr->type == PLAYER_MSGTYPE_REQ)
02135 return(this->HandleConfig(resp_queue,hdr,data));
02136 else if(hdr->type == PLAYER_MSGTYPE_CMD)
02137 return(this->HandleCommand(hdr,data));
02138 else
02139 return(-1);
02140 }
02141
02142 int
02143 P2OS::HandleConfig(QueuePointer & resp_queue,
02144 player_msghdr * hdr,
02145 void * data)
02146 {
02147 int joint = 0;
02148 double newSpeed = 0.0f;
02149
02150
02151 if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02152 PLAYER_POSITION2D_REQ_SET_ODOM,
02153 this->position_id))
02154 {
02155 if(hdr->size != sizeof(player_position2d_set_odom_req_t))
02156 {
02157 PLAYER_WARN("Arg to odometry set requests wrong size; ignoring");
02158 return(-1);
02159 }
02160 player_position2d_set_odom_req_t* set_odom_req =
02161 (player_position2d_set_odom_req_t*)data;
02162
02163 this->sippacket->x_offset = ((int)rint(set_odom_req->pose.px*1e3)) -
02164 this->sippacket->xpos;
02165 this->sippacket->y_offset = ((int)rint(set_odom_req->pose.py*1e3)) -
02166 this->sippacket->ypos;
02167 this->sippacket->angle_offset = ((int)rint(RTOD(set_odom_req->pose.pa))) -
02168 this->sippacket->angle;
02169
02170 this->Publish(this->position_id, resp_queue,
02171 PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_SET_ODOM);
02172 return(0);
02173 }
02174 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02175 PLAYER_POSITION2D_REQ_MOTOR_POWER,
02176 this->position_id))
02177 {
02178
02179
02180
02181
02182 if(hdr->size != sizeof(player_position2d_power_config_t))
02183 {
02184 PLAYER_WARN("Arg to motor state change request wrong size; ignoring");
02185 return(-1);
02186 }
02187 player_position2d_power_config_t* power_config =
02188 (player_position2d_power_config_t*)data;
02189 this->ToggleMotorPower(power_config->state);
02190
02191 this->Publish(this->position_id, resp_queue,
02192 PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_MOTOR_POWER);
02193 return(0);
02194 }
02195 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02196 PLAYER_POSITION2D_REQ_RESET_ODOM,
02197 this->position_id))
02198 {
02199
02200 if(hdr->size != 0)
02201 {
02202 PLAYER_WARN("Arg to reset position request is wrong size; ignoring");
02203 return(-1);
02204 }
02205 ResetRawPositions();
02206
02207 this->Publish(this->position_id, resp_queue,
02208 PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_RESET_ODOM);
02209 return(0);
02210 }
02211 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02212 PLAYER_POSITION2D_REQ_GET_GEOM,
02213 this->position_id))
02214 {
02215
02216 if(hdr->size != 0)
02217 {
02218 PLAYER_WARN("Arg get robot geom is wrong size; ignoring");
02219 return(-1);
02220 }
02221 player_position2d_geom_t geom;
02222
02223
02224
02225 geom.pose.px = -0.1;
02226 geom.pose.py = 0.0;
02227 geom.pose.pyaw = 0.0;
02228
02229 geom.size.sl = PlayerRobotParams[param_idx].RobotLength / 1e3;
02230 geom.size.sw = PlayerRobotParams[param_idx].RobotWidth / 1e3;
02231
02232 this->Publish(this->position_id, resp_queue,
02233 PLAYER_MSGTYPE_RESP_ACK,
02234 PLAYER_POSITION2D_REQ_GET_GEOM,
02235 (void*)&geom, sizeof(geom), NULL);
02236 return(0);
02237 }
02238 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02239 PLAYER_POSITION2D_REQ_VELOCITY_MODE,
02240 this->position_id))
02241 {
02242
02243
02244
02245
02246 if(hdr->size != sizeof(player_position2d_velocity_mode_config_t))
02247 {
02248 PLAYER_WARN("Arg to velocity control mode change request is wrong "
02249 "size; ignoring");
02250 return(-1);
02251 }
02252 player_position2d_velocity_mode_config_t* velmode_config =
02253 (player_position2d_velocity_mode_config_t*)data;
02254
02255 if(velmode_config->value)
02256 direct_wheel_vel_control = false;
02257 else
02258 direct_wheel_vel_control = true;
02259
02260 this->Publish(this->position_id, resp_queue,
02261 PLAYER_MSGTYPE_RESP_ACK, PLAYER_POSITION2D_REQ_VELOCITY_MODE);
02262 return(0);
02263 }
02264
02265 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02266 PLAYER_SONAR_REQ_POWER,
02267 this->sonar_id))
02268 {
02269
02270
02271
02272
02273 if(hdr->size != sizeof(player_sonar_power_config_t))
02274 {
02275 PLAYER_WARN("Arg to sonar state change request wrong size; ignoring");
02276 return(-1);
02277 }
02278 player_sonar_power_config_t* sonar_config =
02279 (player_sonar_power_config_t*)data;
02280 this->ToggleSonarPower(sonar_config->state);
02281
02282 this->Publish(this->sonar_id, resp_queue,
02283 PLAYER_MSGTYPE_RESP_ACK, PLAYER_SONAR_REQ_POWER);
02284 return(0);
02285 }
02286 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02287 PLAYER_SONAR_REQ_GET_GEOM,
02288 this->sonar_id))
02289 {
02290
02291 if(hdr->size != 0)
02292 {
02293 PLAYER_WARN("Arg get sonar geom is wrong size; ignoring");
02294 return(-1);
02295 }
02296 player_sonar_geom_t geom;
02297 geom.poses_count = PlayerRobotParams[param_idx].SonarNum;
02298 geom.poses = new player_pose3d_t[geom.poses_count];
02299 for(int i = 0; i < PlayerRobotParams[param_idx].SonarNum; i++)
02300 {
02301 sonar_pose_t pose = PlayerRobotParams[param_idx].sonar_pose[i];
02302 geom.poses[i].px = pose.x / 1e3;
02303 geom.poses[i].py = pose.y / 1e3;
02304 geom.poses[i].pyaw = DTOR(pose.th);
02305 }
02306
02307 this->Publish(this->sonar_id, resp_queue,
02308 PLAYER_MSGTYPE_RESP_ACK, PLAYER_SONAR_REQ_GET_GEOM,
02309 (void*)&geom);
02310 delete [] geom.poses;
02311 return(0);
02312 }
02313
02314 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02315 PLAYER_BLOBFINDER_REQ_SET_COLOR,
02316 this->blobfinder_id))
02317 {
02318
02319
02320 if(hdr->size != sizeof(player_blobfinder_color_config_t))
02321 {
02322 puts("Arg to blobfinder color request wrong size; ignoring");
02323 return(-1);
02324 }
02325 player_blobfinder_color_config_t* color_config =
02326 (player_blobfinder_color_config_t*)data;
02327
02328 CMUcamTrack(color_config->rmin,
02329 color_config->rmax,
02330 color_config->gmin,
02331 color_config->gmax,
02332 color_config->bmin,
02333 color_config->bmax);
02334
02335 this->Publish(this->blobfinder_id, resp_queue,
02336 PLAYER_MSGTYPE_RESP_ACK, PLAYER_BLOBFINDER_REQ_SET_COLOR);
02337 return(0);
02338 }
02339 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,
02340 PLAYER_BLOBFINDER_REQ_SET_IMAGER_PARAMS,
02341 this->blobfinder_id))
02342 {
02343
02344 if(hdr->size != sizeof(player_blobfinder_imager_config_t))
02345 {
02346 puts("Arg to blobfinder imager request wrong size; ignoring");
02347 return(-1);
02348 }
02349 player_blobfinder_imager_config_t* imager_config =
02350 (player_blobfinder_imager_config_t*)data;
02351
02352 P2OSPacket cam_packet;
02353 unsigned char cam_command[50];
02354 int np;
02355
02356 np=3;
02357
02358 CMUcamStopTracking();
02359
02360 cam_command[0] = TTY3;
02361 cam_command[1] = ARGSTR;
02362 np += sprintf((char*)&cam_command[np], "CR ");
02363
02364 if (imager_config->brightness >= 0)
02365 np += sprintf((char*)&cam_command[np], " 6 %d",
02366 imager_config->brightness);
02367
02368 if (imager_config->contrast >= 0)
02369 np += sprintf((char*)&cam_command[np], " 5 %d",
02370 imager_config->contrast);
02371
02372 if (imager_config->autogain >= 0)
02373 if (imager_config->autogain == 0)
02374 np += sprintf((char*)&cam_command[np], " 19 32");
02375 else
02376 np += sprintf((char*)&cam_command[np], " 19 33");
02377
02378 if (imager_config->colormode >= 0)
02379 if (imager_config->colormode == 3)
02380 np += sprintf((char*)&cam_command[np], " 18 36");
02381 else if (imager_config->colormode == 2)
02382 np += sprintf((char*)&cam_command[np], " 18 32");
02383 else if (imager_config->colormode == 1)
02384 np += sprintf((char*)&cam_command[np], " 18 44");
02385 else
02386 np += sprintf((char*)&cam_command[np], " 18 40");
02387
02388 if (np > 6)
02389 {
02390 sprintf((char*)&cam_command[np], "\r");
02391 cam_command[2] = strlen((char *)&cam_command[3]);
02392 cam_packet.Build(cam_command, (int)cam_command[2]+3);
02393 SendReceive(&cam_packet);
02394
02395 printf("Blobfinder imager parameters updated.\n");
02396 printf(" %s\n", &cam_command[3]);
02397 } else
02398 printf("Blobfinder imager parameters NOT updated.\n");
02399
02400 CMUcamTrack();
02401
02402 this->Publish(this->blobfinder_id, resp_queue,
02403 PLAYER_MSGTYPE_RESP_ACK,
02404 PLAYER_BLOBFINDER_REQ_SET_IMAGER_PARAMS);
02405 return(0);
02406 }
02407 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_ACTARRAY_REQ_POWER,this->actarray_id))
02408 {
02409 ToggleActArrayPower (((player_actarray_power_config_t*) data)->value);
02410 this->Publish(this->actarray_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_POWER);
02411 return 0;
02412 }
02413 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_ACTARRAY_REQ_GET_GEOM,this->actarray_id))
02414 {
02415
02416 P2OSPacket aaPacket;
02417 unsigned char aaCmd = ARM_INFO;
02418 aaPacket.Build (&aaCmd, 1);
02419 SendReceive (&aaPacket);
02420
02421 player_actarray_geom_t aaGeom;
02422 player_actarray_actuatorgeom_t *actuators;
02423
02424 aaGeom.actuators_count = sippacket->armNumJoints;
02425 actuators = new player_actarray_actuatorgeom_t[sippacket->armNumJoints];
02426 if (actuators == NULL)
02427 {
02428 PLAYER_ERROR ("Failed to allocate memory for actuator data");
02429 return -1;
02430 }
02431 aaGeom.actuators = actuators;
02432
02433 for (int ii = 0; ii < sippacket->armNumJoints; ii++)
02434 {
02435 aaGeom.actuators[ii].type = PLAYER_ACTARRAY_TYPE_ROTARY;
02436 aaGeom.actuators[ii].length = aaLengths[ii];
02437 aaGeom.actuators[ii].orientation.proll = aaOrients[ii * 3];
02438 aaGeom.actuators[ii].orientation.ppitch = aaOrients[ii * 3 + 1];
02439 aaGeom.actuators[ii].orientation.pyaw = aaOrients[ii * 3 + 2];
02440 aaGeom.actuators[ii].axis.px = aaAxes[ii * 3];
02441 aaGeom.actuators[ii].axis.py = aaAxes[ii * 3 + 1];
02442 aaGeom.actuators[ii].axis.pz = aaAxes[ii * 3 + 2];
02443 aaGeom.actuators[ii].min = static_cast<float> (TicksToRadians (ii, sippacket->armJoints[ii].min));
02444 aaGeom.actuators[ii].centre = static_cast<float> (TicksToRadians (ii, sippacket->armJoints[ii].centre));
02445 aaGeom.actuators[ii].max = static_cast<float> (TicksToRadians (ii, sippacket->armJoints[ii].max));
02446 aaGeom.actuators[ii].home = static_cast<float> (TicksToRadians (ii, sippacket->armJoints[ii].home));
02447 aaGeom.actuators[ii].config_speed = static_cast<float> (SecsPerTicktoRadsPerSec (ii, sippacket->armJoints[ii].speed));
02448 aaGeom.actuators[ii].hasbrakes = 0;
02449 }
02450
02451 aaGeom.base_pos.px = aaBasePos.px;
02452 aaGeom.base_pos.py = aaBasePos.py;
02453 aaGeom.base_pos.pz = aaBasePos.pz;
02454 aaGeom.base_orientation.proll = aaBaseOrient.proll;
02455 aaGeom.base_orientation.ppitch = aaBaseOrient.ppitch;
02456 aaGeom.base_orientation.pyaw = aaBaseOrient.pyaw;
02457
02458 this->Publish(this->actarray_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_GET_GEOM, &aaGeom, sizeof (aaGeom), NULL);
02459 delete[] actuators;
02460 return 0;
02461 }
02462 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_ACTARRAY_REQ_SPEED,this->actarray_id))
02463 {
02464 joint = ((player_actarray_speed_config_t*) data)->joint + 1;
02465 newSpeed = RadsPerSectoSecsPerTick (joint, ((player_actarray_speed_config_t*) data)->speed);
02466 SetActArrayJointSpeed (joint, newSpeed);
02467
02468 this->Publish(this->actarray_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_SPEED);
02469 return 0;
02470 }
02471 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_LIMB_REQ_POWER,this->limb_id))
02472 {
02473 ToggleActArrayPower (((player_actarray_power_config_t*) data)->value);
02474 this->Publish(this->actarray_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_LIMB_REQ_POWER);
02475 return 0;
02476 }
02477 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_LIMB_REQ_BRAKES,this->limb_id))
02478 {
02479
02480 return 0;
02481 }
02482 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_LIMB_REQ_GEOM,this->limb_id))
02483 {
02484 player_limb_geom_req_t limbGeom;
02485
02486 limbGeom.basePos.px = armOffsetX;
02487 limbGeom.basePos.py = armOffsetY;
02488 limbGeom.basePos.pz = armOffsetZ;
02489
02490 this->Publish(this->limb_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_LIMB_REQ_GEOM, &limbGeom, sizeof (limbGeom), NULL);
02491 return 0;
02492 }
02493 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_LIMB_REQ_SPEED,this->limb_id))
02494 {
02495
02496
02497
02498 float speed = ((player_limb_speed_req_t*) data)->speed;
02499 for (int ii = 1; ii < 6; ii++)
02500 {
02501 newSpeed = RadsPerSectoSecsPerTick (ii, speed);
02502 SetActArrayJointSpeed (ii, newSpeed);
02503 }
02504
02505 this->Publish(this->limb_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_LIMB_REQ_SPEED);
02506 return 0;
02507 }
02508 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_REQ, PLAYER_BUMPER_REQ_GET_GEOM, this->bumper_id))
02509 {
02510
02511 if(hdr->size != 0)
02512 {
02513 PLAYER_WARN("Arg get bumper geom is wrong size; ignoring");
02514 return(-1);
02515 }
02516 player_bumper_geom_t geom;
02517 geom.bumper_def_count = PlayerRobotParams[param_idx].NumFrontBumpers + PlayerRobotParams[param_idx].NumRearBumpers;
02518 geom.bumper_def = new player_bumper_define_t[geom.bumper_def_count];
02519 for(unsigned int ii = 0; ii < geom.bumper_def_count; ii++)
02520 {
02521 bumper_def_t def = PlayerRobotParams[param_idx].bumper_geom[ii];
02522 geom.bumper_def[ii].pose.px = def.x;
02523 geom.bumper_def[ii].pose.py = def.y;
02524 geom.bumper_def[ii].pose.pyaw = DTOR(def.th);
02525 geom.bumper_def[ii].length = def.length;
02526 geom.bumper_def[ii].radius = def.radius;
02527 }
02528
02529 this->Publish(this->bumper_id, resp_queue,
02530 PLAYER_MSGTYPE_RESP_ACK, PLAYER_BUMPER_REQ_GET_GEOM,
02531 (void*)&geom);
02532 delete [] geom.bumper_def;
02533 return(0);
02534 }
02535 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_ACTARRAY_REQ_GET_GEOM,this->lift_id))
02536 {
02537 player_actarray_geom_t aaGeom;
02538 player_actarray_actuatorgeom_t actuator;
02539 aaGeom.actuators = &actuator;
02540
02541 aaGeom.actuators_count = 1;
02542 memset (aaGeom.actuators, 0, sizeof (player_actarray_actuator_t));
02543
02544 aaGeom.actuators[0].type = PLAYER_ACTARRAY_TYPE_LINEAR;
02545 aaGeom.actuators[0].min = 0.0f;
02546 aaGeom.actuators[0].centre = 0.5f;
02547 aaGeom.actuators[0].max = 1.0f;
02548 aaGeom.actuators[0].home = 1.0f;
02549 aaGeom.actuators[0].config_speed = 0.02f;
02550 aaGeom.actuators[0].hasbrakes = 0;
02551
02552 this->Publish(this->lift_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_ACTARRAY_REQ_GET_GEOM, &aaGeom, sizeof (aaGeom), NULL);
02553 return 0;
02554 }
02555 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_GRIPPER_REQ_GET_GEOM,this->gripper_id))
02556 {
02557 player_gripper_geom_t geom;
02558 memset (&geom, 0, sizeof (player_gripper_geom_t));
02559
02560 geom.pose = gripperPose;
02561 geom.outer_size = gripperOuterSize;
02562 geom.inner_size = gripperInnerSize;
02563 geom.num_beams = 2;
02564 geom.capacity = 0;
02565
02566 this->Publish(this->gripper_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_GRIPPER_REQ_GET_GEOM, &geom, sizeof (geom), NULL);
02567 return 0;
02568 }
02569 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_REQ,PLAYER_GRIPPER_REQ_GET_GEOM,this->armgripper_id))
02570 {
02571 player_gripper_geom_t geom;
02572 memset (&geom, 0, sizeof (player_gripper_geom_t));
02573
02574 memset (&(geom.pose), 0, sizeof (player_pose3d_t));
02575 geom.outer_size = armGripperOuterSize;
02576 geom.inner_size = armGripperInnerSize;
02577 geom.num_beams = 0;
02578 geom.capacity = 0;
02579
02580 this->Publish(this->armgripper_id, resp_queue, PLAYER_MSGTYPE_RESP_ACK, PLAYER_GRIPPER_REQ_GET_GEOM, &geom, sizeof (geom), NULL);
02581 return 0;
02582 }
02583 else
02584 {
02585 PLAYER_WARN("unknown config request to p2os driver");
02586 return(-1);
02587 }
02588 }
02589
02590 void P2OS::SendPulse (void)
02591 {
02592 unsigned char command;
02593 P2OSPacket packet;
02594
02595 command = PULSE;
02596 packet.Build(&command, 1);
02597 SendReceive(&packet);
02598 }
02599
02601
02603
02604 void
02605 P2OS::HandlePositionCommand(player_position2d_cmd_vel_t position_cmd)
02606 {
02607 int speedDemand, turnRateDemand;
02608 double leftvel, rightvel;
02609 double rotational_term;
02610 unsigned short absspeedDemand, absturnRateDemand;
02611 unsigned char motorcommand[4];
02612 P2OSPacket motorpacket;
02613
02614 speedDemand = (int)rint(position_cmd.vel.px * 1e3);
02615 turnRateDemand = (int)rint(RTOD(position_cmd.vel.pa));
02616
02617 if(this->direct_wheel_vel_control)
02618 {
02619
02620 rotational_term = (M_PI/180.0) * turnRateDemand /
02621 PlayerRobotParams[param_idx].DiffConvFactor;
02622 leftvel = (speedDemand - rotational_term);
02623 rightvel = (speedDemand + rotational_term);
02624
02625
02626 if(fabs(leftvel) > this->motor_max_speed)
02627 {
02628 if(leftvel > 0)
02629 {
02630 rightvel *= this->motor_max_speed/leftvel;
02631 leftvel = this->motor_max_speed;
02632 puts("Left wheel velocity threshholded!");
02633 }
02634 else
02635 {
02636 rightvel *= -this->motor_max_speed/leftvel;
02637 leftvel = -this->motor_max_speed;
02638 }
02639 }
02640 if(fabs(rightvel) > this->motor_max_speed)
02641 {
02642 if(rightvel > 0)
02643 {
02644 leftvel *= this->motor_max_speed/rightvel;
02645 rightvel = this->motor_max_speed;
02646 puts("Right wheel velocity threshholded!");
02647 }
02648 else
02649 {
02650 leftvel *= -this->motor_max_speed/rightvel;
02651 rightvel = -this->motor_max_speed;
02652 }
02653 }
02654
02655
02656 if(this->use_vel_band)
02657 {
02658
02659
02660 if (leftvel * rightvel < 0)
02661 {
02662 if (leftvel + rightvel >= 0)
02663 {
02664 if (leftvel < 0)
02665 leftvel = 0;
02666 if (rightvel < 0)
02667 rightvel = 0;
02668 }
02669 else
02670 {
02671 if (leftvel > 0)
02672 leftvel = 0;
02673 if (rightvel > 0)
02674 rightvel = 0;
02675 }
02676 }
02677 }
02678
02679
02680 if (leftvel / PlayerRobotParams[param_idx].Vel2Divisor > 126)
02681 leftvel = 126 * PlayerRobotParams[param_idx].Vel2Divisor;
02682 if (leftvel / PlayerRobotParams[param_idx].Vel2Divisor < -126)
02683 leftvel = -126 * PlayerRobotParams[param_idx].Vel2Divisor;
02684 if (rightvel / PlayerRobotParams[param_idx].Vel2Divisor > 126)
02685 rightvel = 126 * PlayerRobotParams[param_idx].Vel2Divisor;
02686 if (rightvel / PlayerRobotParams[param_idx].Vel2Divisor < -126)
02687 rightvel = -126 * PlayerRobotParams[param_idx].Vel2Divisor;
02688
02689
02690 motorcommand[0] = VEL2;
02691 motorcommand[1] = ARGINT;
02692 motorcommand[2] = (char)(rightvel /
02693 PlayerRobotParams[param_idx].Vel2Divisor);
02694 motorcommand[3] = (char)(leftvel /
02695 PlayerRobotParams[param_idx].Vel2Divisor);
02696
02697 motorpacket.Build(motorcommand, 4);
02698 this->SendReceive(&motorpacket);
02699 }
02700 else
02701 {
02702
02703
02704 motorcommand[0] = VEL;
02705 if(speedDemand >= 0)
02706 motorcommand[1] = ARGINT;
02707 else
02708 motorcommand[1] = ARGNINT;
02709
02710 absspeedDemand = (unsigned short)abs(speedDemand);
02711 if(absspeedDemand < this->motor_max_speed)
02712 {
02713 motorcommand[2] = absspeedDemand & 0x00FF;
02714 motorcommand[3] = (absspeedDemand & 0xFF00) >> 8;
02715 }
02716 else
02717 {
02718 puts("Speed demand threshholded!");
02719 motorcommand[2] = this->motor_max_speed & 0x00FF;
02720 motorcommand[3] = (this->motor_max_speed & 0xFF00) >> 8;
02721 }
02722 motorpacket.Build(motorcommand, 4);
02723 this->SendReceive(&motorpacket);
02724
02725 motorcommand[0] = RVEL;
02726 if(turnRateDemand >= 0)
02727 motorcommand[1] = ARGINT;
02728 else
02729 motorcommand[1] = ARGNINT;
02730
02731 absturnRateDemand = (unsigned short)abs(turnRateDemand);
02732 if(absturnRateDemand < this->motor_max_turnspeed)
02733 {
02734 motorcommand[2] = absturnRateDemand & 0x00FF;
02735 motorcommand[3] = (absturnRateDemand & 0xFF00) >> 8;
02736 }
02737 else
02738 {
02739 puts("Turn rate demand threshholded!");
02740 motorcommand[2] = this->motor_max_turnspeed & 0x00FF;
02741 motorcommand[3] = (this->motor_max_turnspeed & 0xFF00) >> 8;
02742 }
02743
02744 motorpacket.Build(motorcommand, 4);
02745 this->SendReceive(&motorpacket);
02746
02747 }
02748 }
02749
02750 void
02751 P2OS::HandleAudioCommand(player_audio_sample_item_t audio_cmd)
02752 {
02753 unsigned char soundcommand[4];
02754 P2OSPacket soundpacket;
02755 unsigned short soundindex;
02756
02757 soundindex = audio_cmd.index;
02758
02759 if(!this->sent_audio_cmd || (soundindex != this->last_audio_cmd.index))
02760 {
02761 soundcommand[0] = SOUND;
02762 soundcommand[1] = ARGINT;
02763 soundcommand[2] = soundindex & 0x00FF;
02764 soundcommand[3] = (soundindex & 0xFF00) >> 8;
02765 soundpacket.Build(soundcommand,4);
02766 SendReceive(&soundpacket);
02767 fflush(stdout);
02768
02769 this->last_audio_cmd.index = soundindex;
02770 }
02771 }
02772
02774
02775
02776 void P2OS::HandleActArrayPosCmd (player_actarray_position_cmd_t cmd)
02777 {
02778 unsigned char command[4];
02779 P2OSPacket packet;
02780
02781 if (!(lastActArrayCmd == PLAYER_ACTARRAY_CMD_POS) || ((lastActArrayCmd == PLAYER_ACTARRAY_CMD_POS) &&
02782 (cmd.joint != lastActArrayPosCmd.joint || cmd.position != lastActArrayPosCmd.position)))
02783 {
02784 command[0] = ARM_POS;
02785 command[1] = ARGINT;
02786 command[2] = RadiansToTicks (cmd.joint, cmd.position);
02787 command[3] = static_cast<unsigned char> (cmd.joint) + 1;
02788 packet.Build(command, 4);
02789 SendReceive(&packet);
02790 sippacket->armJointTargetPos[static_cast<unsigned char> (cmd.joint)] = command[2];
02791 }
02792 }
02793
02794 void P2OS::HandleActArrayHomeCmd (player_actarray_home_cmd_t cmd)
02795 {
02796 unsigned char command[4];
02797 P2OSPacket packet;
02798
02799 if ((lastActArrayCmd == PLAYER_ACTARRAY_CMD_POS) || (!(lastActArrayCmd == PLAYER_ACTARRAY_CMD_POS) &&
02800 (cmd.joint != lastActArrayHomeCmd.joint)))
02801 {
02802 command[0] = ARM_HOME;
02803 command[1] = ARGINT;
02804 command[2] = (cmd.joint == -1) ? 7 : (static_cast<unsigned char> (cmd.joint) + 1);
02805 command[3] = 0;
02806 packet.Build(command, 4);
02807 SendReceive(&packet);
02808 }
02809 }
02810
02811 int P2OS::HandleActArrayCommand (player_msghdr * hdr, void * data)
02812 {
02813 if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_POS, this->actarray_id))
02814 {
02815 player_actarray_position_cmd_t cmd;
02816 cmd = *(player_actarray_position_cmd_t*) data;
02817 this->HandleActArrayPosCmd (cmd);
02818 lastActArrayCmd = PLAYER_ACTARRAY_CMD_POS;
02819 return 0;
02820 }
02821 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_HOME, this->actarray_id))
02822 {
02823 player_actarray_home_cmd_t cmd;
02824 cmd = *(player_actarray_home_cmd_t*) data;
02825 this->HandleActArrayHomeCmd (cmd);
02826 lastActArrayCmd = PLAYER_ACTARRAY_CMD_HOME;
02827 return 0;
02828 }
02829 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_ACTARRAY_CMD_MULTI_POS, this->actarray_id))
02830 {
02831 player_actarray_multi_position_cmd_t cmd = *(player_actarray_multi_position_cmd_t*) data;
02832 player_actarray_position_cmd_t singleCmd;
02833 for (unsigned int ii = 0; ii < cmd.positions_count && ii < 6; ii++)
02834 {
02835 singleCmd.joint = ii;
02836 singleCmd.position = cmd.positions[ii];
02837 this->HandleActArrayPosCmd (singleCmd);
02838 }
02839 lastActArrayCmd = PLAYER_ACTARRAY_CMD_MULTI_POS;
02840 }
02841
02842 return -1;
02843 }
02844
02846
02847
02848 void P2OS::HandleLimbHomeCmd (void)
02849 {
02850 unsigned char command[4];
02851 P2OSPacket packet;
02852
02853 command[0] = ARM_HOME;
02854 command[1] = ARGINT;
02855 command[2] = 7;
02856 command[3] = 0;
02857 packet.Build(command, 4);
02858 SendReceive(&packet);
02859 }
02860
02861 void P2OS::HandleLimbStopCmd (void)
02862 {
02863 unsigned char command[4];
02864 P2OSPacket packet;
02865
02866 command[0] = ARM_STOP;
02867 command[1] = ARGINT;
02868
02869 for (int ii = 1; ii < 5; ii++)
02870 {
02871 command[2] = ii;
02872 command[3] = 0;
02873 packet.Build (command, 4);
02874 SendReceive (&packet);
02875 }
02876 }
02877
02878 void P2OS::HandleLimbSetPoseCmd (player_limb_setpose_cmd_t cmd)
02879 {
02880 unsigned char command[4];
02881 P2OSPacket packet;
02882 EndEffector pose;
02883
02884
02885
02886 pose.p.x = cmd.position.px - armOffsetX;
02887 pose.p.y = cmd.position.py - armOffsetY;
02888 pose.p.z = cmd.position.pz - armOffsetZ;
02889 pose.a.x = cmd.approach.px; pose.a.y = cmd.approach.py; pose.a.z = cmd.approach.pz;
02890 pose.o.x = cmd.orientation.px; pose.o.y = cmd.orientation.py; pose.o.z = cmd.orientation.pz;
02891 pose.a = kineCalc->Normalise (pose.a);
02892 pose.o = kineCalc->Normalise (pose.o);
02893 pose.n = kineCalc->CalculateN (pose);
02894
02895
02896
02897
02898
02899
02900 if (!kineCalc->CalculateIK (pose))
02901 {
02902 limb_data.state = PLAYER_LIMB_STATE_OOR;
02903 return;
02904 }
02905
02906 command[0] = ARM_POS;
02907 command[1] = ARGINT;
02908
02909 for (int ii = 0; ii < 5; ii++)
02910 {
02911 command[2] = RadiansToTicks (ii, kineCalc->GetTheta (ii));
02912 command[3] = ii + 1;
02913 packet.Build (command, 4);
02914 SendReceive (&packet);
02915
02916 }
02917
02918 limb_data.state = PLAYER_LIMB_STATE_MOVING;
02919 }
02920
02921
02922 void P2OS::HandleLimbSetPositionCmd (player_limb_setposition_cmd_t cmd)
02923 {
02924 EndEffector pose;
02925 unsigned char command[4];
02926 P2OSPacket packet;
02927
02928 pose.p.x = cmd.position.px - armOffsetX;
02929 pose.p.y = -(cmd.position.py - armOffsetY);
02930 pose.p.z = cmd.position.pz - armOffsetZ;
02931
02932
02933
02934 pose.o = kineCalc->GetO ();
02935 pose.a = kineCalc->GetA ();
02936 pose.n = kineCalc->GetN ();
02937
02938 if (!kineCalc->CalculateIK (pose))
02939 {
02940 limb_data.state = PLAYER_LIMB_STATE_OOR;
02941 return;
02942 }
02943
02944 command[0] = ARM_POS;
02945 command[1] = ARGINT;
02946
02947 for (int ii = 0; ii < 5; ii++)
02948 {
02949 command[2] = RadiansToTicks (ii, kineCalc->GetTheta (ii));
02950 command[3] = ii + 1;
02951 packet.Build (command, 4);
02952 SendReceive (&packet);
02953 }
02954
02955 limb_data.state = PLAYER_LIMB_STATE_MOVING;
02956 }
02957
02958
02959 void P2OS::HandleLimbVecMoveCmd (player_limb_vecmove_cmd_t cmd)
02960 {
02961 EndEffector pose;
02962 unsigned char command[4];
02963 P2OSPacket packet;
02964
02965
02966
02967
02968
02969
02970
02971
02972
02973
02974
02975
02976 pose.p = kineCalc->GetP ();
02977 pose.o = kineCalc->GetO ();
02978 pose.a = kineCalc->GetA ();
02979 pose.n = kineCalc->GetN ();
02980
02981 KineVector offset;
02982 offset.x = cmd.direction.px; offset.y = -cmd.direction.py; offset.z = cmd.direction.pz;
02983 offset = kineCalc->Normalise (offset);
02984 offset.x *= cmd.length;
02985 offset.y *= cmd.length;
02986 offset.z *= cmd.length;
02987
02988 pose.p.x += offset.x;
02989 pose.p.y += offset.y;
02990 pose.p.z += offset.z;
02991
02992 if (!kineCalc->CalculateIK (pose))
02993 {
02994 limb_data.state = PLAYER_LIMB_STATE_OOR;
02995 return;
02996 }
02997
02998 command[0] = ARM_POS;
02999 command[1] = ARGINT;
03000
03001 for (int ii = 0; ii < 5; ii++)
03002 {
03003 command[2] = RadiansToTicks (ii, kineCalc->GetTheta (ii));
03004 command[3] = ii + 1;
03005 packet.Build (command, 4);
03006 SendReceive (&packet);
03007 }
03008
03009 limb_data.state = PLAYER_LIMB_STATE_MOVING;
03010 }
03011
03012 int P2OS::HandleLimbCommand (player_msghdr *hdr, void *data)
03013 {
03014 if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_CMD,PLAYER_LIMB_CMD_HOME,this->limb_id))
03015 {
03016 this->HandleLimbHomeCmd ();
03017 return 0;
03018 }
03019 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_CMD,PLAYER_LIMB_CMD_STOP,this->limb_id))
03020 {
03021 this->HandleLimbStopCmd ();
03022 return 0;
03023 }
03024 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_CMD,PLAYER_LIMB_CMD_SETPOSE,this->limb_id))
03025 {
03026 player_limb_setpose_cmd_t cmd;
03027 cmd = *(player_limb_setpose_cmd_t*) data;
03028 this->HandleLimbSetPoseCmd (cmd);
03029 return 0;
03030 }
03031 return -1;
03032 }
03033
03035
03036
03037 int P2OS::HandleLiftCommand (player_msghdr *hdr, void *data)
03038 {
03039 unsigned char command[4];
03040 P2OSPacket packet;
03041
03042 if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_CMD,PLAYER_ACTARRAY_CMD_POS,this->lift_id))
03043 {
03044 player_actarray_position_cmd_t cmd;
03045 cmd = *(player_actarray_position_cmd_t*) data;
03046
03047
03048 if (cmd.joint > 0)
03049 return -1;
03050
03051 if (lastLiftCmd == PLAYER_ACTARRAY_CMD_POS && lastLiftPosCmd.position == cmd.position)
03052 return 0;
03053
03054 command[0] = GRIPPER;
03055 command[1] = ARGINT;
03056
03057
03058 if (cmd.position <= 0.0)
03059 {
03060 command[2] = LIFTdown;
03061 command[3] = 0;
03062 packet.Build (command, 4);
03063 SendReceive (&packet);
03064 }
03065 else if (cmd.position >= 1.0)
03066 {
03067 command[3] = LIFTup;
03068 command[3] = 0;
03069 packet.Build (command, 4);
03070 SendReceive (&packet);
03071 }
03072 else
03073 {
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084
03085
03086
03087
03088 double offset = cmd.position - lastLiftPosCmd.position;
03089 double travelTime = offset * 3.5f;
03090 short liftCarryVal = static_cast<short> (travelTime / 0.02f);
03091
03092
03093 command[2] = LIFTcarry;
03094 command[3] = 0;
03095 packet.Build (command, 4);
03096 SendReceive (&packet);
03097
03098
03099 command[0] = GRIPPERVAL;
03100 command[2] = liftCarryVal & 0x00FF;
03101 command[3] = (liftCarryVal & 0xFF00) >> 8;
03102 packet.Build (command, 4);
03103 SendReceive (&packet);
03104 }
03105
03106 lastLiftCmd = PLAYER_ACTARRAY_CMD_POS;
03107 lastLiftPosCmd = cmd;
03108 sippacket->lastLiftPos = cmd.position;
03109 return 0;
03110 }
03111 else if(Message::MatchMessage(hdr,PLAYER_MSGTYPE_CMD,PLAYER_ACTARRAY_CMD_HOME,this->lift_id))
03112 {
03113 if (lastLiftCmd == PLAYER_ACTARRAY_CMD_HOME)
03114 return 0;
03115
03116
03117 command[0] = GRIPPER;
03118 command[1] = ARGINT;
03119 command[2] = LIFTup;
03120 command[3] = 0;
03121 packet.Build (command, 4);
03122 SendReceive (&packet);
03123 lastLiftCmd = PLAYER_ACTARRAY_CMD_HOME;
03124 lastLiftPosCmd.position = 1.0f;
03125 return 0;
03126 }
03127 return -1;
03128 }
03129
03131
03132
03133 void P2OS::OpenGripper (void)
03134 {
03135 unsigned char cmd[4];
03136 P2OSPacket packet;
03137
03138
03139
03140
03141
03142
03143 cmd[0] = GRIPPER;
03144 cmd[1] = ARGINT;
03145 cmd[2] = GRIPopen;
03146 cmd[3] = 0;
03147 packet.Build (cmd, 4);
03148 SendReceive (&packet);
03149
03150 sentGripperCmd = true;
03151 lastGripperCmd = PLAYER_GRIPPER_CMD_OPEN;
03152 }
03153
03154 void P2OS::CloseGripper (void)
03155 {
03156 unsigned char cmd[4];
03157 P2OSPacket packet;
03158
03159
03160
03161
03162
03163
03164 cmd[0] = GRIPPER;
03165 cmd[1] = ARGINT;
03166 cmd[2] = GRIPclose;
03167 cmd[3] = 0;
03168 packet.Build (cmd, 4);
03169 SendReceive (&packet);
03170
03171 sentGripperCmd = true;
03172 lastGripperCmd = PLAYER_GRIPPER_CMD_CLOSE;
03173 }
03174
03175 void P2OS::StopGripper (void)
03176 {
03177 unsigned char cmd[4];
03178 P2OSPacket packet;
03179
03180 if (sentGripperCmd && lastGripperCmd == PLAYER_GRIPPER_CMD_STOP)
03181 return;
03182
03183 cmd[0] = GRIPPER;
03184 cmd[1] = ARGINT;
03185 cmd[2] = GRIPstop;
03186 cmd[3] = 0;
03187 packet.Build (cmd, 4);
03188 SendReceive (&packet);
03189
03190 sentGripperCmd = true;
03191 lastGripperCmd = PLAYER_GRIPPER_CMD_STOP;
03192 }
03193
03194 int P2OS::HandleGripperCommand (player_msghdr * hdr, void * data)
03195 {
03196 if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_OPEN, this->gripper_id))
03197 {
03198 OpenGripper ();
03199 return 0;
03200 }
03201 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_CLOSE, this->gripper_id))
03202 {
03203 CloseGripper ();
03204 return 0;
03205 }
03206 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_STOP, this->gripper_id))
03207 {
03208 StopGripper ();
03209 return 0;
03210 }
03211 return -1;
03212 }
03213
03215
03216
03217 void P2OS::OpenArmGripper (void)
03218 {
03219 unsigned char command[4];
03220 P2OSPacket packet;
03221
03222 if (sentArmGripperCmd && lastArmGripperCmd == PLAYER_GRIPPER_CMD_OPEN)
03223 return;
03224
03225 command[0] = ARM_POS;
03226 command[1] = ARGINT;
03227 command[2] = sippacket->armJoints[5].max;
03228 command[3] = 6;
03229 packet.Build(command, 4);
03230 SendReceive(&packet);
03231
03232 sippacket->armJointTargetPos[5] = command[2];
03233 sentArmGripperCmd = true;
03234 lastArmGripperCmd = PLAYER_GRIPPER_CMD_OPEN;
03235 }
03236
03237 void P2OS::CloseArmGripper (void)
03238 {
03239 unsigned char command[4];
03240 P2OSPacket packet;
03241
03242 if (sentArmGripperCmd && lastArmGripperCmd == PLAYER_GRIPPER_CMD_CLOSE)
03243 return;
03244
03245 command[0] = ARM_POS;
03246 command[1] = ARGINT;
03247 command[2] = sippacket->armJoints[5].min;
03248 command[3] = 6;
03249 packet.Build(command, 4);
03250 SendReceive(&packet);
03251
03252 sippacket->armJointTargetPos[5] = command[2];
03253 sentArmGripperCmd = true;
03254 lastArmGripperCmd = PLAYER_GRIPPER_CMD_CLOSE;
03255 }
03256
03257 void P2OS::StopArmGripper (void)
03258 {
03259 unsigned char command[4];
03260 P2OSPacket packet;
03261
03262 if (sentArmGripperCmd && lastArmGripperCmd == PLAYER_GRIPPER_CMD_STOP)
03263 return;
03264
03265 command[0] = ARM_STOP;
03266 command[1] = ARGINT;
03267 command[2] = 6;
03268 command[3] = 0;
03269 packet.Build(command, 4);
03270 SendReceive(&packet);
03271
03272 sentArmGripperCmd = true;
03273 lastArmGripperCmd = PLAYER_GRIPPER_CMD_STOP;
03274 }
03275
03276 int P2OS::HandleArmGripperCommand (player_msghdr *hdr, void *data)
03277 {
03278 if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_OPEN, this->armgripper_id))
03279 {
03280 OpenArmGripper ();
03281 return 0;
03282 }
03283 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_CLOSE, this->armgripper_id))
03284 {
03285 CloseArmGripper ();
03286 return 0;
03287 }
03288 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRIPPER_CMD_STOP, this->armgripper_id))
03289 {
03290 StopArmGripper ();
03291 return 0;
03292 }
03293 return -1;
03294 }
03295
03297
03298 int
03299 P2OS::HandleCommand(player_msghdr * hdr, void* data)
03300 {
03301 int retVal = -1;
03302 struct timeval timeVal;
03303
03304 if(Message::MatchMessage(hdr,
03305 PLAYER_MSGTYPE_CMD,
03306 PLAYER_POSITION2D_CMD_VEL,
03307 this->position_id))
03308 {
03309
03310 player_position2d_cmd_vel_t position_cmd;
03311 position_cmd = *(player_position2d_cmd_vel_t*)data;
03312 this->HandlePositionCommand(position_cmd);
03313 retVal = 0;
03314 }
03315 else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD, PLAYER_AUDIO_CMD_SAMPLE_PLAY, this->audio_id))
03316 {
03317
03318 player_audio_sample_item_t audio_cmd;
03319 audio_cmd = *(player_audio_sample_item_t*)data;
03320 this->HandleAudioCommand(audio_cmd);
03321 retVal = 0;
03322 }
03323 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, -1, actarray_id))
03324 {
03325 retVal = HandleActArrayCommand (hdr, data);
03326 }
03327 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, -1, limb_id))
03328 {
03329 retVal = HandleLimbCommand (hdr, data);
03330 }
03331 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, -1, lift_id))
03332 {
03333 retVal = HandleLiftCommand (hdr, data);
03334 }
03335 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, -1, gripper_id))
03336 {
03337 retVal = HandleGripperCommand (hdr, data);
03338 }
03339 else if(Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD, -1, gripper_id))
03340 {
03341 retVal = HandleGripperCommand(hdr, data);
03342 }
03343 else if (Message::MatchMessage (hdr, PLAYER_MSGTYPE_CMD, -1, armgripper_id))
03344 {
03345 retVal = HandleArmGripperCommand (hdr, data);
03346 }
03347
03348
03349 if (retVal == 0 && pulse != -1)
03350 {
03351 gettimeofday (&timeVal, NULL);
03352 lastPulseTime = static_cast<double> (timeVal.tv_sec) + (static_cast<double> (timeVal.tv_usec) / 1e6);
03353 }
03354 return retVal;
03355 }