|
26 | 26 | */ |
27 | 27 | //---------------------------------------------------------------------- |
28 | 28 |
|
| 29 | +#include <cassert> |
29 | 30 | #include <iostream> |
| 31 | +#include <vector> |
30 | 32 | #include <gtest/gtest.h> |
31 | 33 | #include <string.h> |
32 | 34 |
|
33 | 35 | #include <ur_client_library/comm/bin_parser.h> |
| 36 | +#include <ur_client_library/primary/package_header.h> |
34 | 37 | #include <ur_client_library/primary/primary_parser.h> |
| 38 | +#include <ur_client_library/primary/robot_state/configuration_data.h> |
35 | 39 | #include "ur_client_library/primary/robot_message/key_message.h" |
36 | 40 |
|
37 | 41 | using namespace urcl; |
38 | 42 |
|
| 43 | +namespace |
| 44 | +{ |
| 45 | +// ConfigurationData payload before optional int16 reserved fields (older UR software). |
| 46 | +constexpr size_t kConfigurationDataPayloadBytes = 6 * 2 * sizeof(double) + // joint position limits |
| 47 | + 6 * 2 * sizeof(double) + // joint motion limits |
| 48 | + 5 * sizeof(double) + // v/a joint/tool defaults + eq_radius |
| 49 | + 4 * 6 * sizeof(double) + // dh_a, dh_d, dh_alpha, dh_theta |
| 50 | + 4 * sizeof(int32_t); // masterboard, controller, robot type, sub type |
| 51 | + |
| 52 | +static_assert(kConfigurationDataPayloadBytes == 440); |
| 53 | + |
| 54 | +std::vector<uint8_t> makeRobotStatePacketWithConfigurationSubmessage(const std::vector<uint8_t>& configuration_payload) |
| 55 | +{ |
| 56 | + const uint32_t sub_size = static_cast<uint32_t>(sizeof(uint32_t) + sizeof(uint8_t) + configuration_payload.size()); |
| 57 | + const uint32_t total_packet_size = static_cast<uint32_t>(sizeof(int32_t) + sizeof(uint8_t) + sub_size); |
| 58 | + |
| 59 | + std::vector<uint8_t> packet(total_packet_size); |
| 60 | + size_t offset = 0; |
| 61 | + packet[offset++] = static_cast<uint8_t>((total_packet_size >> 24) & 0xFF); |
| 62 | + packet[offset++] = static_cast<uint8_t>((total_packet_size >> 16) & 0xFF); |
| 63 | + packet[offset++] = static_cast<uint8_t>((total_packet_size >> 8) & 0xFF); |
| 64 | + packet[offset++] = static_cast<uint8_t>(total_packet_size & 0xFF); |
| 65 | + packet[offset++] = static_cast<uint8_t>(primary_interface::RobotPackageType::ROBOT_STATE); |
| 66 | + |
| 67 | + packet[offset++] = static_cast<uint8_t>((sub_size >> 24) & 0xFF); |
| 68 | + packet[offset++] = static_cast<uint8_t>((sub_size >> 16) & 0xFF); |
| 69 | + packet[offset++] = static_cast<uint8_t>((sub_size >> 8) & 0xFF); |
| 70 | + packet[offset++] = static_cast<uint8_t>(sub_size & 0xFF); |
| 71 | + packet[offset++] = static_cast<uint8_t>(primary_interface::RobotStateType::CONFIGURATION_DATA); |
| 72 | + |
| 73 | + memcpy(packet.data() + offset, configuration_payload.data(), configuration_payload.size()); |
| 74 | + offset += configuration_payload.size(); |
| 75 | + assert(offset == packet.size()); |
| 76 | + return packet; |
| 77 | +} |
| 78 | +} // namespace |
| 79 | + |
39 | 80 | /* First RobotState of UR5e from URSim v5.8 |
40 | 81 | * |
41 | 82 | * This package contains: |
@@ -549,6 +590,44 @@ TEST_F(PrimaryParserTest, parsing_safetymode_results_in_correct_string) |
549 | 590 | } |
550 | 591 | } |
551 | 592 |
|
| 593 | +TEST_F(PrimaryParserTest, parse_configuration_data_without_reserved_fields) |
| 594 | +{ |
| 595 | + std::vector<uint8_t> payload(kConfigurationDataPayloadBytes, 0); |
| 596 | + std::vector<uint8_t> packet = makeRobotStatePacketWithConfigurationSubmessage(payload); |
| 597 | + |
| 598 | + comm::BinParser bp(packet.data(), packet.size()); |
| 599 | + std::vector<std::unique_ptr<primary_interface::PrimaryPackage>> products; |
| 600 | + ASSERT_TRUE(parser_.parse(bp, products)); |
| 601 | + ASSERT_EQ(products.size(), 1u); |
| 602 | + |
| 603 | + auto* config = dynamic_cast<primary_interface::ConfigurationData*>(products[0].get()); |
| 604 | + ASSERT_NE(config, nullptr); |
| 605 | + EXPECT_EQ(config->reserved_1_, 0); |
| 606 | + EXPECT_EQ(config->reserved_2_, 0); |
| 607 | +} |
| 608 | + |
| 609 | +TEST_F(PrimaryParserTest, parse_configuration_data_with_reserved_fields) |
| 610 | +{ |
| 611 | + std::vector<uint8_t> payload(kConfigurationDataPayloadBytes, 0); |
| 612 | + // Big-endian int16 values appended after the legacy payload. |
| 613 | + payload.push_back(0x12); |
| 614 | + payload.push_back(0x34); |
| 615 | + payload.push_back(0x56); |
| 616 | + payload.push_back(0x78); |
| 617 | + |
| 618 | + std::vector<uint8_t> packet = makeRobotStatePacketWithConfigurationSubmessage(payload); |
| 619 | + |
| 620 | + comm::BinParser bp(packet.data(), packet.size()); |
| 621 | + std::vector<std::unique_ptr<primary_interface::PrimaryPackage>> products; |
| 622 | + ASSERT_TRUE(parser_.parse(bp, products)); |
| 623 | + ASSERT_EQ(products.size(), 1u); |
| 624 | + |
| 625 | + auto* config = dynamic_cast<primary_interface::ConfigurationData*>(products[0].get()); |
| 626 | + ASSERT_NE(config, nullptr); |
| 627 | + EXPECT_EQ(config->reserved_1_, static_cast<int16_t>(0x1234)); |
| 628 | + EXPECT_EQ(config->reserved_2_, static_cast<int16_t>(0x5678)); |
| 629 | +} |
| 630 | + |
552 | 631 | int main(int argc, char* argv[]) |
553 | 632 | { |
554 | 633 | ::testing::InitGoogleTest(&argc, argv); |
|
0 commit comments