rmp_io.cc
Go to the documentation of this file.
1 #include "segwayrmp/segwayrmp.h"
3 
4 inline void printHex(char * data, int length) {
5  for(int i = 0; i < length; ++i) {
6  printf("0x%.2X ", (unsigned)(unsigned char)data[i]);
7  }
8  printf("\n");
9 }
10 
11 using namespace segwayrmp;
12 
13 static unsigned int BUFFER_SIZE = 256;
14 
16 // RMPIO
17 
18 void RMPIO::getPacket(Packet &packet) {
19  if(!this->connected)
20  RMP_THROW_MSG_AND_ID(PacketRetrievalException, "Not connected.", 1);
21 
22  unsigned char usb_packet[18];
23  bool packet_complete = false;
24  int packet_index = 0;
25 
26  while(!packet_complete && !this->canceled) {
27  // Top the buffer off
28  size_t prev_size = this->data_buffer.size();
29  if(prev_size < 18) {
30  this->fillBuffer();
31  // Ensure that data was read into the buffer
32  if(prev_size == this->data_buffer.size()) {
33  RMP_THROW_MSG_AND_ID(PacketRetrievalException, "No data received "
34  "from Segway.", 3);
35  }
36  }
37 
38  // If looking for start of packet and start of packet
39  if(packet_index == 0 && this->data_buffer[0] == 0xF0) {
40  // Put the 0xF0 in the packet
41  usb_packet[packet_index] = this->data_buffer[0];
42  // Remove the 0xF0 from the buffer
43  this->data_buffer.erase(this->data_buffer.begin());
44  // Look for next packet byte
45  packet_index += 1;
46  } else if(packet_index == 0) { // If we were looking for the first byte, but didn't find it
47  // Remove the invalid byte from the buffer
48  this->data_buffer.erase(this->data_buffer.begin());
49  }
50 
51  // If looking for second byte of packet and second byte of packet
52  if(packet_index == 1 && this->data_buffer[0] == 0x55) {
53  // Put the 0x55 in the packet
54  usb_packet[packet_index] = this->data_buffer[0];
55  // Remove the 0x55 from the buffer
56  this->data_buffer.erase(this->data_buffer.begin());
57  // Look for next packet byte
58  packet_index += 1;
59  } else if(packet_index == 1) { // Else were looking for second byte but didn't find it
60  // Reset the packet index to start search for packet over
61  packet_index = 0;
62  }
63 
64  // If looking for channel byte and channel A or B
65  if(packet_index == 2 && (this->data_buffer[0] == 0xAA || this->data_buffer[0] == 0xBB)) {
66  // Put the channel in the packet
67  usb_packet[packet_index] = this->data_buffer[0];
68  // Remove the channel from the buffer
69  this->data_buffer.erase(this->data_buffer.begin());
70  // Look for next packet byte
71  packet_index += 1;
72  } else if(packet_index == 2) { // Else were looking for channel byte but didn't find it
73  // Reset the packet index to start search for packet over
74  packet_index = 0;
75  }
76 
77  // If packet_index >= 3 then we just need to collect the rest of the bytes
78  // (we assume that if the previous three bytes were recieved then this is a valid packet,
79  // if it isn't the checksum will fail)
80  if(packet_index >= 3) {
81  // Put the next btye in the packet
82  usb_packet[packet_index] = this->data_buffer[0];
83  // Remove the byte from the buffer
84  this->data_buffer.erase(this->data_buffer.begin());
85  // Look for next packet byte
86  packet_index += 1;
87  }
88 
89  // If packet_index is 18 then we have a full packet
90  if(packet_index == 18)
91  packet_complete = true;
92  }
93 
94  // Check the Checksum
95  if(usb_packet[17] != this->computeChecksum(usb_packet)) {
96  RMP_THROW_MSG_AND_ID(PacketRetrievalException, "Checksum mismatch.", 2);
97  }
98 
99  // Convert to the packet type
100  packet.channel = usb_packet[2];
101  packet.id = ((usb_packet[4] << 3) | ((usb_packet[5] >> 5) & 7)) & 0x0fff;
102  for (int i = 0; i < 8; i++) {
103  packet.data[i] = usb_packet[i + 9];
104  }
105 
106  return;
107 }
108 
109 void RMPIO::sendPacket(Packet &packet) {
110  unsigned char usb_packet[18] = {0xF0, 0x55, 0x00, 0x00, 0x00, 0x00, 0x04,
111  0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112  0x00, 0x00, 0x00, 0x00};
113  // Set the id
114  usb_packet[6] = (packet.id & 0xFF00) >> 8;
115  usb_packet[7] = packet.id & 0x00FF;
116  // Set the desitnation channel, 0x01 for 0xAA and 0x02 for 0xBB
117  usb_packet[2] = packet.channel;
118  // Copy movement and configuration commands
119  for(int i = 0; i < 8; ++i) {
120  usb_packet[9+i] = packet.data[i];
121  }
122  // Compute and set the checksum
123  usb_packet[17] = this->computeChecksum(usb_packet);
124 
125  // Write the data
126  this->write(usb_packet, 18);
127 }
128 
130  unsigned char buffer[BUFFER_SIZE];
131  // Read up to BUFFER_SIZE what ever is needed to fill the vector
132  // to BUFFER_SIZE
133  int bytes_read = this->read(buffer, BUFFER_SIZE-this->data_buffer.size());
134  // Append the buffered data to the vector
135  this->data_buffer.insert(this->data_buffer.end(), buffer, buffer+bytes_read);
136 }
137 
138 unsigned char RMPIO::computeChecksum(unsigned char* usb_packet) {
139  unsigned short checksum = 0;
140  unsigned short checksum_hi = 0;
141 
142  for(int i = 0; i < 17; i++) {
143  checksum += (short)usb_packet[i];
144  }
145 
146  checksum_hi = (unsigned short)(checksum >> 8);
147  checksum &= 0xff;
148  checksum += checksum_hi;
149  checksum_hi = (unsigned short)(checksum >> 8);
150  checksum &= 0xff;
151  checksum += checksum_hi;
152  checksum = (~checksum + 1) & 0xff;
153  return (unsigned char)checksum;
154 }
unsigned char computeChecksum(unsigned char *usb_packet)
Definition: rmp_io.cc:138
void sendPacket(Packet &packet)
Definition: rmp_io.cc:109
bool connected
Definition: rmp_io.h:129
std::vector< unsigned char > data_buffer
Definition: rmp_io.h:132
void printHex(char *data, int length)
Definition: rmp_io.cc:4
static unsigned int BUFFER_SIZE
Definition: rmp_io.cc:13
void getPacket(Packet &packet)
Definition: rmp_io.cc:18
unsigned char channel
Definition: rmp_io.h:57
virtual int read(unsigned char *buffer, int size)=0
unsigned short id
Definition: rmp_io.h:56
unsigned char data[8]
Definition: rmp_io.h:58
void fillBuffer()
Definition: rmp_io.cc:129
#define RMP_THROW_MSG_AND_ID(ExceptionClass, Message, Id)
Definition: segwayrmp.h:86
virtual int write(unsigned char *buffer, int size)=0


libsegwayrmp
Author(s): William Woodall
autogenerated on Mon Jun 10 2019 13:46:49