|
37 | 37 |
|
38 | 38 | #include "ur_controllers/gpio_controller.hpp" |
39 | 39 |
|
| 40 | +#include <cmath> |
40 | 41 | #include <string> |
41 | 42 |
|
42 | 43 | namespace ur_controllers |
@@ -160,6 +161,11 @@ controller_interface::InterfaceConfiguration ur_controllers::GPIOController::sta |
160 | 161 | // program running |
161 | 162 | config.names.emplace_back(tf_prefix + "gpio/program_running"); |
162 | 163 |
|
| 164 | + config.names.emplace_back(tf_prefix + "payload/mass"); |
| 165 | + config.names.emplace_back(tf_prefix + "payload/cog.x"); |
| 166 | + config.names.emplace_back(tf_prefix + "payload/cog.y"); |
| 167 | + config.names.emplace_back(tf_prefix + "payload/cog.z"); |
| 168 | + |
163 | 169 | return config; |
164 | 170 | } |
165 | 171 |
|
@@ -530,13 +536,25 @@ bool GPIOController::setPayload(const ur_msgs::srv::SetPayload::Request::SharedP |
530 | 536 |
|
531 | 537 | resp->success = static_cast<bool>(command_interfaces_[CommandInterfaces::PAYLOAD_ASYNC_SUCCESS].get_value()); |
532 | 538 |
|
533 | | - if (resp->success) { |
534 | | - RCLCPP_INFO(get_node()->get_logger(), "Payload has been set successfully"); |
535 | | - } else { |
| 539 | + if (!resp->success) { |
536 | 540 | RCLCPP_ERROR(get_node()->get_logger(), "Could not set the payload"); |
537 | 541 | return false; |
538 | 542 | } |
539 | 543 |
|
| 544 | + if (params_.verify_payload_on_set) { |
| 545 | + if (!waitForPayloadRtdeMatch(static_cast<double>(req->mass), req->center_of_gravity.x, req->center_of_gravity.y, |
| 546 | + req->center_of_gravity.z)) { |
| 547 | + RCLCPP_WARN(get_node()->get_logger(), "setPayload reported success but RTDE payload / payload_cog do not match " |
| 548 | + "the " |
| 549 | + "request yet. (This might " |
| 550 | + "happen when using the mocked interface.)"); |
| 551 | + resp->success = false; |
| 552 | + RCLCPP_ERROR(get_node()->get_logger(), "Payload RTDE verification failed"); |
| 553 | + return false; |
| 554 | + } |
| 555 | + |
| 556 | + RCLCPP_INFO(get_node()->get_logger(), "Payload has been set and verified against RTDE feedback"); |
| 557 | + } |
540 | 558 | return true; |
541 | 559 | } |
542 | 560 |
|
@@ -588,6 +606,26 @@ bool GPIOController::waitForAsyncCommand(std::function<double(void)> get_value) |
588 | 606 | return true; |
589 | 607 | } |
590 | 608 |
|
| 609 | +bool GPIOController::waitForPayloadRtdeMatch(double mass, double cx, double cy, double cz) |
| 610 | +{ |
| 611 | + constexpr double tol_mass = 1e-3; |
| 612 | + constexpr double tol_cog = 1e-4; |
| 613 | + const auto maximum_retries = params_.check_io_successfull_retries; |
| 614 | + |
| 615 | + for (int retries = 0; retries <= maximum_retries; ++retries) { |
| 616 | + const auto m = state_interfaces_[StateInterfaces::PAYLOAD_STATE_MASS].get_value(); |
| 617 | + const auto sx = state_interfaces_[StateInterfaces::PAYLOAD_STATE_COG_X].get_value(); |
| 618 | + const auto sy = state_interfaces_[StateInterfaces::PAYLOAD_STATE_COG_Y].get_value(); |
| 619 | + const auto sz = state_interfaces_[StateInterfaces::PAYLOAD_STATE_COG_Z].get_value(); |
| 620 | + if (std::abs(m - mass) <= tol_mass && std::abs(sx - cx) <= tol_cog && std::abs(sy - cy) <= tol_cog && |
| 621 | + std::abs(sz - cz) <= tol_cog) { |
| 622 | + return true; |
| 623 | + } |
| 624 | + std::this_thread::sleep_for(std::chrono::milliseconds(50)); |
| 625 | + } |
| 626 | + return false; |
| 627 | +} |
| 628 | + |
591 | 629 | } // namespace ur_controllers |
592 | 630 |
|
593 | 631 | #include "pluginlib/class_list_macros.hpp" |
|
0 commit comments