qbrobotics_research_api.cpp
Go to the documentation of this file.
1 /***
2  * Software License Agreement: BSD 3-Clause License
3  *
4  * Copyright (c) 2015-2021, qbrobotics®
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
8  * following conditions are met:
9  *
10  * * Redistributions of source code must retain the above copyright notice, this list of conditions and the
11  * following disclaimer.
12  *
13  * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
14  * following disclaimer in the documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote
17  * products derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
25  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 // standard libraries
29 #include <algorithm>
30 #include <sstream> // for macOS
31 // project libraries
33 
34 using namespace qbrobotics_research_api;
35 
37  : Communication(2000000) {}
38 
39 Communication::Communication(uint32_t baud_rate)
40  : Communication(baud_rate, serial::Serial::Timeout(200)) {} // could be serial::Serial::Timeout(20) for new devices but legacy require a higher timeout(even 150 for SHR2)
41 
43  : Communication(2000000, timeout) {}
44 
45 Communication::Communication(uint32_t baud_rate, const serial::Serial::Timeout &timeout)
46  : serial_ports_baud_rate_(baud_rate),
47  serial_ports_timeout_(timeout) {}
48 
50  : Communication(communication, communication.serial_ports_timeout_) {}
51 
53  : connected_devices_(communication.connected_devices_),
54  serial_ports_info_(communication.serial_ports_info_),
55  serial_ports_(communication.serial_ports_),
56  serial_ports_baud_rate_(communication.serial_ports_baud_rate_),
57  serial_ports_timeout_(timeout) {}
58 
59 int Communication::listSerialPorts(std::vector<serial::PortInfo> &serial_ports_info) {
60  serial_ports_info.clear();
61 
62  std::vector<serial::PortInfo> connected_serial_ports;
63  if (serial::getPortsInfo(connected_serial_ports) < 0) {
64  return -1;
65  }
66 
67  // add new entries to private members
68  for (auto const &serial_port : connected_serial_ports) {
69  if (serial_port.manufacturer == "QB Robotics" || serial_port.id_vendor == 0x403) {
70  serial_ports_info.push_back(serial_port);
71  if (!isInSerialPortsInfo(serial_port.serial_port)) {
72  if (isInSerialPorts(serial_port.serial_port)) {
73  return -1; // this should never happen
74  }
75  serial_ports_info_[serial_port.serial_port] = serial_port;
76  serial_ports_[serial_port.serial_port] = std::make_shared<serial::Serial>(); // this does not open the serial port
77  }
78  }
79  }
80 
81  // remove no longer existing entries in private members
82  for (auto serial_port_it = serial_ports_info_.begin(); serial_port_it != serial_ports_info_.end();) {
83  if (std::find_if(connected_serial_ports.begin(), connected_serial_ports.end(),
84  [&](auto item){ return serial_port_it->first == item.serial_port; }) == connected_serial_ports.end()) {
85  serial_ports_.erase(serial_port_it->first);
86  serial_port_it = serial_ports_info_.erase(serial_port_it);
87  } else {
88  serial_port_it++; // only when items are not erased
89  }
90  }
91 
92  return serial_ports_info.size();
93 }
94 
96  connected_devices_.clear();
97  int connected_devices = 0;
98  for (auto const &serial_port : serial_ports_) {
99  std::vector<ConnectedDeviceInfo> device_ids;
100  if (listConnectedDevices(serial_port.first, device_ids) > 0) {
101  connected_devices_[serial_port.first] = device_ids;
102  connected_devices += device_ids.size();
103  }
104  }
105  return connected_devices;
106 }
107 
108 int Communication::listConnectedDevices(const std::string &serial_port_name, std::vector<ConnectedDeviceInfo> &device_ids) {
109  device_ids.clear();
110 
112  if (!openSerialPort(serial_port_name, serial_ports_baud_rate_, short_timeout)) {
113  serial_ports_.at(serial_port_name)->setTimeout(short_timeout); // if already connected it might have a different timeout
114  std::vector<int8_t> data_in;
115 
116  std::vector<uint8_t> max_id({255, 50, 10, 10, 10}); // max ID checked during i-th scan
117  // Smart device scan: more retries for lower IDs (more likely)
118  // 1-10: very likely -> 5x10 scan
119  // 11-50: unlikely -> 2x40 scan
120  // 51-255: very unlikely -> 1x205 scan
121  // = 335 pings
122  for (size_t scan = 0; scan < max_id.size(); scan++) {
123  for (uint16_t device_id = 1; device_id <= max_id.at(scan); device_id++) { // should be uint8_t, but uint8_t(256) == 0 and it never ends
124  // skip device_id if already found
125  if (std::find_if(device_ids.begin(), device_ids.end(), [&device_id](const auto& info){ return info.id == device_id; }) != device_ids.end()) {
126  continue;
127  }
128  // sendCommandAndParse with 0 repetitions. Actual repetitions are decided by the for loops
129  if (sendCommandAndParse(serial_port_name, device_id, CMD_PING, 0, data_in) >= 0) {
130  device_ids.push_back({static_cast<uint8_t>(device_id)});
131  if (data_in.size() > 0) { // the 4-byte S/N is stored in the ping payload (only for v7.1+ firmware)
132  std::stringstream str;
133  str << std::setfill('0') << std::setw(10) << Communication::vectorCastAndSwap<uint32_t>(data_in).front();
134  std::string serial_number(str.str());
135  device_ids.back().serial_number = serial_number;
136  device_ids.back().type = std::string(serial_number.begin(), serial_number.begin()+3);
137  device_ids.back().sub_type = std::string(serial_number.begin()+3, serial_number.begin()+6);
138  }
139  }
140  }
141  }
142  std::sort(device_ids.begin(), device_ids.end(), [](const auto& a, const auto& b){ return a.id > b.id; });
143  }
144  serial_ports_.at(serial_port_name)->setTimeout(serial_ports_timeout_);
145 
146  return device_ids.size();
147 }
148 
149 int Communication::closeSerialPort(const std::string &serial_port_name) {
150  if (!isInSerialPorts(serial_port_name)) {
151  return -1;
152  }
153 
154  try {
155  serial_ports_.at(serial_port_name)->close();
156  } catch (...) {
157  return -1;
158  }
159 
160  return 0;
161 }
162 
163 int Communication::createSerialPort(const std::string &serial_port_name) {
164  return createSerialPort(serial_port_name, serial_ports_baud_rate_);
165 }
166 
167 int Communication::createSerialPort(const std::string &serial_port_name, uint32_t baud_rate) {
168  return createSerialPort(serial_port_name, baud_rate, serial_ports_timeout_);
169 }
170 
171 int Communication::createSerialPort(const std::string &serial_port_name, const serial::Serial::Timeout &timeout) {
172  return createSerialPort(serial_port_name, serial_ports_baud_rate_, timeout);
173 }
174 
175 int Communication::createSerialPort(const std::string &serial_port_name, uint32_t baud_rate, const serial::Serial::Timeout &timeout) {
176  if (isInSerialPorts(serial_port_name)) {
177  return -1;
178  }
179 
180  try {
181  serial_ports_[serial_port_name] = std::make_shared<serial::Serial>(serial_port_name, baud_rate, timeout);
182  } catch (...) {
183  return -1;
184  }
185  return 0;
186 }
187 
188 int Communication::openSerialPort(const std::string &serial_port_name) {
189  return openSerialPort(serial_port_name, serial_ports_baud_rate_);
190 }
191 
192 int Communication::openSerialPort(const std::string &serial_port_name, uint32_t baud_rate) {
193  return openSerialPort(serial_port_name, baud_rate, serial_ports_timeout_);
194 }
195 
196 int Communication::openSerialPort(const std::string &serial_port_name, serial::Serial::Timeout &timeout) {
197  return openSerialPort(serial_port_name, serial_ports_baud_rate_, timeout);
198 }
199 
200 int Communication::openSerialPort(const std::string &serial_port_name, uint32_t baud_rate, serial::Serial::Timeout &timeout) {
201  if (!isInSerialPorts(serial_port_name)) {
202  return -1;
203  }
204  if (serial_ports_.at(serial_port_name)->isOpen()) {
205  return 0;
206  }
207 
208  try {
209  if (serial_ports_.at(serial_port_name)->getPort().empty()) {
210  serial_ports_.at(serial_port_name)->setPort(serial_port_name);
211  }
212  serial_ports_.at(serial_port_name)->setBaudrate(baud_rate);
213  serial_ports_.at(serial_port_name)->setTimeout(timeout);
214  serial_ports_.at(serial_port_name)->open();
215  } catch (...) {
216  return -1;
217  }
218  return 0;
219 }
220 
221 int Communication::parsePackage(const std::string &serial_port_name, uint8_t device_id, uint8_t command) {
222  std::vector<int8_t> data_in;
223  return parsePackage(serial_port_name, device_id, command, data_in);
224 }
225 
226 int Communication::parsePackage(const std::string &serial_port_name, uint8_t device_id, uint8_t command, std::vector<int8_t> &data_in) {
227  data_in.clear();
228  uint8_t device_id_in = 0;
229  uint8_t command_in = 0;
230  std::vector<int8_t> data_in_buffer;
231 
232  // works only for non-broadcast commands
233  if (!device_id) {
234  return -1;
235  }
236 
237  while (readPackage(serial_port_name, device_id_in, command_in, data_in_buffer) > 0) {
238  //WARN: this is ugly because it can lead to unwanted command parsing on CMD_INIT_MEM, CMD_RESTORE_PARAMS or CMD_GET_PARAM_LIST (especially this that is used for many things!)
239  if (device_id != device_id_in && (command != CMD_INIT_MEM && command != CMD_RESTORE_PARAMS && (command != CMD_GET_PARAM_LIST || data_in_buffer.size() != 1))) { // id and id_in can differ on CMD_INIT_MEM or CMD_RESTORE_PARAMS (and also with CMD_GET_PARAM_LIST when changing the device ID)
240  continue;
241  }
242  // ACK is checked from the caller that knows whether the command has ACK or not
243  if (command_in == command) {
244  data_in = data_in_buffer;
245  if (device_id != device_id_in) {
246  data_in.push_back(device_id_in); // ugly fix to pass the new id to the caller (data_in_buffer is only the ACK response in these cases)
247  }
248  return data_in.size();
249  }
250  }
251  return -1;
252 }
253 
254 int Communication::sendCommand(const std::string &serial_port_name, uint8_t device_id, uint8_t command) {
255  std::vector<int8_t> data_out;
256  return sendCommand(serial_port_name, device_id, command, data_out);
257 }
258 
259 int Communication::sendCommand(const std::string &serial_port_name, uint8_t device_id, uint8_t command, const std::vector<int8_t> &data_out) {
260  if (openSerialPort(serial_port_name)) {
261  return -1;
262  }
263  if (writePackage(serial_port_name, device_id, command, data_out) < 0) {
264  return -1;
265  }
266  return 0;
267 }
268 
269 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command) {
270  return sendCommandAndParse(serial_port_name, device_id, command, 2); // 3 attempts by default (1 + 2 optional retrials)
271 }
272 
273 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, uint8_t max_repeats) {
274  std::vector<int8_t> data_in, data_out;
275  return sendCommandAndParse(serial_port_name, device_id, command, max_repeats, data_out, data_in);
276 }
277 
278 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, std::vector<int8_t> &data_in) {
279  return sendCommandAndParse(serial_port_name, device_id, command, 2, data_in); // 3 attempts by default (1 + 2 optional retrials)
280 }
281 
282 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, uint8_t max_repeats, std::vector<int8_t> &data_in) {
283  std::vector<int8_t> data_out;
284  return sendCommandAndParse(serial_port_name, device_id, command, max_repeats, data_out, data_in);
285 }
286 
287 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, const std::vector<int8_t> &data_out) {
288  return sendCommandAndParse(serial_port_name, device_id, command, 2, data_out); // 3 attempts by default (1 + 2 optional retrials)
289 }
290 
291 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, uint8_t max_repeats, const std::vector<int8_t> &data_out) {
292  std::vector<int8_t> data_in;
293  return sendCommandAndParse(serial_port_name, device_id, command, max_repeats, data_out, data_in);
294 }
295 
296 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, const std::vector<int8_t> &data_out, std::vector<int8_t> &data_in) {
297  return sendCommandAndParse(serial_port_name, device_id, command, 2, data_out, data_in); // 3 attempts by default (1 + 2 optional retrials)
298 }
299 
300 int Communication::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, uint8_t max_repeats, const std::vector<int8_t> &data_out, std::vector<int8_t> &data_in) {
301  uint8_t repeats = 0;
302  data_in.clear();
303 
304  while (repeats <= max_repeats) {
305  if (sendCommand(serial_port_name, device_id, command, data_out) < 0) {
306  repeats++;
307  continue;
308  }
309 
310  if (command == CMD_STORE_PARAMS || command == CMD_STORE_DEFAULT_PARAMS) { // writing to EEPROM takes a while
311  std::this_thread::sleep_for(std::chrono::milliseconds(600));
312  }
313 
314  std::vector<int8_t> packages_in;
315  if (parsePackage(serial_port_name, device_id, command, packages_in) >= 0) {
316  data_in = packages_in;
317  break;
318  }
319 
320  repeats++;
321  }
322 
323  return repeats <= max_repeats ? data_in.size() : -1;
324 }
325 
326 int Communication::sendCommandBroadcast(const std::string &serial_port_name, uint8_t command) {
327  std::vector<int8_t> data_out;
328  return sendCommand(serial_port_name, 0, command, data_out);
329  //WARN: broadcast should be used only for non-returning methods (it is unreliable for returning methods)
330 }
331 
332 int Communication::sendCommandBroadcast(const std::string &serial_port_name, uint8_t command, const std::vector<int8_t> &data_out) {
333  return sendCommand(serial_port_name, 0, command, data_out);
334  //WARN: broadcast should be used only for non-returning methods (it is unreliable for returning methods)
335 }
336 
337 int Communication::deserializePackage(const std::vector<uint8_t> &package_in, uint8_t &device_id, uint8_t &command) {
338  std::vector<int8_t> data;
339  return deserializePackage(package_in, device_id, command, data);
340 }
341 
342 int Communication::deserializePackage(const std::vector<uint8_t> &package_in, uint8_t &device_id, uint8_t &command, std::vector<int8_t> &data) {
343  if (package_in.size() < 6) {
344  return -1;
345  }
346  if (package_in.at(0) != ':' || package_in.at(1) != ':') {
347  return -1;
348  }
349  if (package_in.at(2) == 0) {
350  return -1;
351  }
352  if (package_in.at(4) == CMD_GET_INFO || package_in.at(4) == CMD_GET_PARAM_LIST) { // special case for very long packets that exceed 8bit length
353  if (package_in.at(3) != package_in.size()-4 && (static_cast<uint32_t>(package_in.at(3)) << 5) != package_in.size()-4) {
354  return -1;
355  }
356  } else { // all common commands
357  if (package_in.at(3) != package_in.size()-4) {
358  return -1;
359  }
360  }
361  if (package_in.back() != checksum(package_in, package_in.size()-1)) {
362  return -1;
363  }
364  device_id = package_in.at(2);
365  command = package_in.at(4);
366  data.clear();
367  data.insert(std::end(data), std::begin(package_in)+5, std::end(package_in)-1);
368 
369  return package_in.size();
370 }
371 
372 int Communication::readPackage(const std::string &serial_port_name, uint8_t &device_id, uint8_t &command) {
373  std::vector<uint8_t> package_in;
374  if (readPackage(serial_port_name, package_in) < 0) {
375  return -1;
376  }
377  return deserializePackage(package_in, device_id, command);
378 }
379 
380 int Communication::readPackage(const std::string &serial_port_name, uint8_t &device_id, uint8_t &command, std::vector<int8_t> &data) {
381  std::vector<uint8_t> package_in;
382  if (readPackage(serial_port_name, package_in) < 0) {
383  return -1;
384  }
385  return deserializePackage(package_in, device_id, command, data);
386 }
387 
388 int Communication::readPackage(const std::string &serial_port_name, std::vector<uint8_t> &package_in) {
389  package_in.clear();
390  try {
391  serial_ports_.at(serial_port_name)->read(package_in, 4);
392  if (package_in.size() != 4) {
393  serial_ports_.at(serial_port_name)->flush();
394  return -1;
395  }
396  if (package_in.at(0) != ':' || package_in.at(1) != ':') {
397  serial_ports_.at(serial_port_name)->flush();
398  return -1;
399  }
400  serial_ports_.at(serial_port_name)->read(package_in, package_in.at(3));
401 
402  // special case for very long packets that exceed 8bit length
403  if (package_in.size() > 3 && (package_in.at(4) == CMD_GET_INFO || (package_in.at(4) == CMD_GET_PARAM_LIST && package_in.size() > 7))) {
404  int special_packet_length = package_in.at(3) << 5; // multiple of 32
405  serial_ports_.at(serial_port_name)->read(package_in, special_packet_length - package_in.at(3)); // already read package_in.at(3) bytes
406  }
407  } catch (...) {
408  return -1;
409  }
410  return package_in.size();
411 }
412 
413 int Communication::serializePackage(uint8_t device_id, uint8_t command, std::vector<uint8_t> &package_out) {
414  std::vector<int8_t> data;
415  return serializePackage(device_id, command, data, package_out);
416 }
417 
418 int Communication::serializePackage(uint8_t device_id, uint8_t command, const std::vector<int8_t> &data, std::vector<uint8_t> &package_out) {
419  package_out.clear();
420  package_out.push_back(':');
421  package_out.push_back(':');
422  package_out.push_back(device_id);
423  package_out.push_back(2 + data.size());
424  package_out.push_back(command);
425  package_out.insert(std::end(package_out), std::begin(data), std::end(data));
426  package_out.push_back(checksum(package_out, package_out.size()));
427  return package_out.size();
428 }
429 
430 int Communication::writePackage(const std::string &serial_port_name, uint8_t device_id, uint8_t command) {
431  std::vector<uint8_t> package_out;
432  serializePackage(device_id, command, package_out);
433  return writePackage(serial_port_name, package_out);
434 }
435 
436 int Communication::writePackage(const std::string &serial_port_name, uint8_t device_id, uint8_t command, const std::vector<int8_t> &data) {
437  std::vector<uint8_t> package_out;
438  serializePackage(device_id, command, data, package_out);
439  return writePackage(serial_port_name, package_out);
440 }
441 
442 int Communication::writePackage(const std::string &serial_port_name, const std::vector<uint8_t> &package_out) {
443  try {
444  if (serial_ports_.at(serial_port_name)->write(package_out) != package_out.size()) {
445  return -1;
446  }
447  } catch (...) {
448  return -1;
449  }
450  return package_out.size();
451 }
452 
453 uint8_t Communication::checksum(const std::vector<uint8_t> &data, uint32_t size) {
454  uint8_t checksum = 0x00;
455  if (data.size() >= size) {
456  for (uint32_t i=4; i<size; i++) { // exclude first 4 bytes for backward compatibility
457  checksum = checksum ^ data.at(i);
458  }
459  }
460  return checksum;
461 }
462 
463 bool Communication::isInSerialPorts(const std::string &serial_port_name) {
464  return serial_ports_.count(serial_port_name);
465 }
466 
467 bool Communication::isInSerialPortsInfo(const std::string &serial_port_name) {
468  return serial_ports_info_.count(serial_port_name);
469 }
470 
472  : Communication(communication) {}
473 
475  : Communication(communication, timeout) {}
476 
477 int CommunicationLegacy::parsePackage(const std::string &serial_port_name, uint8_t device_id, uint8_t command, std::vector<int8_t> &data_in) {
478  data_in.clear();
479  uint8_t device_id_in = 0;
480  uint8_t command_in = 0;
481  std::vector<int8_t> data_in_buffer;
482 
483  // works only for non-broadcast commands
484  if (!device_id) {
485  return -1;
486  }
487 
488  while (readPackage(serial_port_name, device_id_in, command_in, data_in_buffer) > 0) {
489  //WARN: this is ugly because it can lead to unwanted command parsing on CMD_INIT_MEM, CMD_RESTORE_PARAMS or CMD_GET_PARAM_LIST (especially this that is used for many things!)
490  if (device_id != device_id_in && (command != CMD_INIT_MEM && command != CMD_RESTORE_PARAMS && (command != CMD_GET_PARAM_LIST || data_in_buffer.size() != 1))) { // id and id_in can differ on CMD_INIT_MEM or CMD_RESTORE_PARAMS (and also with CMD_GET_PARAM_LIST when changing the device ID)
491  continue;
492  }
493  //WARN: ACK messages do not carry the command info on legacy devices
495  data_in = data_in_buffer;
496  if (device_id != device_id_in) {
497  data_in.push_back(device_id_in); // ugly fix to pass the new id to the caller (data_in_buffer is only the ACK response in these cases)
498  }
499  return data_in.size();
500  }
501  }
502  return -1;
503 }
504 
505 int CommunicationLegacy::sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, uint8_t max_repeats, const std::vector<int8_t> &data_out, std::vector<int8_t> &data_in) {
506  uint8_t repeats = 0;
507  data_in.clear();
508 
509  while (repeats <= max_repeats) {
510  if (sendCommand(serial_port_name, device_id, command, data_out) < 0) {
511  repeats++;
512  continue;
513  }
514 
515  if (command == CMD_STORE_PARAMS || command == CMD_STORE_DEFAULT_PARAMS) { // writing to EEPROM takes a while
516  std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 100ms should be enough for legacy firmware which write less bytes in EEPROM
517  }
518 
519  // CMD_GET_PARAM_LIST and CMD_GET_INFO packages size exceeds uint8 max value and require a special parsing method
520  if ((command == CMD_GET_PARAM_LIST && data_out.size() == 2) || command == CMD_GET_INFO) {
521  std::vector<uint8_t> package_in;
522  std::this_thread::sleep_for(std::chrono::milliseconds(50));
523  if (readLongPackage(serial_port_name, package_in) > 0) {
524  if (command == CMD_GET_PARAM_LIST) { // CMD_GET_INFO is pure ASCII package without packet info (there is no need to trim it)
525  package_in.erase(package_in.begin(), package_in.begin()+5); // 5 bytes that need to be filtered out (:|:|<ID>|<LEN>|<CMD>)
526  package_in.erase(package_in.end()-1); // one checksum byte that need to be filtered out
527  }
528  data_in = std::vector<int8_t>(std::begin(package_in), std::end(package_in));
529  break;
530  }
531  } else if (command == CMD_GET_PARAM_LIST) { // set param did non have ACK on legacy devices...
532  data_in.push_back(1); // fake ACK because legacy devices do not provide ACK on set param
533  break;
534  } else { // all other commands
535  std::vector<int8_t> packages_in;
536  if (parsePackage(serial_port_name, device_id, command, packages_in) >= 0) {
537  data_in = packages_in;
538  break;
539  }
540  }
541 
542  repeats++;
543  }
544 
545  return repeats <= max_repeats ? data_in.size() : -1;
546 }
547 
548 int CommunicationLegacy::deserializePackage(const std::vector<uint8_t> &package_in, uint8_t &device_id, uint8_t &command, std::vector<int8_t> &data) {
549  if (package_in.size() < 6) {
550  return -1;
551  }
552  if (package_in.at(0) != ':' || package_in.at(1) != ':') {
553  return -1;
554  }
555  if (package_in.at(2) == 0) {
556  return -1;
557  }
558  if (package_in.at(4) != CMD_GET_INFO && (package_in.at(4) != CMD_GET_PARAM_LIST || package_in.size() <= 7)) { // cannot check size for very long packets that exceed 8bit length
559  if (package_in.at(3) != package_in.size()-4) {
560  return -1;
561  }
562  }
563  if (package_in.back() != checksum(package_in, package_in.size()-1)) {
564  return -1;
565  }
566  device_id = package_in.at(2);
567  command = package_in.at(4);
568  data.clear();
569  data.insert(std::end(data), std::begin(package_in)+5, std::end(package_in)-1);
570 
571  return package_in.size();
572 }
573 
574 int CommunicationLegacy::readLongPackage(const std::string &serial_port_name, std::vector<uint8_t> &package_in) {
575  package_in.clear();
576  try {
577  serial_ports_.at(serial_port_name)->read(package_in, 5000);
578  } catch (...) {
579  return -1;
580  }
581  return package_in.size();
582 }
583 
584 int CommunicationLegacy::readPackage(const std::string &serial_port_name, uint8_t &device_id, uint8_t &command, std::vector<int8_t> &data) {
585  std::vector<uint8_t> package_in;
586  if (readPackage(serial_port_name, package_in) < 0) {
587  return -1;
588  }
589  return deserializePackage(package_in, device_id, command, data);
590 }
591 
592 int CommunicationLegacy::readPackage(const std::string &serial_port_name, std::vector<uint8_t> &package_in) {
593  package_in.clear();
594  try {
595  serial_ports_.at(serial_port_name)->read(package_in, 4);
596  if (package_in.size() != 4) {
597  serial_ports_.at(serial_port_name)->flush();
598  return -1;
599  }
600  if (package_in.at(0) != ':' || package_in.at(1) != ':') {
601  serial_ports_.at(serial_port_name)->flush();
602  return -1;
603  }
604  serial_ports_.at(serial_port_name)->read(package_in, package_in.at(3));
605  } catch (...) {
606  return -1;
607  }
608  return package_in.size();
609 }
610 
611 Device::Device(std::shared_ptr<Communication> communication, std::string name, std::string serial_port, uint8_t id)
612  : Device(std::move(communication), std::move(name), std::move(serial_port), id, true, std::make_unique<Params>()) {}
613 
614 Device::Device(std::shared_ptr<Communication> communication, std::string name, std::string serial_port, uint8_t id, bool init_params)
615  : Device(std::move(communication), std::move(name), std::move(serial_port), id, init_params, std::make_unique<Params>()) {}
616 
617 Device::Device(std::shared_ptr<Communication> communication, std::string name, std::string serial_port, uint8_t id, bool init_params, std::unique_ptr<Params> params)
618  : name_(std::move(name)),
619  serial_port_(std::move(serial_port)),
620  params_(std::move(params)),
621  communication_(std::move(communication)) {
622  params_->id = id;
623  if (init_params) {
624  std::vector<int8_t> param_buffer;
625  if (getParameters(id, param_buffer) != 0) {
626  throw std::runtime_error("failure during getParameters()");
627  }
628  params_->initParams(param_buffer);
629  if (params_->id != id) {
630  throw std::runtime_error("failure during initParams()");
631  }
632  }
633 }
634 
636  return communication_->sendCommandAndParse(serial_port_, params_->id, CMD_PING);
637 }
638 
639 int Device::getControlReferences(std::vector<int16_t> &control_references) {
640  std::vector<int8_t> data_in;
641  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_INPUTS, data_in) < 0) {
642  return -1;
643  }
644  control_references = Communication::vectorCastAndSwap<int16_t>(data_in);
645  return 0;
646 }
647 
648 int Device::getCurrents(std::vector<int16_t> &currents) {
649  std::vector<int8_t> data_in;
650  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_CURRENTS, data_in) < 0) {
651  return -1;
652  }
653  currents = Communication::vectorCastAndSwap<int16_t>(data_in);
654  return 0;
655 }
656 
657 int Device::getCurrentsAndPositions(std::vector<int16_t> &currents,
658  std::vector<int16_t> &positions) {
659  std::vector<int8_t> data_in;
660  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_CURR_AND_MEAS, data_in) < 0) {
661  return -1;
662  }
663  auto currents_and_positions = Communication::vectorCastAndSwap<int16_t>(data_in);
664  currents = std::vector<int16_t>(currents_and_positions.begin(), currents_and_positions.begin()+2);
665  positions = std::vector<int16_t>(currents_and_positions.begin()+2, currents_and_positions.end());
666  return 0;
667 }
668 
669 int Device::getPositions(std::vector<int16_t> &positions) {
670  std::vector<int8_t> data_in;
671  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_MEASUREMENTS, data_in) < 0) {
672  return -1;
673  }
674  positions = Communication::vectorCastAndSwap<int16_t>(data_in);
675  return 0;
676 }
677 
678 int Device::getVelocities(std::vector<int16_t> &velocities) {
679  std::vector<int8_t> data_in;
680  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_VELOCITIES, data_in) < 0) {
681  return -1;
682  }
683  velocities = Communication::vectorCastAndSwap<int16_t>(data_in);
684  return 0;
685 }
686 
687 int Device::getAccelerations(std::vector<int16_t> &accelerations) {
688  std::vector<int8_t> data_in;
689  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_ACCEL, data_in) < 0) {
690  return -1;
691  }
692  accelerations = Communication::vectorCastAndSwap<int16_t>(data_in);
693  return 0;
694 }
695 
696 int Device::getMotorStates(bool &motor_state) {
697  std::vector<int8_t> data_in;
698  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_ACTIVATE, data_in) < 0) {
699  return -1;
700  }
701  if (data_in.size() != 1 || (data_in.front() != 0x03 && data_in.front() != 0x00)) {
702  return -1;
703  }
704  motor_state = data_in.front() == 0x03;
705  return 0;
706 }
707 
708 int Device::getCycleTime(int16_t &cycle_time) {
709  std::vector<int8_t> data_in;
710  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_CYCLE_TIME, data_in) < 0) {
711  return -1;
712  }
713  cycle_time = Communication::vectorCastAndSwap<int16_t>(data_in).at(1);
714  return 0;
715 }
716 
717 int Device::setControlReferences(const std::vector<int16_t> &control_references) {
718  auto const data_out = Communication::vectorSwapAndCast<int8_t>(control_references);
719  if (communication_->sendCommand(serial_port_, params_->id, CMD_SET_INPUTS, data_out) < 0) {
720  return -1;
721  }
722  return 0;
723 }
724 
725 int Device::setControlReferencesAndWait(const std::vector<int16_t> &control_references) {
726  auto const data_out = Communication::vectorSwapAndCast<int8_t>(control_references);
727  std::vector<int8_t> data_in;
728  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_SET_INPUTS_ACK, data_out, data_in) < 0) {
729  return -1;
730  }
731  if (data_in.size() < 0) {
732  return data_in.size();
733  }
734  return 0;
735 }
736 
737 int Device::setMotorStates(bool motor_state) {
738  uint8_t data_out = motor_state ? 0x03 : 0x00;
739  if (communication_->sendCommand(serial_port_, params_->id, CMD_ACTIVATE, std::vector<int8_t>(1, data_out)) < 0) {
740  return -1;
741  }
742  return 0;
743 }
744 
745 int Device::getInfo(std::string &info) {
746  return getInfo(0, info);
747 }
748 
749 int Device::getInfo(uint16_t info_type, std::string &info) {
750  std::vector<int8_t> data_in;
751  const std::vector<int8_t> data_out = Communication::vectorSwapAndCast<int8_t, uint16_t>({info_type});
752  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_INFO, data_out, data_in) < 0) {
753  return -1;
754  }
755  info.assign(data_in.begin(), data_in.end());
756  return 0;
757 }
758 
759 int Device::getParameters(std::vector<int8_t> &param_buffer) {
760  return getParameters(params_->id, param_buffer);
761 }
762 
763 int Device::getParameters(uint8_t id, std::vector<int8_t> &param_buffer) {
764  param_buffer.clear();
765  const std::vector<int8_t> data_out = Communication::vectorSwapAndCast<int8_t, uint16_t>({0x0000});
766  if (communication_->sendCommandAndParse(serial_port_, id, CMD_GET_PARAM_LIST, data_out, param_buffer) < 0) {
767  return -1;
768  }
769  return 0;
770 }
771 
773  return getParamId(params_->id);
774 }
775 
776 int Device::getParamId(uint8_t &id) {
777  std::vector<int8_t> param_buffer;
778  if (getParameters(param_buffer) != 0) {
779  return -1;
780  }
781  Params::getParameter<uint8_t>(1, param_buffer, id);
782  return 0;
783 }
784 
786  return getParamPositionPID(params_->position_pid);
787 }
788 
789 int Device::getParamPositionPID(std::vector<float> &position_pid) {
790  std::vector<int8_t> param_buffer;
791  if (getParameters(param_buffer) != 0) {
792  return -1;
793  }
794  Params::getParameter<float>(2, param_buffer, position_pid);
795  return 0;
796 }
797 
799  return getParamCurrentPID(params_->current_pid);
800 }
801 
802 int Device::getParamCurrentPID(std::vector<float> &current_pid) {
803  std::vector<int8_t> param_buffer;
804  if (getParameters(param_buffer) != 0) {
805  return -1;
806  }
807  Params::getParameter<float>(3, param_buffer, current_pid);
808  return 0;
809 }
810 
812  return getParamStartupActivation(params_->startup_activation);
813 }
814 
815 int Device::getParamStartupActivation(uint8_t &startup_activation) {
816  std::vector<int8_t> param_buffer;
817  if (getParameters(param_buffer) != 0) {
818  return -1;
819  }
820  Params::getParameter<uint8_t>(4, param_buffer, startup_activation);
821  return 0;
822 }
823 
825  return getParamInputMode(params_->input_mode);
826 }
827 
828 int Device::getParamInputMode(uint8_t &input_mode) {
829  std::vector<int8_t> param_buffer;
830  if (getParameters(param_buffer) != 0) {
831  return -1;
832  }
833  Params::getParameter<uint8_t>(5, param_buffer, input_mode);
834  return 0;
835 }
836 
838  return getParamControlMode(params_->control_mode);
839 }
840 
841 int Device::getParamControlMode(uint8_t &control_mode) {
842  std::vector<int8_t> param_buffer;
843  if (getParameters(param_buffer) != 0) {
844  return -1;
845  }
846  Params::getParameter<uint8_t>(6, param_buffer, control_mode);
847  return 0;
848 }
849 
851  return getParamEncoderResolutions(params_->encoder_resolutions);
852 }
853 
854 int Device::getParamEncoderResolutions(std::vector<uint8_t> &encoder_resolutions) {
855  std::vector<int8_t> param_buffer;
856  if (getParameters(param_buffer) != 0) {
857  return -1;
858  }
859  Params::getParameter<uint8_t>(7, param_buffer, encoder_resolutions);
860  return 0;
861 }
862 
864  return getParamEncoderOffsets(params_->encoder_offsets);
865 }
866 
867 int Device::getParamEncoderOffsets(std::vector<int16_t> &encoder_offsets) {
868  std::vector<int8_t> param_buffer;
869  if (getParameters(param_buffer) != 0) {
870  return -1;
871  }
872  Params::getParameter<int16_t>(8, param_buffer, encoder_offsets);
873  return 0;
874 }
875 
877  return getParamEncoderMultipliers(params_->encoder_multipliers);
878 }
879 
880 int Device::getParamEncoderMultipliers(std::vector<float> &encoder_multipliers) {
881  std::vector<int8_t> param_buffer;
882  if (getParameters(param_buffer) != 0) {
883  return -1;
884  }
885  Params::getParameter<float>(9, param_buffer, encoder_multipliers);
886  return 0;
887 }
888 
890  return getParamUsePositionLimits(params_->use_position_limits);
891 }
892 
893 int Device::getParamUsePositionLimits(uint8_t &use_position_limits) {
894  std::vector<int8_t> param_buffer;
895  if (getParameters(param_buffer) != 0) {
896  return -1;
897  }
898  Params::getParameter<uint8_t>(10, param_buffer, use_position_limits);
899  return 0;
900 }
901 
903  return getParamPositionLimits(params_->position_limits);
904 }
905 
906 int Device::getParamPositionLimits(std::vector<int32_t> &position_limits) {
907  std::vector<int8_t> param_buffer;
908  if (getParameters(param_buffer) != 0) {
909  return -1;
910  }
911  Params::getParameter<int32_t>(11, param_buffer, position_limits);
912  return 0;
913 }
914 
916  return getParamPositionMaxSteps(params_->position_max_steps);
917 }
918 
919 int Device::getParamPositionMaxSteps(std::vector<int32_t> &position_max_steps) {
920  std::vector<int8_t> param_buffer;
921  if (getParameters(param_buffer) != 0) {
922  return -1;
923  }
924  Params::getParameter<int32_t>(12, param_buffer, position_max_steps);
925  return 0;
926 }
927 
929  return getParamCurrentLimit(params_->current_limit);
930 }
931 
932 int Device::getParamCurrentLimit(int16_t &current_limit) {
933  std::vector<int8_t> param_buffer;
934  if (getParameters(param_buffer) != 0) {
935  return -1;
936  }
937  Params::getParameter<int16_t>(13, param_buffer, current_limit);
938  return 0;
939 }
940 
941 int Device::setParameter(uint16_t param_type, const std::vector<int8_t> &param_data) {
942  bool motor_state = true;
943  if (getMotorStates(motor_state) || motor_state) {
944  return -1; // motor must be stopped while changing parameters
945  }
946 
947  std::vector<int8_t> data_in;
948  std::vector<int8_t> param_payload = Communication::vectorSwapAndCast<int8_t, uint16_t>({param_type});
949  param_payload.insert(param_payload.end(), param_data.begin(), param_data.end());
950  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_GET_PARAM_LIST, param_payload, data_in) < 0) {
951  return -1;
952  }
953  if (data_in.size() > 0 && data_in.front() != 1) { // check ACK
954  return -2;
955  }
956  return 0;
957 }
958 
959 int Device::setParamId(uint8_t id) {
960  int set_fail = setParameter(1, Communication::vectorSwapAndCast<int8_t, uint8_t>({id}));
961  if (!set_fail) {
962  params_->id = id;
963  }
964  return set_fail;
965 }
966 
967 int Device::setParamPositionPID(const std::vector<float> &position_pid) {
968  int set_fail = setParameter(2, Communication::vectorSwapAndCast<int8_t, float>(position_pid));
969  if (!set_fail) {
970  params_->position_pid = position_pid;
971  }
972  return set_fail;
973 }
974 
975 int Device::setParamCurrentPID(const std::vector<float> &current_pid) {
976  int set_fail = setParameter(3, Communication::vectorSwapAndCast<int8_t, float>(current_pid));
977  if (!set_fail) {
978  params_->current_pid = current_pid;
979  }
980  return set_fail;
981 }
982 
983 int Device::setParamStartupActivation(bool startup_activation) {
984  int set_fail = setParameter(4, Communication::vectorSwapAndCast<int8_t, uint8_t>({startup_activation}));
985  if (!set_fail) {
986  params_->startup_activation = startup_activation;
987  }
988  return set_fail;
989 }
990 
991 int Device::setParamInputMode(uint8_t input_mode) {
992  int set_fail = setParameter(5, Communication::vectorSwapAndCast<int8_t, uint8_t>({input_mode}));
993  if (!set_fail) {
994  params_->input_mode = input_mode;
995  }
996  return set_fail;
997 }
998 
999 int Device::setParamControlMode(uint8_t control_mode) {
1000  int set_fail = setParameter(6, Communication::vectorSwapAndCast<int8_t, uint8_t>({control_mode}));
1001  if (!set_fail) {
1002  params_->control_mode = control_mode;
1003  }
1004  return set_fail;
1005 }
1006 
1007 int Device::setParamEncoderResolutions(const std::vector<uint8_t> &encoder_resolutions) {
1008  int set_fail = setParameter(7, Communication::vectorSwapAndCast<int8_t, uint8_t>(encoder_resolutions));
1009  if (!set_fail) {
1010  params_->encoder_resolutions = encoder_resolutions;
1011  }
1012  return set_fail;
1013 }
1014 
1015 int Device::setParamEncoderOffsets(const std::vector<int16_t> &encoder_offsets) {
1016  int set_fail = setParameter(8, Communication::vectorSwapAndCast<int8_t, int16_t>(encoder_offsets));
1017  if (!set_fail) {
1018  params_->encoder_offsets = encoder_offsets;
1019  }
1020  return set_fail;
1021 }
1022 
1023 int Device::setParamEncoderMultipliers(const std::vector<float> &encoder_multipliers) {
1024  int set_fail = setParameter(9, Communication::vectorSwapAndCast<int8_t, float>(encoder_multipliers));
1025  if (!set_fail) {
1026  params_->encoder_multipliers = encoder_multipliers;
1027  }
1028  return set_fail;
1029 }
1030 
1031 int Device::setParamUsePositionLimits(bool use_position_limits) {
1032  int set_fail = setParameter(10, Communication::vectorSwapAndCast<int8_t, uint8_t>({use_position_limits}));
1033  if (!set_fail) {
1034  params_->use_position_limits = use_position_limits;
1035  }
1036  return set_fail;
1037 }
1038 
1039 int Device::setParamPositionLimits(const std::vector<int32_t> &position_limits) {
1040  int set_fail = setParameter(11, Communication::vectorSwapAndCast<int8_t, int32_t>(position_limits));
1041  if (!set_fail) {
1042  params_->position_limits = position_limits;
1043  }
1044  return set_fail;
1045 }
1046 
1047 int Device::setParamPositionMaxSteps(const std::vector<int32_t> &position_max_steps) {
1048  int set_fail = setParameter(12, Communication::vectorSwapAndCast<int8_t, int32_t>(position_max_steps));
1049  if (!set_fail) {
1050  params_->position_max_steps = position_max_steps;
1051  }
1052  return set_fail;
1053 }
1054 
1055 int Device::setParamCurrentLimit(int16_t current_limit) {
1056  int set_fail = setParameter(13, Communication::vectorSwapAndCast<int8_t, int16_t>({current_limit}));
1057  if (!set_fail) {
1058  params_->current_limit = current_limit;
1059  }
1060  return set_fail;
1061 }
1062 
1064  std::vector<int8_t> data_in;
1065  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_SET_ZEROS, data_in) < 0) {
1066  return -1;
1067  }
1068  return getParamEncoderOffsets(); // update intenal params_->encoder_offsets values
1069 }
1070 
1071 int Device::setParamBaudrate(uint8_t prescaler_divider) {
1072  const std::vector<int8_t> data_out = Communication::vectorSwapAndCast<int8_t, uint8_t>({prescaler_divider});
1073  if (communication_->sendCommand(serial_port_, params_->id, CMD_SET_BAUDRATE, data_out) < 0) {
1074  return -1;
1075  }
1076  return 0;
1077 }
1078 
1079 void Device::Params::initParams(const std::vector<int8_t> &param_buffer) {
1080  //FIXME: hardcoded input mode parameter id
1081  getParameter<uint8_t>(1, param_buffer, id);
1082  getParameter<float>(2, param_buffer, position_pid);
1083  getParameter<float>(3, param_buffer, current_pid);
1084  getParameter<uint8_t>(4, param_buffer, startup_activation);
1085  getParameter<uint8_t>(5, param_buffer, input_mode);
1086  getParameter<uint8_t>(6, param_buffer, control_mode);
1087  getParameter<uint8_t>(7, param_buffer, encoder_resolutions);
1088  getParameter<int16_t>(8, param_buffer, encoder_offsets);
1089  getParameter<float>(9, param_buffer, encoder_multipliers);
1090  getParameter<uint8_t>(10, param_buffer, use_position_limits);
1091  getParameter<int32_t>(11, param_buffer, position_limits);
1092  getParameter<int32_t>(12, param_buffer, position_max_steps);
1093  getParameter<int16_t>(13, param_buffer, current_limit);
1094 }
1095 
1097  std::vector<int8_t> data_in;
1098  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_INIT_MEM, data_in) < 0) {
1099  return -1;
1100  }
1101  if (data_in.size() > 0 && data_in.front() != 1) { // check ACK
1102  return -2;
1103  }
1104  if (data_in.size() > 0) { // if data_in is empty the ID is the same
1105  params_->id = data_in.back(); // the package contains the ACK + the new device id
1106  }
1107  return 0;
1108 }
1109 
1111  std::vector<int8_t> data_in;
1112  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_RESTORE_PARAMS, data_in) < 0) {
1113  return -1;
1114  }
1115  if (data_in.size() > 0 && data_in.front() != 1) { // check ACK
1116  return -2;
1117  }
1118  if (data_in.size() > 0) { // if data_in is empty the ID is the same
1119  params_->id = data_in.back(); // the package contains the ACK + the new device id
1120  }
1121  return 0;
1122 }
1123 
1125  std::vector<int8_t> data_in;
1126  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_STORE_PARAMS, data_in) < 0) {
1127  return -1;
1128  }
1129  if (data_in.size() > 0 && data_in.front() != 1) { // check ACK
1130  return -2;
1131  }
1132  return 0;
1133 }
1134 
1136  std::vector<int8_t> data_in;
1137  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_STORE_DEFAULT_PARAMS, data_in) < 0) {
1138  return -1;
1139  }
1140  if (data_in.size() > 0 && data_in.front() != 1) { // check ACK
1141  return -2;
1142  }
1143  return 0;
1144 }
1145 
1147  std::vector<int8_t> data_in;
1148  if (communication_->sendCommandAndParse(serial_port_, params_->id, CMD_BOOTLOADER, data_in) < 0) {
1149  return -1;
1150  }
1151  if (data_in.size() > 0 && data_in.front() != 1) { // check ACK
1152  return -2;
1153  }
1154  return 0;
1155 }
CMD_GET_INPUTS
@ CMD_GET_INPUTS
Command for getting reference inputs.
Definition: qbrobotics_research_commands.h:66
qbrobotics_research_api::Communication::closeSerialPort
virtual int closeSerialPort(const std::string &serial_port_name)
Close the serial port if it belongs to the opened port set.
Definition: qbrobotics_research_api.cpp:149
qbrobotics_research_api::Device::setParameter
virtual int setParameter(uint16_t param_type, const std::vector< int8_t > &param_data)
Set the Parameter specified by param_type with the values stored in param_data.
Definition: qbrobotics_research_api.cpp:941
qbrobotics_research_api::CommunicationLegacy::sendCommandAndParse
int sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command, uint8_t max_repeats, const std::vector< int8_t > &data_out, std::vector< int8_t > &data_in) override
Definition: qbrobotics_research_api.cpp:505
qbrobotics_research_api::Device::getParamEncoderResolutions
virtual int getParamEncoderResolutions()
Update the device encoder resolutions in the class variable param_.
Definition: qbrobotics_research_api.cpp:850
qbrobotics_research_api::Communication::serial_ports_
std::map< std::string, std::shared_ptr< serial::Serial > > serial_ports_
Definition: qbrobotics_research_api.h:235
CMD_GET_CURRENTS
@ CMD_GET_CURRENTS
Command for asking device's current measurements.
Definition: qbrobotics_research_commands.h:68
qbrobotics_research_api::Device::getParamId
virtual int getParamId()
Update the device ID in the class variable param_.
Definition: qbrobotics_research_api.cpp:772
qbrobotics_research_api::Communication::deserializePackage
virtual int deserializePackage(const std::vector< uint8_t > &package_in, uint8_t &device_id, uint8_t &command)
Definition: qbrobotics_research_api.cpp:337
qbrobotics_research_api::Communication::writePackage
virtual int writePackage(const std::string &serial_port_name, const std::vector< uint8_t > &package_out)
Definition: qbrobotics_research_api.cpp:442
qbrobotics_research_api::Device::getParameters
virtual int getParameters(std::vector< int8_t > &param_buffer)
Get the parameters from the device.
Definition: qbrobotics_research_api.cpp:759
CMD_INIT_MEM
@ CMD_INIT_MEM
Initialize the memory with the default values.
Definition: qbrobotics_research_commands.h:58
qbrobotics_research_api::CommunicationLegacy::readLongPackage
int readLongPackage(const std::string &serial_port_name, std::vector< uint8_t > &package_in)
Definition: qbrobotics_research_api.cpp:574
qbrobotics_research_api::Communication::openSerialPort
virtual int openSerialPort(const std::string &serial_port_name)
Open the serial communication on the given serial port.
Definition: qbrobotics_research_api.cpp:188
CMD_SET_INPUTS_ACK
@ CMD_SET_INPUTS_ACK
Command to set the device inputs and return an acknowledgment signal (needed for less comm.
Definition: qbrobotics_research_commands.h:84
serial
Definition: impl.h:56
qbrobotics_research_api::Device::Params::position_limits
std::vector< int32_t > position_limits
Definition: qbrobotics_research_api.h:309
qbrobotics_research_api::Communication::connected_devices_
std::map< std::string, std::vector< ConnectedDeviceInfo > > connected_devices_
Definition: qbrobotics_research_api.h:233
qbrobotics_research_api::Device::Params::position_max_steps
std::vector< int32_t > position_max_steps
Definition: qbrobotics_research_api.h:310
qbrobotics_research_api::Device::params_
std::shared_ptr< Params > params_
Definition: qbrobotics_research_api.h:852
qbrobotics_research_api::Device::Params::use_position_limits
uint8_t use_position_limits
Definition: qbrobotics_research_api.h:308
qbrobotics_research_api::Device::ping
virtual int ping()
Definition: qbrobotics_research_api.cpp:635
qbrobotics_research_api::Device::Params::current_pid
std::vector< float > current_pid
Definition: qbrobotics_research_api.h:301
qbrobotics_research_api::Device::setParamEncoderResolutions
virtual int setParamEncoderResolutions(const std::vector< uint8_t > &encoder_resolutions)
Set the encoder resolutions parameters of the device.
Definition: qbrobotics_research_api.cpp:1007
command
ROSLIB_DECL std::string command(const std::string &cmd)
CMD_GET_MEASUREMENTS
@ CMD_GET_MEASUREMENTS
Command for asking device's position measurements.
Definition: qbrobotics_research_commands.h:67
qbrobotics_research_api::Device::getCycleTime
virtual int getCycleTime(int16_t &cycle_time)
Definition: qbrobotics_research_api.cpp:708
CMD_GET_CURR_AND_MEAS
@ CMD_GET_CURR_AND_MEAS
Command for asking device's measurements and currents.
Definition: qbrobotics_research_commands.h:69
CMD_GET_CYCLE_TIME
@ CMD_GET_CYCLE_TIME
Command to get the device cycle time.
Definition: qbrobotics_research_commands.h:88
serial::Serial::Timeout
Definition: serial.h:101
CMD_HAND_CALIBRATE
@ CMD_HAND_CALIBRATE
Starts a series of opening and closures of the hand.
Definition: qbrobotics_research_commands.h:61
qbrobotics_research_api::Device::getParamControlMode
virtual int getParamControlMode()
Update the device control mode in the class variable param_.
Definition: qbrobotics_research_api.cpp:837
qbrobotics_research_api::Device::setParamEncoderOffsets
virtual int setParamEncoderOffsets(const std::vector< int16_t > &encoder_offsets)
Set the encoder offsets parameters of the device.
Definition: qbrobotics_research_api.cpp:1015
ACK_OK
@ ACK_OK
Definition: qbrobotics_research_commands.h:173
qbrobotics_research_api::Device::setBootloaderMode
virtual int setBootloaderMode()
Set the bootloader mode.
Definition: qbrobotics_research_api.cpp:1146
qbrobotics_research_api::Device::Params::control_mode
uint8_t control_mode
Definition: qbrobotics_research_api.h:304
CMD_PING
@ CMD_PING
Asks for a ping message.
Definition: qbrobotics_research_commands.h:47
qbrobotics_research_api::Device::Params::encoder_resolutions
std::vector< uint8_t > encoder_resolutions
Definition: qbrobotics_research_api.h:305
qbrobotics_research_api::Communication::serial_ports_baud_rate_
uint32_t serial_ports_baud_rate_
Definition: qbrobotics_research_api.h:237
qbrobotics_research_api::Device::restoreFactoryDataMemory
virtual int restoreFactoryDataMemory()
Restore factory parameter on 7.X.X firmware devices.
Definition: qbrobotics_research_api.cpp:1096
qbrobotics_research_api::Communication::isInSerialPorts
bool isInSerialPorts(const std::string &serial_port_name)
Definition: qbrobotics_research_api.cpp:463
qbrobotics_research_api
Definition: qbmove_research_api.h:33
qbrobotics_research_api::CommunicationLegacy::parsePackage
int parsePackage(const std::string &serial_port_name, uint8_t device_id, uint8_t command, std::vector< int8_t > &data_in) override
Definition: qbrobotics_research_api.cpp:477
qbrobotics_research_api::Device::getParamPositionLimits
virtual int getParamPositionLimits()
Update the position limits parameters in the class variable param_.
Definition: qbrobotics_research_api.cpp:902
qbrobotics_research_api::Device::getParamInputMode
virtual int getParamInputMode()
Get the input mode parameter in the class variable param_.
Definition: qbrobotics_research_api.cpp:824
qbrobotics_research_api::Device::setMotorStates
virtual int setMotorStates(bool motor_state)
Activate or deactivate the motor(s)
Definition: qbrobotics_research_api.cpp:737
qbrobotics_research_api::Device::storeUserDataMemory
virtual int storeUserDataMemory()
Store the changed parameters on 7.X.X firmware devices in user memory.
Definition: qbrobotics_research_api.cpp:1124
qbrobotics_research_api::Device::Params::input_mode
uint8_t input_mode
Definition: qbrobotics_research_api.h:303
qbrobotics_research_api::Device::storeFactoryDataMemory
virtual int storeFactoryDataMemory()
Store the changed parameters on 7.X.X firmware devices in factory memory.
Definition: qbrobotics_research_api.cpp:1135
qbrobotics_research_api::Device::serial_port_
std::string serial_port_
Definition: qbrobotics_research_api.h:851
qbrobotics_research_api::Device::getParamPositionPID
virtual int getParamPositionPID()
Update the device position PID parameters in the class variable param_.
Definition: qbrobotics_research_api.cpp:785
qbrobotics_research_api::Device::setParamControlMode
virtual int setParamControlMode(uint8_t control_mode)
Set the control mode parameter of the device.
Definition: qbrobotics_research_api.cpp:999
qbrobotics_research_api::Device::getParamEncoderOffsets
virtual int getParamEncoderOffsets()
Update the device encoder offsets in the class variable param_.
Definition: qbrobotics_research_api.cpp:863
qbrobotics_research_api::Device
General class that allow to get/set parameters from/to qbrobotics devices.
Definition: qbrobotics_research_api.h:268
qbrobotics_research_api::Communication::sendCommand
virtual int sendCommand(const std::string &serial_port_name, uint8_t device_id, uint8_t command)
Definition: qbrobotics_research_api.cpp:254
qbrobotics_research_api::Device::getParamPositionMaxSteps
virtual int getParamPositionMaxSteps()
Update the max step position parameters in the class variable param_.
Definition: qbrobotics_research_api.cpp:915
qbrobotics_research_api::Device::setParamInputMode
virtual int setParamInputMode(uint8_t input_mode)
Set the input mode parameter of the device.
Definition: qbrobotics_research_api.cpp:991
qbrobotics_research_api::Device::getParamCurrentPID
virtual int getParamCurrentPID()
Update the device current PID parameters in the class variable param_.
Definition: qbrobotics_research_api.cpp:798
qbrobotics_research_api::Device::communication_
std::shared_ptr< Communication > communication_
Definition: qbrobotics_research_api.h:853
qbrobotics_research_api::Device::getParamUsePositionLimits
virtual int getParamUsePositionLimits()
Update the the use of position limits in the class variable param_.
Definition: qbrobotics_research_api.cpp:889
CMD_BOOTLOADER
@ CMD_BOOTLOADER
Sets the bootloader modality to update the firmware.
Definition: qbrobotics_research_commands.h:57
qbrobotics_research_api::Device::restoreUserDataMemory
virtual int restoreUserDataMemory()
Restore user parameter on 7.X.X firmware devices.
Definition: qbrobotics_research_api.cpp:1110
qbrobotics_research_api.h
CMD_ACTIVATE
@ CMD_ACTIVATE
Command for activating/deactivating the device.
Definition: qbrobotics_research_commands.h:63
qbrobotics_research_api::Device::getControlReferences
virtual int getControlReferences(std::vector< int16_t > &control_references)
Get the reference command sent to the motor(s) of the device.
Definition: qbrobotics_research_api.cpp:639
qbrobotics_research_api::Device::getMotorStates
virtual int getMotorStates(bool &motor_state)
Get the device motor state.
Definition: qbrobotics_research_api.cpp:696
qbrobotics_research_api::Communication::isInSerialPortsInfo
bool isInSerialPortsInfo(const std::string &serial_port_name)
Definition: qbrobotics_research_api.cpp:467
qbrobotics_research_api::Device::setControlReferencesAndWait
virtual int setControlReferencesAndWait(const std::vector< int16_t > &control_references)
Set motor(s) control reference and wait for acknowledge - position[tick](only for legacy qbmoves)
Definition: qbrobotics_research_api.cpp:725
qbrobotics_research_api::Device::setParamCurrentPID
virtual int setParamCurrentPID(const std::vector< float > &current_pid)
Set the current PID parameters of the device.
Definition: qbrobotics_research_api.cpp:975
qbrobotics_research_api::Device::getInfo
virtual int getInfo(std::string &info)
Get all system information.
Definition: qbrobotics_research_api.cpp:745
qbrobotics_research_api::Device::setParamPositionPID
virtual int setParamPositionPID(const std::vector< float > &position_pid)
Set the position PID parameters of the device.
Definition: qbrobotics_research_api.cpp:967
qbrobotics_research_api::Device::setParamEncoderMultipliers
virtual int setParamEncoderMultipliers(const std::vector< float > &encoder_multipliers)
Set the encoder multipliers parameters of the device.
Definition: qbrobotics_research_api.cpp:1023
qbrobotics_research_api::Device::getVelocities
virtual int getVelocities(std::vector< int16_t > &velocities)
Get the motor(s) velocitie(s)
Definition: qbrobotics_research_api.cpp:678
qbrobotics_research_api::Communication::serial_ports_timeout_
serial::Serial::Timeout serial_ports_timeout_
Definition: qbrobotics_research_api.h:238
CMD_GET_VELOCITIES
@ CMD_GET_VELOCITIES
Command for asking device's velocity measurements.
Definition: qbrobotics_research_commands.h:72
CMD_STORE_DEFAULT_PARAMS
@ CMD_STORE_DEFAULT_PARAMS
Store current parameters as factory parameters.
Definition: qbrobotics_research_commands.h:50
qbrobotics_research_api::Communication::sendCommandBroadcast
virtual int sendCommandBroadcast(const std::string &serial_port_name, uint8_t command)
Definition: qbrobotics_research_api.cpp:326
qbrobotics_research_api::Device::Device
Device(std::shared_ptr< Communication > communication, std::string name, std::string serial_port, uint8_t id)
Definition: qbrobotics_research_api.cpp:611
qbrobotics_research_api::Device::Params::encoder_offsets
std::vector< int16_t > encoder_offsets
Definition: qbrobotics_research_api.h:306
qbrobotics_research_api::Device::getAccelerations
virtual int getAccelerations(std::vector< int16_t > &accelerations)
Get the motor(s) acceleration(s)
Definition: qbrobotics_research_api.cpp:687
qbrobotics_research_api::Communication::serial_ports_info_
std::map< std::string, serial::PortInfo > serial_ports_info_
Definition: qbrobotics_research_api.h:234
qbrobotics_research_api::Device::setParamId
virtual int setParamId(uint8_t id)
Set the ID of the device.
Definition: qbrobotics_research_api.cpp:959
CMD_RESTORE_PARAMS
@ CMD_RESTORE_PARAMS
Restore default factory parameters.
Definition: qbrobotics_research_commands.h:51
qbrobotics_research_api::CommunicationLegacy::deserializePackage
int deserializePackage(const std::vector< uint8_t > &package_in, uint8_t &device_id, uint8_t &command, std::vector< int8_t > &data) override
Definition: qbrobotics_research_api.cpp:548
qbrobotics_research_api::Device::setParamZeros
virtual int setParamZeros()
Set motor(s) zero(s) to actual encoder reading.
Definition: qbrobotics_research_api.cpp:1063
qbrobotics_research_api::Device::Params::startup_activation
uint8_t startup_activation
Definition: qbrobotics_research_api.h:302
qbrobotics_research_api::Device::getCurrents
virtual int getCurrents(std::vector< int16_t > &currents)
Get the device current(s) absorbed by the motor(s)
Definition: qbrobotics_research_api.cpp:648
qbrobotics_research_api::Device::setParamBaudrate
virtual int setParamBaudrate(uint8_t prescaler_divider)
Set the device baud rate.
Definition: qbrobotics_research_api.cpp:1071
qbrobotics_research_api::Device::getCurrentsAndPositions
virtual int getCurrentsAndPositions(std::vector< int16_t > &currents, std::vector< int16_t > &positions)
Get the device currents absorbed by the motor(s) and its/their position(s)
Definition: qbrobotics_research_api.cpp:657
qbrobotics_research_api::Communication::listSerialPorts
virtual int listSerialPorts(std::vector< serial::PortInfo > &serial_ports_info)
List all the serial ports with a qbrobotics device connected.
Definition: qbrobotics_research_api.cpp:59
CMD_SET_BAUDRATE
@ CMD_SET_BAUDRATE
Command for setting baud rate of communication.
Definition: qbrobotics_research_commands.h:80
qbrobotics_research_api::Device::Params
Manage qbrobotics devices parameters.
Definition: qbrobotics_research_api.h:274
CMD_STORE_PARAMS
@ CMD_STORE_PARAMS
Stores all parameters in memory and loads them.
Definition: qbrobotics_research_commands.h:49
CMD_SET_ZEROS
@ CMD_SET_ZEROS
Command for setting the encoders zero position.
Definition: qbrobotics_research_commands.h:48
qbrobotics_research_api::Device::Params::encoder_multipliers
std::vector< float > encoder_multipliers
Definition: qbrobotics_research_api.h:307
qbrobotics_research_api::Communication::parsePackage
virtual int parsePackage(const std::string &serial_port_name, uint8_t device_id, uint8_t command)
Definition: qbrobotics_research_api.cpp:221
CMD_CALIBRATE
@ CMD_CALIBRATE
Starts the stiffness calibration of the qbMove.
Definition: qbrobotics_research_commands.h:59
qbrobotics_research_api::Device::Params::initParams
virtual void initParams(const std::vector< int8_t > &param_buffer)
Definition: qbrobotics_research_api.cpp:1079
CMD_GET_INFO
@ CMD_GET_INFO
Asks for a string of information about.
Definition: qbrobotics_research_commands.h:52
qbrobotics_research_api::CommunicationLegacy::CommunicationLegacy
CommunicationLegacy()=default
CMD_SET_INPUTS
@ CMD_SET_INPUTS
Command for setting reference inputs.
Definition: qbrobotics_research_commands.h:65
std
qbrobotics_research_api::Device::getPositions
virtual int getPositions(std::vector< int16_t > &positions)
Get the Positions given by the encoders mounted on the device.
Definition: qbrobotics_research_api.cpp:669
qbrobotics_research_api::Device::setParamUsePositionLimits
virtual int setParamUsePositionLimits(bool use_position_limits)
Enable or disable the use of position limits.
Definition: qbrobotics_research_api.cpp:1031
qbrobotics_research_api::Device::setParamCurrentLimit
virtual int setParamCurrentLimit(int16_t current_limit)
Set the cerrent limit parameter of the device.
Definition: qbrobotics_research_api.cpp:1055
qbrobotics_research_api::Communication::serializePackage
virtual int serializePackage(uint8_t device_id, uint8_t command, std::vector< uint8_t > &package_out)
Definition: qbrobotics_research_api.cpp:413
qbrobotics_research_api::Device::Params::position_pid
std::vector< float > position_pid
Definition: qbrobotics_research_api.h:300
qbrobotics_research_api::Communication::Communication
Communication()
Definition: qbrobotics_research_api.cpp:36
CMD_GET_ACCEL
@ CMD_GET_ACCEL
Command for asking device's acceleration measurements.
Definition: qbrobotics_research_commands.h:74
CMD_GET_ACTIVATE
@ CMD_GET_ACTIVATE
Command for getting device activation state.
Definition: qbrobotics_research_commands.h:64
qbrobotics_research_api::Device::setParamStartupActivation
virtual int setParamStartupActivation(bool startup_activation)
Set the startup activation parameter of the device.
Definition: qbrobotics_research_api.cpp:983
qbrobotics_research_api::Device::getParamCurrentLimit
virtual int getParamCurrentLimit()
Update the current limits parameters in the class variable param_.
Definition: qbrobotics_research_api.cpp:928
qbrobotics_research_api::Communication::checksum
virtual uint8_t checksum(const std::vector< uint8_t > &data, uint32_t size)
Definition: qbrobotics_research_api.cpp:453
qbrobotics_research_api::Device::setParamPositionMaxSteps
virtual int setParamPositionMaxSteps(const std::vector< int32_t > &position_max_steps)
Set the position max steps parameters of the device.
Definition: qbrobotics_research_api.cpp:1047
qbrobotics_research_api::CommunicationLegacy::readPackage
int readPackage(const std::string &serial_port_name, uint8_t &device_id, uint8_t &command, std::vector< int8_t > &data) override
Definition: qbrobotics_research_api.cpp:584
qbrobotics_research_api::Communication::sendCommandAndParse
virtual int sendCommandAndParse(const std::string &serial_port_name, uint8_t device_id, uint8_t command)
Definition: qbrobotics_research_api.cpp:269
qbrobotics_research_api::Device::Params::current_limit
int16_t current_limit
Definition: qbrobotics_research_api.h:311
qbrobotics_research_api::Communication::listConnectedDevices
virtual int listConnectedDevices()
Definition: qbrobotics_research_api.cpp:95
qbrobotics_research_api::Device::getParamStartupActivation
virtual int getParamStartupActivation()
Update the startup activation parameter in the class variable param_.
Definition: qbrobotics_research_api.cpp:811
qbrobotics_research_api::Device::setParamPositionLimits
virtual int setParamPositionLimits(const std::vector< int32_t > &position_limits)
Set the position limits parameters of the device.
Definition: qbrobotics_research_api.cpp:1039
CMD_GET_PARAM_LIST
@ CMD_GET_PARAM_LIST
Command to get the parameters list or to set a defined value chosen by the use.
Definition: qbrobotics_research_commands.h:60
serial::getPortsInfo
int getPortsInfo(std::vector< PortInfo > &serial_ports)
qbrobotics_research_api::Communication::readPackage
virtual int readPackage(const std::string &serial_port_name, std::vector< uint8_t > &package_in)
Definition: qbrobotics_research_api.cpp:388
qbrobotics_research_api::Communication::createSerialPort
virtual int createSerialPort(const std::string &serial_port_name)
put in the class map serial_ports_ a newly created shared pointer Serial class that provides a portab...
Definition: qbrobotics_research_api.cpp:163
qbrobotics_research_api::Device::setControlReferences
virtual int setControlReferences(const std::vector< int16_t > &control_references)
Set motor(s) control reference - position[tick].
Definition: qbrobotics_research_api.cpp:717
qbrobotics_research_api::Communication
Class that handles the communication with 7.X.X firmware devices.
Definition: qbrobotics_research_api.h:50
qbrobotics_research_api::Device::getParamEncoderMultipliers
virtual int getParamEncoderMultipliers()
Update the device encoder multipliers in the class variable param_.
Definition: qbrobotics_research_api.cpp:876


qb_device_driver
Author(s): qbrobotics®
autogenerated on Thu Apr 27 2023 02:36:32