00001 #include <RFlex.H>
00002 #include <cassert>
00003 #include <cstring>
00004 #include <cmath>
00005 #include <iostream>
00006 #include <unistd.h>
00007 #include <sys/select.h>
00008 #include <netinet/in.h>
00009
00010 #include <wds-debug.h>
00011
00012
00013
00014 static const double B21_MAGIC_DISTANCE = 101230.0;
00015 static const double B21_MAGIC_ANGLE = 35343.888;
00016 static const double B21_MAGIC_TORQUE = 35000.0;
00017
00018 static const double ATRVJR_MAGIC_DISTANCE = 90810.0;
00019 static const double ATRVJR_MAGIC_ANGLE = 37000.0;
00020 static const double ATRVJR_MAGIC_TORQUE = 35000.0;
00021
00022
00023 static const int PROTOCOL_SIZE = 9;
00024 static const int PACKET_CRC_START = 2;
00025 static const int PACKET_CRC_OFFSET = 4;
00026
00027
00028 static const unsigned char NUL = 0;
00029 static const unsigned char SOH = 1;
00030 static const unsigned char STX = 2;
00031 static const unsigned char ETX = 3;
00032 static const unsigned char ESC = 27;
00033
00034
00035 static const unsigned int SYSTEM_PORT = 1;
00036 static const unsigned int MOTOR_PORT = 2;
00037 static const unsigned int JOYSTICK_PORT = 3;
00038 static const unsigned int SONAR_PORT = 4;
00039 static const unsigned int DIGITAL_IO_PORT = 5;
00040 static const unsigned int IR_PORT = 6;
00041
00042
00043 static const int PACKET_PORT_BYTE = 2;
00044 static const int PACKET_ID_BYTE = 3;
00045 static const int PACKET_OPCODE_BYTE = 4;
00046 static const int PACKET_SIZE_BYTE = 5;
00047 static const int PACKET_DATA_START_BYTE = 6;
00048
00049
00050
00051 static const int SYSTEM_LCD_DUMP = 0;
00052 static const int SYSTEM_STATUS = 1;
00053
00054 static const int MOTOR_AXIS_GET_SYSTEM = 0;
00055 static const int MOTOR_AXIS_GET_MODEL = 1;
00056 static const int MOTOR_AXIS_GET_TARGET = 2;
00057 static const int MOTOR_AXIS_SET_LIMITS = 3;
00058 static const int MOTOR_AXIS_GET_LIMITS = 4;
00059 static const int MOTOR_AXIS_SET_POS_LIMITS = 5;
00060 static const int MOTOR_AXIS_GET_POS_LIMITS = 6;
00061 static const int MOTOR_AXIS_SET_DIR = 7;
00062 static const int MOTOR_AXIS_SET_POS = 8;
00063 static const int MOTOR_AXIS_GET_MODE = 9;
00064 static const int MOTOR_SET_DEFAULTS = 10;
00065 static const int MOTOR_BRAKE_SET = 11;
00066 static const int MOTOR_BRAKE_RELEASE = 12;
00067 static const int MOTOR_SYSTEM_REPORT = 33;
00068 static const int MOTOR_SYSTEM_REPORT_REQUEST = 34;
00069 static const int MOTOR_GET_NAXES = 65;
00070 static const int MOTOR_SET_GEARING = 66;
00071 static const int MOTOR_GET_GEARING = 67;
00072 static const int MOTOR_MOTOR_SET_MODE = 68;
00073 static const int MOTOR_MOTOR_GET_MODE = 69;
00074 static const int MOTOR_MOTOR_SET_PARMS = 70;
00075 static const int MOTOR_MOTOR_GET_PARMS = 71;
00076 static const int MOTOR_MOTOR_SET_LIMITS = 72;
00077 static const int MOTOR_MOTOR_GET_LIMITS = 73;
00078 static const int MOTOR_MOTOR_GET_DATA = 74;
00079 static const int MOTOR_AXIS_SET_PARMS = 75;
00080 static const int MOTOR_AXIS_GET_PARMS = 76;
00081 static const int MOTOR_AXIS_SET_PWM_LIMIT = 77;
00082 static const int MOTOR_AXIS_GET_PWM_LIMIT = 78;
00083 static const int MOTOR_AXIS_SET_PWM = 79;
00084 static const int MOTOR_AXIS_GET_PWM = 80;
00085
00086 static const int JOYSTICK_GET_STATE = 0;
00087
00088 static const int SONAR_RUN = 0;
00089 static const int SONAR_GET_UPDATE = 1;
00090 static const int SONAR_REPORT = 2;
00091
00092 static const unsigned char SONAR_OFF = 0;
00093 static const unsigned char SONAR_REPORT_ON_REQUEST = 1;
00094 static const unsigned char SONAR_CONTINUOUS_REPORT = 2;
00095
00096 static const int DIGITAL_IO_REPORT_REQUEST = 0;
00097 static const int DIGITAL_IO_REPORT = 1;
00098 static const int DIGITAL_IO_GET_UPDATE = 2;
00099 static const int DIGITAL_IO_UPDATE = 3;
00100 static const int DIGITAL_IO_SET = 4;
00101
00102 static const int IR_RUN = 0;
00103 static const int IR_REPORT = 1;
00104
00105
00106 using namespace std;
00107
00108
00109
00110
00111
00112 RFlex::RFlex(const std::string &filename, const std::string &robotType) :m_port(filename, 115200), m_found(false), m_offset(0), m_translate_command(0.0), m_rotate_command(0.0) {
00113
00114 m_x = 0.0;
00115 m_y = 0.0;
00116 m_theta = 0;
00117 m_last_distance = 0;
00118 m_last_angdistance = 0;
00119 m_last_distance_set =false;
00120 m_last_angdistance_set = false;
00121 m_trans_velocity = 0.0;
00122 m_rot_velocity = 0.0;
00123
00124 bzero(m_sonars,MAX_SONAR*sizeof(double));
00125 if(robotType=="B21r"){
00126 m_type=RFLEX_B21R;
00127 m_magicDistance=B21_MAGIC_DISTANCE;
00128 m_magicAngle=B21_MAGIC_ANGLE;
00129 m_magicTorque=B21_MAGIC_TORQUE;
00130 m_numSonar=0;
00131 }else if(robotType=="ATRVJr"){
00132 m_type=RFLEX_ATRVJR;
00133 m_magicDistance=ATRVJR_MAGIC_DISTANCE;
00134 m_magicAngle=ATRVJR_MAGIC_ANGLE;
00135 m_magicTorque=ATRVJR_MAGIC_TORQUE;
00136 m_numSonar=17;
00137 }else{
00138 cerr << "Unknown robot type!" << endl;
00139 exit(1);
00140 }
00141
00142
00143 pthread_mutex_init(&m_write_mutex, NULL);
00144 pthread_mutex_init(&m_motor_mutex, NULL);
00145 pthread_mutex_init(&m_command_mutex, NULL);
00146
00147
00148 pthread_create(&m_read_thread, NULL, RFlex::rFlexReadThread, this);
00149 pthread_create(&m_periodic_thread, NULL, RFlex::rFlexPeriodicThread, this);
00150
00151
00152 systemUpdate();
00153 odometryOn();
00154 }
00155
00156
00157
00158 RFlex::~RFlex() {
00159
00160 motorSetTranslateVelocity(0.0);
00161 motorSetRotateVelocity(0.0);
00162 odometryOff();
00163 digitalIOOff();
00164 sonarOff();
00165
00166
00167 pthread_mutex_destroy(&m_write_mutex);
00168 pthread_mutex_destroy(&m_motor_mutex);
00169
00170
00171 }
00172
00173
00174 bool RFlex::systemUpdate() {
00175 pthread_mutex_lock(&m_write_mutex);
00176 const bool retval = sendCommand(SYSTEM_PORT, 0, SYSTEM_STATUS, 0);
00177 pthread_mutex_unlock(&m_write_mutex);
00178
00179 return retval;
00180 }
00181
00182
00183 #warning Need to check this
00184 bool RFlex::systemLCDDump() {
00185 pthread_mutex_lock(&m_write_mutex);
00186 const bool retval = sendCommand(SYSTEM_PORT, 0, SYSTEM_LCD_DUMP, 5);
00187 pthread_mutex_unlock(&m_write_mutex);
00188
00189 return retval;
00190 }
00191
00192
00193 bool RFlex::motionSetDefaults() {
00194 pthread_mutex_lock(&m_write_mutex);
00195 pthread_mutex_unlock(&m_write_mutex);
00196
00197 #warning Need to implement this
00198 return false;
00199 }
00200
00201
00202 #warning No effect
00203 bool RFlex::setBrake() {
00204 pthread_mutex_lock(&m_write_mutex);
00205 const bool retval = sendCommand(MOTOR_PORT, 0, MOTOR_BRAKE_SET, 0);
00206 pthread_mutex_unlock(&m_write_mutex);
00207
00208 return retval;
00209 }
00210
00211
00212 #warning No effect
00213 bool RFlex::releaseBrake() {
00214 pthread_mutex_lock(&m_write_mutex);
00215 const bool retval = sendCommand(MOTOR_PORT, 0, MOTOR_BRAKE_RELEASE, 0);
00216 pthread_mutex_unlock(&m_write_mutex);
00217
00218 return retval;
00219 }
00220
00221
00222 void RFlex::motorSetTranslateVelocity(const double velocity) {
00223 pthread_mutex_lock(&m_command_mutex);
00224 m_translate_command = velocity;
00225 pthread_mutex_unlock(&m_command_mutex);
00226 }
00227
00228
00229 void RFlex::motorSetRotateVelocity(const double velocity) {
00230 pthread_mutex_lock(&m_command_mutex);
00231 m_rotate_command = velocity;
00232 pthread_mutex_unlock(&m_command_mutex);
00233 }
00234
00235
00236 void RFlex::motorSetVelocity(const double translate, const double rotate) {
00237 pthread_mutex_lock(&m_command_mutex);
00238 m_translate_command = translate;
00239 m_rotate_command = rotate;
00240 pthread_mutex_unlock(&m_command_mutex);
00241 }
00242
00243
00244 bool RFlex::odometryOn(const int period) {
00245 pthread_mutex_lock(&m_write_mutex);
00246 insertLong(period, 0);
00247 insertLong(3, 4);
00248
00249 const bool retval = sendCommand(MOTOR_PORT, 0, MOTOR_SYSTEM_REPORT_REQUEST, 8);
00250 pthread_mutex_unlock(&m_write_mutex);
00251
00252 return retval;
00253 }
00254
00255
00256 bool RFlex::odometryOff() {
00257 pthread_mutex_lock(&m_write_mutex);
00258 insertLong(0, 0);
00259 insertLong(3, 4);
00260
00261 const bool retval = sendCommand(MOTOR_PORT, 0, MOTOR_SYSTEM_REPORT_REQUEST, 8);
00262 pthread_mutex_unlock(&m_write_mutex);
00263
00264 return retval;
00265 }
00266
00267
00268 bool RFlex::digitalIOOn(const int period) {
00269 pthread_mutex_lock(&m_write_mutex);
00270 insertLong(period, 0);
00271
00272 const bool retval = sendCommand(DIGITAL_IO_PORT, 0, DIGITAL_IO_REPORT_REQUEST, 4);
00273 pthread_mutex_unlock(&m_write_mutex);
00274
00275 return retval;
00276 }
00277
00278
00279 bool RFlex::digitalIOOff() {
00280 pthread_mutex_lock(&m_write_mutex);
00281 insertLong(0, 0);
00282
00283 const bool retval = sendCommand(DIGITAL_IO_PORT, 0, DIGITAL_IO_REPORT_REQUEST, 4);
00284 pthread_mutex_unlock(&m_write_mutex);
00285
00286 return retval;
00287 }
00288
00289
00290 bool RFlex::joystickReport() {
00291 pthread_mutex_lock(&m_write_mutex);
00292 const bool retval = sendCommand(JOYSTICK_PORT, 0, JOYSTICK_GET_STATE, 0);
00293 pthread_mutex_unlock(&m_write_mutex);
00294
00295 return retval;
00296 }
00297
00298
00299 bool RFlex::sonarOn() {
00300 pthread_mutex_lock(&m_write_mutex);
00301 insertLong(30000, 0);
00302 insertLong(0, 4);
00303 insertLong(0, 8);
00304 insertChar(SONAR_CONTINUOUS_REPORT, 12);
00305
00306 const bool retval = sendCommand(SONAR_PORT, 4, SONAR_RUN, 13);
00307 pthread_mutex_unlock(&m_write_mutex);
00308
00309 return retval;
00310 }
00311
00312
00313 bool RFlex::sonarOff() {
00314 pthread_mutex_lock(&m_write_mutex);
00315
00316 memset(m_write_buffer + PACKET_DATA_START_BYTE, 0, 13);
00317
00318 const bool retval = sendCommand(SONAR_PORT, 4, SONAR_RUN, 13);
00319 pthread_mutex_unlock(&m_write_mutex);
00320
00321 return retval;
00322 }
00323
00324
00325 bool RFlex::motorSendTranslateVelocity(const double velocity) {
00326 const unsigned long vel =static_cast<unsigned long>(fabs(velocity) * m_magicDistance);
00327 const unsigned long acceleration = static_cast<unsigned long>(1.0 * m_magicDistance);
00328 const unsigned long torque = static_cast<unsigned long>(1.0 * m_magicTorque);
00329
00330 pthread_mutex_lock(&m_write_mutex);
00331 insertChar(0, 0);
00332 insertLong(vel, 1);
00333 insertLong(acceleration, 5);
00334 insertLong(torque, 9);
00335 insertChar((velocity < 0)?(0):(1), 13);
00336
00337 const bool retval = sendCommand(MOTOR_PORT, 0, MOTOR_AXIS_SET_DIR, 14);
00338 pthread_mutex_unlock(&m_write_mutex);
00339
00340 return retval;
00341 }
00342
00343
00344 bool RFlex::motorSendRotateVelocity(const double velocity) {
00345 const unsigned long vel =static_cast<unsigned long>(fabs(velocity) * m_magicAngle);
00346 const unsigned long acceleration = static_cast<unsigned long>(1.0 * m_magicDistance);
00347 const unsigned long torque = static_cast<unsigned long>(1.0 * m_magicTorque);
00348
00349 pthread_mutex_lock(&m_write_mutex);
00350 insertChar(1, 0);
00351 insertLong(vel, 1);
00352 insertLong(acceleration, 5);
00353 insertLong(torque, 9);
00354 insertChar((velocity < 0)?(0):(1), 13);
00355
00356 const bool retval = sendCommand(MOTOR_PORT, 0, MOTOR_AXIS_SET_DIR, 14);
00357 pthread_mutex_unlock(&m_write_mutex);
00358
00359 return retval;
00360 }
00361
00362
00363 bool RFlex::sendCommand(const unsigned char port, const unsigned char id, const unsigned char opcode, const int length) {
00364 assert(length + PROTOCOL_SIZE <= s_buffer_size);
00365
00366
00367 m_write_buffer[0] = ESC;
00368 m_write_buffer[1] = STX;
00369 m_write_buffer[PACKET_PORT_BYTE] = port;
00370 m_write_buffer[PACKET_ID_BYTE] = id;
00371 m_write_buffer[PACKET_OPCODE_BYTE] = opcode;
00372 m_write_buffer[PACKET_SIZE_BYTE] = static_cast<unsigned char>(length);
00373
00374
00375 m_write_buffer[length + PACKET_DATA_START_BYTE] = computeCRC(m_write_buffer + PACKET_CRC_START, length + PACKET_CRC_OFFSET);
00376 m_write_buffer[length + PACKET_DATA_START_BYTE + 1] = ESC;
00377 m_write_buffer[length + PACKET_DATA_START_BYTE + 2] = ETX;
00378
00379
00380 return writePacket(length + 9);
00381 }
00382
00383
00384 bool RFlex::writePacket(const int length) const {
00385 if (m_port.fail())
00386 return false;
00387
00388 int bytes_written = 0;
00389
00390 while (bytes_written < length) {
00391 int n = write(m_port, m_write_buffer + bytes_written, length - bytes_written);
00392 if (n < 0)
00393 return false;
00394 else
00395 bytes_written += n;
00396
00397
00398 usleep(1000);
00399 }
00400
00401 return true;
00402 }
00403
00404
00405 void RFlex::readPacket() {
00406
00407 const int read_size = readData();
00408 if (read_size == 0)
00409 return;
00410
00411
00412 const int data_size = read_size - PROTOCOL_SIZE;
00413 if (m_read_buffer[PACKET_SIZE_BYTE] != data_size) {
00414
00415 for(int i = 0; i < s_buffer_size; ++i) {
00416
00417
00418
00419 }
00420 }
00421
00422
00423 if (computeCRC(m_read_buffer + PACKET_CRC_START, data_size + PACKET_CRC_OFFSET) != m_read_buffer[data_size + PACKET_DATA_START_BYTE]) {
00424
00425
00426 for(int i = 0; i < s_buffer_size; ++i) {
00427
00428
00429
00430 }
00431
00432
00433 unsigned char tdata = 0;
00434 while (tdata != ETX)
00435 while (read(m_port, &tdata, 1) != 1);
00436
00437 return;
00438 }
00439
00440
00441 switch (m_read_buffer[PACKET_PORT_BYTE]) {
00442 case SYSTEM_PORT:
00443
00444 parseSystemReport();
00445 break;
00446 case MOTOR_PORT:
00447
00448 parseMotorReport();
00449 break;
00450 case JOYSTICK_PORT:
00451
00452 parseJoystickReport();
00453 break;
00454 case SONAR_PORT:
00455
00456 parseSonarReport();
00457 break;
00458 case DIGITAL_IO_PORT:
00459
00460 parseDigitalIOReport();
00461 break;
00462 case IR_PORT:
00463
00464 parseIRReport();
00465 break;
00466 default:
00467
00468 break;
00469 }
00470 }
00471
00472
00473 int RFlex::readData() {
00474
00475 if (read(m_port, m_read_buffer + m_offset, 1) != 1)
00476 return 0;
00477
00478
00479 if (!m_found) {
00480
00481
00482 if (m_read_buffer[0] != ESC) {
00483 m_offset = 0;
00484 return 0;
00485 }
00486 if (m_offset == 0) {
00487 m_offset = 1;
00488 return 0;
00489 }
00490
00491
00492
00493 if (m_read_buffer[1] == STX) {
00494 m_found = true;
00495 m_offset = 2;
00496 return 0;
00497 } else if (m_read_buffer[1] == ESC) {
00498 m_offset = 1;
00499 return 0;
00500 } else {
00501 m_offset = 0;
00502 return 0;
00503 }
00504 } else {
00505
00506 if (m_read_buffer[m_offset - 1] == ESC) {
00507 switch (m_read_buffer[m_offset]) {
00508 case NUL:
00509 read(m_port, m_read_buffer + m_offset, 1);
00510 ++m_offset;
00511 return 0;
00512 case SOH:
00513 --m_offset;
00514 return 0;
00515 case ETX:
00516 const int retval = m_offset + 1;
00517 m_found = false;
00518 m_offset = 0;
00519 return retval;
00520 };
00521 } else {
00522
00523 ++m_offset;
00524 assert(m_offset < s_buffer_size);
00525
00526 return 0;
00527 }
00528 }
00529
00530
00531 return 0;
00532 }
00533
00534
00535 void RFlex::parseSystemReport() {
00536 assert(m_read_buffer[PACKET_PORT_BYTE] == SYSTEM_PORT);
00537
00538 const int TIMESTAMP_OFFSET = 6;
00539 const int BATTERY_OFFSET = 10;
00540 const int BRAKE_OFFSET = 14;
00541
00542 const int ROW_OFFSET = 10;
00543 const int MESSAGE_LENGTH_OFFSET = 11;
00544 const int MESSAGE_BODY_OFFSET = 12;
00545
00546 const long timestamp = convertLong(TIMESTAMP_OFFSET);
00547
00548 switch (m_read_buffer[PACKET_OPCODE_BYTE]) {
00549 case SYSTEM_LCD_DUMP: {
00550 const int row = static_cast<int>(convertChar(ROW_OFFSET));
00551 const int length = static_cast<int>(convertChar(MESSAGE_LENGTH_OFFSET));
00552
00553 #ifndef NDEBUG
00554
00555 for(int i = 0; i < length; ++i)
00556
00557
00558 #endif
00559 break;
00560 }
00561 case SYSTEM_STATUS:
00562 m_battery_voltage = static_cast<float>(convertLong(BATTERY_OFFSET)) / 100.0;
00563
00564 break;
00565 default:
00566
00567 break;
00568 }
00569 }
00570
00571
00572 #warning Not complete yet
00573 void RFlex::parseMotorReport() {
00574 assert(m_read_buffer[PACKET_PORT_BYTE] == MOTOR_PORT);
00575
00576
00577 const int TIMESTAMP_OFFSET = 10;
00578 const int AXIS_OFFSET = 14;
00579 const int POSITION_OFFSET = 15;
00580 const int VELOCITY_OFFSET = 19;
00581 const int ACCELERATION_OFFSET = 23;
00582 const int TORQUE_OFFSET = 27;
00583
00584 const int TRANSLATION_AXIS = 0;
00585 const int ROTATION_AXIS = 1;
00586
00587 switch (m_read_buffer[PACKET_OPCODE_BYTE]) {
00588 case MOTOR_SYSTEM_REPORT: {
00589 const long timestamp = convertLong(TIMESTAMP_OFFSET);
00590 const long distance = static_cast<long>(convertLong(POSITION_OFFSET));
00591
00592 switch (m_read_buffer[AXIS_OFFSET]) {
00593 case TRANSLATION_AXIS:
00594 pthread_mutex_lock(&m_motor_mutex);
00595 if(!m_last_distance_set){
00596 m_last_distance=distance;
00597 m_last_distance_set=true;
00598 }
00599 m_x += static_cast<double>(distance - m_last_distance) / m_magicDistance * cos(m_theta);
00600 m_y += static_cast<double>(distance - m_last_distance) / m_magicDistance * sin(m_theta);
00601
00602 m_trans_velocity = static_cast<double>(convertLong(VELOCITY_OFFSET)) / m_magicDistance;
00603 m_trans_acceleration = static_cast<double>(convertLong(ACCELERATION_OFFSET)) / m_magicDistance;
00604 #warning Should the torque be using MAGIC_TORQUE?
00605 m_trans_torque = static_cast<double>(convertLong(TORQUE_OFFSET)) / m_magicDistance;
00606 m_last_distance = distance;
00607 pthread_mutex_unlock(&m_motor_mutex);
00608
00609 break;
00610 case ROTATION_AXIS:
00611 pthread_mutex_lock(&m_motor_mutex);
00612 if(!m_last_angdistance_set){
00613 m_last_angdistance=distance;
00614 m_last_angdistance_set=true;
00615 }
00616
00617 m_theta += static_cast<double>(distance-m_last_angdistance) / m_magicAngle;
00618
00619 m_rot_velocity = static_cast<double>(convertLong(VELOCITY_OFFSET)) / m_magicAngle;
00620 m_rot_acceleration = static_cast<double>(convertLong(ACCELERATION_OFFSET)) / m_magicAngle;
00621 #warning Should the torque be using MAGIC_TORQUE?
00622 m_rot_torque = static_cast<double>(convertLong(TORQUE_OFFSET)) / m_magicAngle;
00623 m_last_angdistance=distance;
00624 pthread_mutex_unlock(&m_motor_mutex);
00625 break;
00626 default:
00627
00628 break;
00629 };
00630 break;
00631 }
00632 case MOTOR_AXIS_SET_DIR:
00633
00634 #warning Should we keep a total of requests and acks, to make sure that theyre more-or-less balanced?
00635 break;
00636 default:
00637
00638 break;
00639 }
00640 }
00641
00642
00643 #warning Not complete yet
00644 void RFlex::parseJoystickReport() {
00645 assert(m_read_buffer[PACKET_PORT_BYTE] == JOYSTICK_PORT);
00646
00647 const int TIMESTAMP_OFFSET = 6;
00648 const int X_OFFSET = 10;
00649 const int Y_OFFSET = 14;
00650 const int BUTTON_OFFSET = 18;
00651
00652 switch (m_read_buffer[PACKET_OPCODE_BYTE]) {
00653 case JOYSTICK_GET_STATE: {
00654 const long timestamp = convertLong(TIMESTAMP_OFFSET);
00655 const long x = convertLong(X_OFFSET);
00656 const long y = convertLong(Y_OFFSET);
00657 const unsigned char buttons = convertChar(BUTTON_OFFSET);
00658
00659
00660
00661 #warning Need to update stored values
00662 break;
00663 }
00664 default:
00665
00666 break;
00667 }
00668 }
00669
00670
00671 #warning Not complete yet
00672 void RFlex::parseSonarReport() {
00673 #warning Need to implement this
00674 assert(m_read_buffer[PACKET_PORT_BYTE] == SONAR_PORT);
00675
00676 const int DATA_LENGTH_OFFSET = 5;
00677 const int VALUE_OFFSET = 6;
00678 const int TIMESTAMP_OFFSET = 10;
00679 const int DATA_OFFSET = 14;
00680
00681 switch (m_read_buffer[PACKET_OPCODE_BYTE]) {
00682 case SONAR_REPORT:
00683 const unsigned char data_length = convertChar(DATA_LENGTH_OFFSET);
00684 const long value = convertLong(VALUE_OFFSET);
00685 const long timestamp = convertLong(TIMESTAMP_OFFSET);
00686
00687 for(int i = 0; i < (data_length - 8) / 3; ++i) {
00688 const int sonar_id = convertChar(DATA_OFFSET + (3 * i));
00689 const int sonar_value = convertShort(DATA_OFFSET + (3 * i) + 1);
00690 if (sonar_value < 500){
00691
00692 if(m_type==RFLEX_ATRVJR){
00693 switch(sonar_id){
00694 case 0x22:
00695 m_sonars[0]=sonar_value;
00696 break;
00697 case 0x23:
00698 m_sonars[1]=sonar_value;
00699 break;
00700 case 0x24:
00701 m_sonars[2]=sonar_value;
00702 break;
00703 case 0x25:
00704 m_sonars[3]=sonar_value;
00705 break;
00706 case 0x14:
00707 m_sonars[4]=sonar_value;
00708 break;
00709 case 0x13:
00710 m_sonars[5]=sonar_value;
00711 break;
00712 case 0x12:
00713 m_sonars[6]=sonar_value;
00714 break;
00715 case 0x11:
00716 m_sonars[7]=sonar_value;
00717 break;
00718 case 0x10:
00719 m_sonars[8]=sonar_value;
00720 break;
00721 case 0x05:
00722 m_sonars[9]=sonar_value;
00723 break;
00724 case 0x04:
00725 m_sonars[10]=sonar_value;
00726 break;
00727 case 0x03:
00728 m_sonars[11]=sonar_value;
00729 break;
00730 case 0x02:
00731 m_sonars[12]=sonar_value;
00732 break;
00733 case 0x01:
00734 m_sonars[13]=sonar_value;
00735 break;
00736 case 0x00:
00737 m_sonars[14]=sonar_value;
00738 break;
00739 case 0x20:
00740 m_sonars[15]=sonar_value;
00741 break;
00742 case 0x21:
00743 m_sonars[16]=sonar_value;
00744 break;
00745 }
00746 }
00747 }
00748 cerr << "Sonar " << sonar_id << " value: " << sonar_value << endl;
00749
00750 }
00751
00752 break;
00753
00754
00755
00756
00757 }
00758 }
00759
00760
00761 #warning Not complete yet
00762 void RFlex::parseDigitalIOReport() {
00763 #warning Need to implement this
00764 assert(m_read_buffer[PACKET_PORT_BYTE] == DIGITAL_IO_PORT);
00765 }
00766
00767
00768 #warning Not complete yet
00769 void RFlex::parseIRReport() {
00770 #warning Need to implement this
00771 assert(m_read_buffer[PACKET_PORT_BYTE] == IR_PORT);
00772 }
00773
00774
00775 unsigned char RFlex::convertChar(const int offset) const {
00776 assert((offset >= 0) && (offset < s_buffer_size - 1));
00777
00778 unsigned char n;
00779 memcpy(&n, m_read_buffer + offset, sizeof(unsigned char));
00780 return n;
00781 }
00782
00783
00784 unsigned short RFlex::convertShort(const int offset) const {
00785 assert((offset >= 0) && (offset < s_buffer_size - 2));
00786
00787 unsigned short n;
00788 memcpy(&n, m_read_buffer + offset, sizeof(unsigned short));
00789 return htons(n);
00790 }
00791
00792
00793 unsigned long RFlex::convertLong(const int offset) const {
00794 assert((offset >= 0) && (offset < s_buffer_size - 4));
00795
00796 unsigned long n;
00797 memcpy(&n, m_read_buffer + offset, sizeof(unsigned long));
00798 return htonl(n);
00799 }
00800
00801
00802 void RFlex::insertChar(const unsigned char value, const int offset) {
00803 assert(sizeof(unsigned char) == 1);
00804 assert((offset >= 0) && (offset < s_buffer_size - PACKET_DATA_START_BYTE - 1));
00805
00806 memcpy(m_write_buffer + PACKET_DATA_START_BYTE + offset, &value, sizeof(unsigned char));
00807 }
00808
00809
00810 void RFlex::insertLong(const long value, const int offset) {
00811 assert(sizeof(unsigned long) == 4);
00812 assert((offset >= 0) && (offset < s_buffer_size - PACKET_DATA_START_BYTE - 4));
00813
00814 unsigned long v = htonl(value);
00815 memcpy(m_write_buffer + PACKET_DATA_START_BYTE + offset, &v, sizeof(unsigned long));
00816 }
00817
00818
00819 unsigned char RFlex::computeCRC(const unsigned char *buffer, const int n) {
00820 assert(buffer != NULL);
00821 assert(n > 0);
00822
00823 int crc =buffer[0];
00824 for(int i = 1; i < n; ++i)
00825 crc ^= buffer[i];
00826
00827 return crc;
00828 }
00829
00830
00831 void *RFlex::rFlexReadThread(void *ptr) {
00832 RFlex *rflex = static_cast<RFlex *>(ptr);
00833
00834 while (true) {
00835
00836 fd_set read_set;
00837 FD_ZERO(&read_set);
00838 FD_SET(rflex->m_port, &read_set);
00839
00840
00841 if (select(rflex->m_port + 1, &read_set, NULL, NULL, NULL) < 0) {
00842
00843 } else if (FD_ISSET(rflex->m_port, &read_set)) {
00844 rflex->readPacket();
00845 }
00846 }
00847 }
00848
00849
00850 void *RFlex::rFlexPeriodicThread(void *ptr) {
00851 RFlex *rflex = static_cast<RFlex *>(ptr);
00852
00853 int counter = 0;
00854 while (true) {
00855
00856
00857
00858 if ((counter % 5) == 0) {
00859 }
00860
00861
00862 if ((counter % 10) == 0) {
00863
00864
00865 pthread_mutex_lock(&(rflex->m_command_mutex));
00866 rflex->motorSendTranslateVelocity(rflex->m_translate_command);
00867 rflex->motorSendRotateVelocity(rflex->m_rotate_command);
00868 pthread_mutex_unlock(&(rflex->m_command_mutex));
00869
00870 rflex->systemUpdate();
00871
00872 }
00873
00874
00875 if ((counter % 20) == 0) {
00876 }
00877
00878
00879 if (counter == 0) {
00880 }
00881
00882
00883 usleep(10000);
00884
00885 counter = (counter + 1) % 100;
00886 }
00887 }
00888