37 #include <arpa/inet.h>
38 #include <boost/algorithm/string/predicate.hpp>
39 #include <boost/foreach.hpp>
62 ROS_WARN_STREAM(
"Serial read buffer is " << available <<
", now flushing in an attempt to catch up.");
67 uint8_t header_bytes[5];
70 uint8_t type, address;
71 if (memcmp(header_bytes,
"snp", 3) == 0)
74 type = header_bytes[3];
75 address = header_bytes[4];
82 if (!boost::algorithm::ends_with(snp,
"snp"))
throw SerialTimeout();
86 "Discarded " << 5 + snp.length() - 3 <<
" junk byte(s) preceeding packet.");
94 uint16_t checksum_calculated =
's' +
'n' +
'p' + type + address;
98 uint8_t data_length = 1;
102 ROS_DEBUG(
"Received packet %02x with batched (%d) data.", address, data_length);
106 ROS_DEBUG(
"Received packet %02x with non-batched data.", address);
111 BOOST_FOREACH(uint8_t ch, data)
113 checksum_calculated += ch;
118 ROS_DEBUG(
"Received packet %02x without data.", address);
122 uint16_t checksum_transmitted;
123 if (
serial_->
read(
reinterpret_cast<uint8_t*
>(&checksum_transmitted), 2) != 2)
127 checksum_transmitted = ntohs(checksum_transmitted);
128 if (checksum_transmitted != checksum_calculated)
135 if ((data.length() > 0) && registers)
137 registers->write_raw(address, data);
145 ROS_WARN(
"Timed out waiting for packet from device.");
149 ROS_WARN(
"Discarding packet due to bad checksum.");
157 BOOST_FOREACH(uint8_t ch,
s)
162 ROS_DEBUG(
"Computed checksum on string of length %zd as %04x.",
s.length(),
checksum);
163 std::string out(2, 0);
171 if (data.length() > 0)
175 if (data.length() > 4)
181 std::stringstream ss(std::stringstream::out | std::stringstream::binary);
182 ss <<
"snp" << type << address << data;
183 std::string output = ss.str();
187 ROS_DEBUG(
"Generated message %02x of overall length %zd.", address, output.length());
193 uint8_t address = r.
index;
194 std::string data(
reinterpret_cast<char*
>(r.
raw()), r.
length * 4);
200 const uint8_t tries = 5;
201 for (uint8_t t = 0; t < tries; t++)
204 const uint8_t listens = 20;
205 for (uint8_t i = 0; i < listens; i++)
208 if (received == r.
index)
210 ROS_DEBUG(
"Message %02x ack received.", received);
213 else if (received == -1)
215 ROS_DEBUG(
"Serial read timed out waiting for ack. Attempting to retransmit.");