46 : serial_ports_baud_rate_(baud_rate),
47 serial_ports_timeout_(timeout) {}
50 :
Communication(communication, communication.serial_ports_timeout_) {}
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) {}
60 serial_ports_info.clear();
62 std::vector<serial::PortInfo> connected_serial_ports;
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);
76 serial_ports_[serial_port.serial_port] = std::make_shared<serial::Serial>();
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()) {
92 return serial_ports_info.size();
97 int connected_devices = 0;
99 std::vector<ConnectedDeviceInfo> device_ids;
102 connected_devices += device_ids.size();
105 return connected_devices;
113 serial_ports_.at(serial_port_name)->setTimeout(short_timeout);
114 std::vector<int8_t> data_in;
116 std::vector<uint8_t> max_id({255, 50, 10, 10, 10});
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++) {
125 if (std::find_if(device_ids.begin(), device_ids.end(), [&device_id](
const auto& info){ return info.id == device_id; }) != device_ids.end()) {
130 device_ids.push_back({
static_cast<uint8_t
>(device_id)});
131 if (data_in.size() > 0) {
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);
142 std::sort(device_ids.begin(), device_ids.end(), [](
const auto& a,
const auto& b){ return a.id > b.id; });
146 return device_ids.size();
181 serial_ports_[serial_port_name] = std::make_shared<serial::Serial>(serial_port_name, baud_rate, timeout);
210 serial_ports_.at(serial_port_name)->setPort(serial_port_name);
222 std::vector<int8_t> data_in;
228 uint8_t device_id_in = 0;
229 uint8_t command_in = 0;
230 std::vector<int8_t> data_in_buffer;
237 while (
readPackage(serial_port_name, device_id_in, command_in, data_in_buffer) > 0) {
244 data_in = data_in_buffer;
245 if (device_id != device_id_in) {
246 data_in.push_back(device_id_in);
248 return data_in.size();
255 std::vector<int8_t> data_out;
259 int Communication::sendCommand(
const std::string &serial_port_name, uint8_t device_id, uint8_t command,
const std::vector<int8_t> &data_out) {
274 std::vector<int8_t> data_in, data_out;
283 std::vector<int8_t> data_out;
292 std::vector<int8_t> data_in;
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) {
304 while (repeats <= max_repeats) {
311 std::this_thread::sleep_for(std::chrono::milliseconds(600));
314 std::vector<int8_t> packages_in;
316 data_in = packages_in;
323 return repeats <= max_repeats ? data_in.size() : -1;
327 std::vector<int8_t> data_out;
338 std::vector<int8_t> data;
343 if (package_in.size() < 6) {
346 if (package_in.at(0) !=
':' || package_in.at(1) !=
':') {
349 if (package_in.at(2) == 0) {
353 if (package_in.at(3) != package_in.size()-4 && (
static_cast<uint32_t
>(package_in.at(3)) << 5) != package_in.size()-4) {
357 if (package_in.at(3) != package_in.size()-4) {
361 if (package_in.back() !=
checksum(package_in, package_in.size()-1)) {
364 device_id = package_in.at(2);
367 data.insert(std::end(data), std::begin(package_in)+5, std::end(package_in)-1);
369 return package_in.size();
373 std::vector<uint8_t> package_in;
374 if (
readPackage(serial_port_name, package_in) < 0) {
381 std::vector<uint8_t> package_in;
382 if (
readPackage(serial_port_name, package_in) < 0) {
392 if (package_in.size() != 4) {
396 if (package_in.at(0) !=
':' || package_in.at(1) !=
':') {
400 serial_ports_.at(serial_port_name)->read(package_in, package_in.at(3));
404 int special_packet_length = package_in.at(3) << 5;
405 serial_ports_.at(serial_port_name)->read(package_in, special_packet_length - package_in.at(3));
410 return package_in.size();
414 std::vector<int8_t> data;
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();
431 std::vector<uint8_t> package_out;
437 std::vector<uint8_t> package_out;
444 if (
serial_ports_.at(serial_port_name)->write(package_out) != package_out.size()) {
450 return package_out.size();
455 if (data.size() >= size) {
456 for (uint32_t i=4; i<size; i++) {
479 uint8_t device_id_in = 0;
480 uint8_t command_in = 0;
481 std::vector<int8_t> data_in_buffer;
488 while (
readPackage(serial_port_name, device_id_in, command_in, data_in_buffer) > 0) {
495 data_in = data_in_buffer;
496 if (device_id != device_id_in) {
497 data_in.push_back(device_id_in);
499 return data_in.size();
509 while (repeats <= max_repeats) {
516 std::this_thread::sleep_for(std::chrono::milliseconds(100));
521 std::vector<uint8_t> package_in;
522 std::this_thread::sleep_for(std::chrono::milliseconds(50));
525 package_in.erase(package_in.begin(), package_in.begin()+5);
526 package_in.erase(package_in.end()-1);
528 data_in = std::vector<int8_t>(std::begin(package_in), std::end(package_in));
532 data_in.push_back(1);
535 std::vector<int8_t> packages_in;
537 data_in = packages_in;
545 return repeats <= max_repeats ? data_in.size() : -1;
549 if (package_in.size() < 6) {
552 if (package_in.at(0) !=
':' || package_in.at(1) !=
':') {
555 if (package_in.at(2) == 0) {
559 if (package_in.at(3) != package_in.size()-4) {
563 if (package_in.back() !=
checksum(package_in, package_in.size()-1)) {
566 device_id = package_in.at(2);
569 data.insert(std::end(data), std::begin(package_in)+5, std::end(package_in)-1);
571 return package_in.size();
581 return package_in.size();
585 std::vector<uint8_t> package_in;
586 if (
readPackage(serial_port_name, package_in) < 0) {
596 if (package_in.size() != 4) {
600 if (package_in.at(0) !=
':' || package_in.at(1) !=
':') {
604 serial_ports_.at(serial_port_name)->read(package_in, package_in.at(3));
608 return package_in.size();
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>()) {}
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>()) {}
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)) {
624 std::vector<int8_t> param_buffer;
626 throw std::runtime_error(
"failure during getParameters()");
628 params_->initParams(param_buffer);
630 throw std::runtime_error(
"failure during initParams()");
640 std::vector<int8_t> data_in;
644 control_references = Communication::vectorCastAndSwap<int16_t>(data_in);
649 std::vector<int8_t> data_in;
653 currents = Communication::vectorCastAndSwap<int16_t>(data_in);
658 std::vector<int16_t> &positions) {
659 std::vector<int8_t> data_in;
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());
670 std::vector<int8_t> data_in;
674 positions = Communication::vectorCastAndSwap<int16_t>(data_in);
679 std::vector<int8_t> data_in;
683 velocities = Communication::vectorCastAndSwap<int16_t>(data_in);
688 std::vector<int8_t> data_in;
692 accelerations = Communication::vectorCastAndSwap<int16_t>(data_in);
697 std::vector<int8_t> data_in;
701 if (data_in.size() != 1 || (data_in.front() != 0x03 && data_in.front() != 0x00)) {
704 motor_state = data_in.front() == 0x03;
709 std::vector<int8_t> data_in;
713 cycle_time = Communication::vectorCastAndSwap<int16_t>(data_in).at(1);
718 auto const data_out = Communication::vectorSwapAndCast<int8_t>(control_references);
726 auto const data_out = Communication::vectorSwapAndCast<int8_t>(control_references);
727 std::vector<int8_t> data_in;
731 if (data_in.size() < 0) {
732 return data_in.size();
738 uint8_t data_out = motor_state ? 0x03 : 0x00;
750 std::vector<int8_t> data_in;
751 const std::vector<int8_t> data_out = Communication::vectorSwapAndCast<int8_t, uint16_t>({info_type});
755 info.assign(data_in.begin(), data_in.end());
764 param_buffer.clear();
765 const std::vector<int8_t> data_out = Communication::vectorSwapAndCast<int8_t, uint16_t>({0x0000});
777 std::vector<int8_t> param_buffer;
781 Params::getParameter<uint8_t>(1, param_buffer,
id);
790 std::vector<int8_t> param_buffer;
794 Params::getParameter<float>(2, param_buffer, position_pid);
803 std::vector<int8_t> param_buffer;
807 Params::getParameter<float>(3, param_buffer, current_pid);
816 std::vector<int8_t> param_buffer;
820 Params::getParameter<uint8_t>(4, param_buffer, startup_activation);
829 std::vector<int8_t> param_buffer;
833 Params::getParameter<uint8_t>(5, param_buffer, input_mode);
842 std::vector<int8_t> param_buffer;
846 Params::getParameter<uint8_t>(6, param_buffer, control_mode);
855 std::vector<int8_t> param_buffer;
859 Params::getParameter<uint8_t>(7, param_buffer, encoder_resolutions);
868 std::vector<int8_t> param_buffer;
872 Params::getParameter<int16_t>(8, param_buffer, encoder_offsets);
881 std::vector<int8_t> param_buffer;
885 Params::getParameter<float>(9, param_buffer, encoder_multipliers);
894 std::vector<int8_t> param_buffer;
898 Params::getParameter<uint8_t>(10, param_buffer, use_position_limits);
907 std::vector<int8_t> param_buffer;
911 Params::getParameter<int32_t>(11, param_buffer, position_limits);
920 std::vector<int8_t> param_buffer;
924 Params::getParameter<int32_t>(12, param_buffer, position_max_steps);
933 std::vector<int8_t> param_buffer;
937 Params::getParameter<int16_t>(13, param_buffer, current_limit);
942 bool motor_state =
true;
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());
953 if (data_in.size() > 0 && data_in.front() != 1) {
960 int set_fail =
setParameter(1, Communication::vectorSwapAndCast<int8_t, uint8_t>({
id}));
968 int set_fail =
setParameter(2, Communication::vectorSwapAndCast<int8_t, float>(position_pid));
970 params_->position_pid = position_pid;
976 int set_fail =
setParameter(3, Communication::vectorSwapAndCast<int8_t, float>(current_pid));
978 params_->current_pid = current_pid;
984 int set_fail =
setParameter(4, Communication::vectorSwapAndCast<int8_t, uint8_t>({startup_activation}));
986 params_->startup_activation = startup_activation;
992 int set_fail =
setParameter(5, Communication::vectorSwapAndCast<int8_t, uint8_t>({input_mode}));
994 params_->input_mode = input_mode;
1000 int set_fail =
setParameter(6, Communication::vectorSwapAndCast<int8_t, uint8_t>({control_mode}));
1002 params_->control_mode = control_mode;
1008 int set_fail =
setParameter(7, Communication::vectorSwapAndCast<int8_t, uint8_t>(encoder_resolutions));
1010 params_->encoder_resolutions = encoder_resolutions;
1016 int set_fail =
setParameter(8, Communication::vectorSwapAndCast<int8_t, int16_t>(encoder_offsets));
1018 params_->encoder_offsets = encoder_offsets;
1024 int set_fail =
setParameter(9, Communication::vectorSwapAndCast<int8_t, float>(encoder_multipliers));
1026 params_->encoder_multipliers = encoder_multipliers;
1032 int set_fail =
setParameter(10, Communication::vectorSwapAndCast<int8_t, uint8_t>({use_position_limits}));
1034 params_->use_position_limits = use_position_limits;
1040 int set_fail =
setParameter(11, Communication::vectorSwapAndCast<int8_t, int32_t>(position_limits));
1042 params_->position_limits = position_limits;
1048 int set_fail =
setParameter(12, Communication::vectorSwapAndCast<int8_t, int32_t>(position_max_steps));
1050 params_->position_max_steps = position_max_steps;
1056 int set_fail =
setParameter(13, Communication::vectorSwapAndCast<int8_t, int16_t>({current_limit}));
1058 params_->current_limit = current_limit;
1064 std::vector<int8_t> data_in;
1072 const std::vector<int8_t> data_out = Communication::vectorSwapAndCast<int8_t, uint8_t>({prescaler_divider});
1081 getParameter<uint8_t>(1, param_buffer,
id);
1083 getParameter<float>(3, param_buffer,
current_pid);
1085 getParameter<uint8_t>(5, param_buffer,
input_mode);
1097 std::vector<int8_t> data_in;
1101 if (data_in.size() > 0 && data_in.front() != 1) {
1104 if (data_in.size() > 0) {
1111 std::vector<int8_t> data_in;
1115 if (data_in.size() > 0 && data_in.front() != 1) {
1118 if (data_in.size() > 0) {
1125 std::vector<int8_t> data_in;
1129 if (data_in.size() > 0 && data_in.front() != 1) {
1136 std::vector<int8_t> data_in;
1140 if (data_in.size() > 0 && data_in.front() != 1) {
1147 std::vector<int8_t> data_in;
1151 if (data_in.size() > 0 && data_in.front() != 1) {