Skip to content

Commit 15882dc

Browse files
authored
[primary] Add new fields to ConfigurationData object (UniversalRobots#485)
The Configuration Data robot message got new fields in 5.25.1. This commits adds support for parsing them into the ConfigurationData object. The implementation only parses them if they are present.
1 parent 02540be commit 15882dc

3 files changed

Lines changed: 91 additions & 1 deletion

File tree

include/ur_client_library/primary/robot_state/configuration_data.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ class ConfigurationData : public RobotState
117117
int32_t controller_box_type_;
118118
int32_t robot_type_;
119119
int32_t robot_sub_type_;
120+
int16_t reserved_1_{ 0 };
121+
int16_t reserved_2_{ 0 };
120122
};
121123

122124
} // namespace primary_interface

src/primary/robot_state/configuration_data.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,15 @@ bool ConfigurationData::parseWith(comm::BinParser& bp)
8181
bp.parse(robot_type_);
8282
bp.parse(robot_sub_type_);
8383

84+
if (bp.checkSize<decltype(reserved_1_)>())
85+
{
86+
bp.parse(reserved_1_);
87+
}
88+
if (bp.checkSize<decltype(reserved_2_)>())
89+
{
90+
bp.parse(reserved_2_);
91+
}
92+
8493
return true;
8594
}
8695

@@ -147,4 +156,4 @@ std::string ConfigurationData::toString() const
147156
}
148157

149158
} // namespace primary_interface
150-
} // namespace urcl
159+
} // namespace urcl

tests/test_primary_parser.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,57 @@
2626
*/
2727
//----------------------------------------------------------------------
2828

29+
#include <cassert>
2930
#include <iostream>
31+
#include <vector>
3032
#include <gtest/gtest.h>
3133
#include <string.h>
3234

3335
#include <ur_client_library/comm/bin_parser.h>
36+
#include <ur_client_library/primary/package_header.h>
3437
#include <ur_client_library/primary/primary_parser.h>
38+
#include <ur_client_library/primary/robot_state/configuration_data.h>
3539
#include "ur_client_library/primary/robot_message/key_message.h"
3640

3741
using namespace urcl;
3842

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+
3980
/* First RobotState of UR5e from URSim v5.8
4081
*
4182
* This package contains:
@@ -549,6 +590,44 @@ TEST_F(PrimaryParserTest, parsing_safetymode_results_in_correct_string)
549590
}
550591
}
551592

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+
552631
int main(int argc, char* argv[])
553632
{
554633
::testing::InitGoogleTest(&argc, argv);

0 commit comments

Comments
 (0)