Go to the documentation of this file.00001 #include "segwayrmp/segwayrmp.h"
00002 #include "segwayrmp/impl/rmp_io.h"
00003
00004 inline void printHex(char * data, int length) {
00005 for(int i = 0; i < length; ++i) {
00006 printf("0x%.2X ", (unsigned)(unsigned char)data[i]);
00007 }
00008 printf("\n");
00009 }
00010
00011 using namespace segwayrmp;
00012
00013 static unsigned int BUFFER_SIZE = 256;
00014
00016
00017
00018 void RMPIO::getPacket(Packet &packet) {
00019 if(!this->connected)
00020 RMP_THROW_MSG_AND_ID(PacketRetrievalException, "Not connected.", 1);
00021
00022 unsigned char usb_packet[18];
00023 bool packet_complete = false;
00024 int packet_index = 0;
00025
00026 while(!packet_complete && !this->canceled) {
00027
00028 size_t prev_size = this->data_buffer.size();
00029 if(prev_size < 18) {
00030 this->fillBuffer();
00031
00032 if(prev_size == this->data_buffer.size()) {
00033 RMP_THROW_MSG_AND_ID(PacketRetrievalException, "No data received "
00034 "from Segway.", 3);
00035 }
00036 }
00037
00038
00039 if(packet_index == 0 && this->data_buffer[0] == 0xF0) {
00040
00041 usb_packet[packet_index] = this->data_buffer[0];
00042
00043 this->data_buffer.erase(this->data_buffer.begin());
00044
00045 packet_index += 1;
00046 } else if(packet_index == 0) {
00047
00048 this->data_buffer.erase(this->data_buffer.begin());
00049 }
00050
00051
00052 if(packet_index == 1 && this->data_buffer[0] == 0x55) {
00053
00054 usb_packet[packet_index] = this->data_buffer[0];
00055
00056 this->data_buffer.erase(this->data_buffer.begin());
00057
00058 packet_index += 1;
00059 } else if(packet_index == 1) {
00060
00061 packet_index = 0;
00062 }
00063
00064
00065 if(packet_index == 2 && (this->data_buffer[0] == 0xAA || this->data_buffer[0] == 0xBB)) {
00066
00067 usb_packet[packet_index] = this->data_buffer[0];
00068
00069 this->data_buffer.erase(this->data_buffer.begin());
00070
00071 packet_index += 1;
00072 } else if(packet_index == 2) {
00073
00074 packet_index = 0;
00075 }
00076
00077
00078
00079
00080 if(packet_index >= 3) {
00081
00082 usb_packet[packet_index] = this->data_buffer[0];
00083
00084 this->data_buffer.erase(this->data_buffer.begin());
00085
00086 packet_index += 1;
00087 }
00088
00089
00090 if(packet_index == 18)
00091 packet_complete = true;
00092 }
00093
00094
00095 if(usb_packet[17] != this->computeChecksum(usb_packet)) {
00096 RMP_THROW_MSG_AND_ID(PacketRetrievalException, "Checksum mismatch.", 2);
00097 }
00098
00099
00100 packet.channel = usb_packet[2];
00101 packet.id = ((usb_packet[4] << 3) | ((usb_packet[5] >> 5) & 7)) & 0x0fff;
00102 for (int i = 0; i < 8; i++) {
00103 packet.data[i] = usb_packet[i + 9];
00104 }
00105
00106 return;
00107 }
00108
00109 void RMPIO::sendPacket(Packet &packet) {
00110 unsigned char usb_packet[18] = {0xF0, 0x55, 0x00, 0x00, 0x00, 0x00, 0x04,
00111 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00112 0x00, 0x00, 0x00, 0x00};
00113
00114 usb_packet[6] = (packet.id & 0xFF00) >> 8;
00115 usb_packet[7] = packet.id & 0x00FF;
00116
00117 usb_packet[2] = packet.channel;
00118
00119 for(int i = 0; i < 8; ++i) {
00120 usb_packet[9+i] = packet.data[i];
00121 }
00122
00123 usb_packet[17] = this->computeChecksum(usb_packet);
00124
00125
00126 this->write(usb_packet, 18);
00127 }
00128
00129 void RMPIO::fillBuffer() {
00130 unsigned char buffer[BUFFER_SIZE];
00131
00132
00133 int bytes_read = this->read(buffer, BUFFER_SIZE-this->data_buffer.size());
00134
00135 this->data_buffer.insert(this->data_buffer.end(), buffer, buffer+bytes_read);
00136 }
00137
00138 unsigned char RMPIO::computeChecksum(unsigned char* usb_packet) {
00139 unsigned short checksum = 0;
00140 unsigned short checksum_hi = 0;
00141
00142 for(int i = 0; i < 17; i++) {
00143 checksum += (short)usb_packet[i];
00144 }
00145
00146 checksum_hi = (unsigned short)(checksum >> 8);
00147 checksum &= 0xff;
00148 checksum += checksum_hi;
00149 checksum_hi = (unsigned short)(checksum >> 8);
00150 checksum &= 0xff;
00151 checksum += checksum_hi;
00152 checksum = (~checksum + 1) & 0xff;
00153 return (unsigned char)checksum;
00154 }