Skip to content

Commit c7a549e

Browse files
authored
1 parent abcc8a8 commit c7a549e

7 files changed

Lines changed: 514 additions & 18 deletions

File tree

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ add_library(urcl
3838
src/primary/robot_state/kinematics_info.cpp
3939
src/primary/robot_state/robot_mode_data.cpp
4040
src/primary/robot_state/configuration_data.cpp
41+
src/primary/robot_state/masterboard_data.cpp
4142
src/rtde/control_package_pause.cpp
4243
src/rtde/control_package_setup_inputs.cpp
4344
src/rtde/control_package_setup_outputs.cpp
@@ -190,4 +191,4 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/ros_package_pa
190191
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/ros_package_path.dsv DESTINATION share/${PROJECT_NAME}/hook)
191192
#### End iport ####
192193

193-
install(DIRECTORY resources DESTINATION share/${PROJECT_NAME})
194+
install(DIRECTORY resources DESTINATION share/${PROJECT_NAME})

include/ur_client_library/primary/abstract_primary_consumer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "ur_client_library/primary/robot_state/kinematics_info.h"
3737
#include "ur_client_library/primary/robot_state/robot_mode_data.h"
3838
#include "ur_client_library/primary/robot_state/configuration_data.h"
39+
#include "ur_client_library/primary/robot_state/masterboard_data.h"
3940
#include "ur_client_library/primary/robot_message/safety_mode_message.h"
4041

4142
namespace urcl
@@ -80,6 +81,7 @@ class AbstractPrimaryConsumer : public comm::IConsumer<PrimaryPackage>
8081
virtual bool consume(ErrorCodeMessage& pkg) = 0;
8182
virtual bool consume(RobotModeData& pkg) = 0;
8283
virtual bool consume(ConfigurationData& pkg) = 0;
84+
virtual bool consume(MasterboardData& pkg) = 0;
8385
virtual bool consume(SafetyModeMessage& pkg) = 0;
8486

8587
private:

include/ur_client_library/primary/primary_consumer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "ur_client_library/primary/abstract_primary_consumer.h"
3232
#include "ur_client_library/primary/robot_state/robot_mode_data.h"
33+
#include "ur_client_library/primary/robot_state/masterboard_data.h"
3334
#include "ur_client_library/ur/datatypes.h"
3435
#include "ur_client_library/ur/version_information.h"
3536

@@ -185,6 +186,19 @@ class PrimaryConsumer : public AbstractPrimaryConsumer
185186
return true;
186187
}
187188

189+
/*!
190+
* \brief Handle a MasterboardData package
191+
*
192+
* \param pkg MasterboardData
193+
*
194+
* \returns True
195+
*/
196+
virtual bool consume(MasterboardData&) override
197+
{
198+
// Nothing to do here for now.
199+
return true;
200+
}
201+
188202
/*!
189203
* \brief Set callback function which will be triggered whenever error code messages are received
190204
*

include/ur_client_library/primary/primary_parser.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include "ur_client_library/primary/robot_message/error_code_message.h"
3535
#include "ur_client_library/primary/robot_state/robot_mode_data.h"
3636
#include "ur_client_library/primary/robot_state/configuration_data.h"
37+
#include "ur_client_library/primary/robot_state/masterboard_data.h"
3738
#include "ur_client_library/primary/robot_message/safety_mode_message.h"
3839

3940
namespace urcl
@@ -209,10 +210,8 @@ class PrimaryParser : public comm::Parser<PrimaryPackage>
209210
{
210211
case RobotStateType::ROBOT_MODE_DATA:
211212
return new RobotModeData(type);
212-
213-
// return new rmd;
214-
// case robot_state_type::MASTERBOARD_DATA:
215-
// return new MBD;*/
213+
case RobotStateType::MASTERBOARD_DATA:
214+
return new MasterboardData(type);
216215
case RobotStateType::KINEMATICS_INFO:
217216
return new KinematicsInfo(type);
218217
case RobotStateType::CONFIGURATION_DATA:
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// -- BEGIN LICENSE BLOCK ----------------------------------------------
2+
// Copyright 2026 Universal Robots A/S
3+
//
4+
// Redistribution and use in source and binary forms, with or without
5+
// modification, are permitted provided that the following conditions are met:
6+
//
7+
// * Redistributions of source code must retain the above copyright
8+
// notice, this list of conditions and the following disclaimer.
9+
//
10+
// * Redistributions in binary form must reproduce the above copyright
11+
// notice, this list of conditions and the following disclaimer in the
12+
// documentation and/or other materials provided with the distribution.
13+
//
14+
// * Neither the name of the {copyright_holder} nor the names of its
15+
// contributors may be used to endorse or promote products derived from
16+
// this software without specific prior written permission.
17+
//
18+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
// POSSIBILITY OF SUCH DAMAGE.
29+
// -- END LICENSE BLOCK ------------------------------------------------
30+
31+
#ifndef UR_CLIENT_LIBRARY_MASTERBOARD_DATA_H_INCLUDED
32+
#define UR_CLIENT_LIBRARY_MASTERBOARD_DATA_H_INCLUDED
33+
34+
#include <bitset>
35+
36+
#include "ur_client_library/types.h"
37+
#include "ur_client_library/primary/robot_state.h"
38+
#include "ur_client_library/ur/datatypes.h"
39+
40+
namespace urcl
41+
{
42+
namespace primary_interface
43+
{
44+
/*!
45+
* \brief The MasterboardData class handles the masterboard data sub-package sent as part of the
46+
* Robot State message on the primary UR interface.
47+
*
48+
* This package contains information about the control box IOs, analog inputs/outputs, voltages,
49+
* currents, temperatures, the safety mode, as well as information about the optional IMMI
50+
* interface. See the Universal Robots primary/secondary guide for details:
51+
* https://docs.universal-robots.com/tutorials/communication-protocol-tutorials/primary-secondary-guide.html
52+
*/
53+
class MasterboardData : public RobotState
54+
{
55+
public:
56+
MasterboardData() = delete;
57+
58+
/*!
59+
* \brief Creates a new MasterboardData object.
60+
*
61+
* \param type The type of RobotState message received
62+
*/
63+
MasterboardData(const RobotStateType type) : RobotState(type)
64+
{
65+
}
66+
67+
/*!
68+
* \brief Creates a copy of a MasterboardData object.
69+
*
70+
* \param pkg The MasterboardData object to be copied
71+
*/
72+
MasterboardData(const MasterboardData& pkg);
73+
74+
virtual ~MasterboardData() = default;
75+
76+
/*!
77+
* \brief Sets the attributes of the package by parsing a serialized representation of the
78+
* package.
79+
*
80+
* \param bp A parser containing a serialized version of the package
81+
*
82+
* \returns True, if the package was parsed successfully, false otherwise
83+
*/
84+
virtual bool parseWith(comm::BinParser& bp);
85+
86+
/*!
87+
* \brief Consume this specific package with a specific consumer.
88+
*
89+
* \param consumer Placeholder for the consumer calling this
90+
*
91+
* \returns true on success
92+
*/
93+
virtual bool consumeWith(AbstractPrimaryConsumer& consumer);
94+
95+
/*!
96+
* \brief Produces a human readable representation of the package object.
97+
*
98+
* \returns A string representing the object
99+
*/
100+
virtual std::string toString() const;
101+
102+
std::bitset<32> digital_input_bits_;
103+
std::bitset<32> digital_output_bits_;
104+
uint8_t analog_input_range_0_;
105+
uint8_t analog_input_range_1_;
106+
double analog_input_0_;
107+
double analog_input_1_;
108+
char analog_output_domain_0_;
109+
char analog_output_domain_1_;
110+
double analog_output_0_;
111+
double analog_output_1_;
112+
float master_board_temperature_;
113+
float robot_voltage_48v_;
114+
float robot_current_;
115+
float master_io_current_;
116+
SafetyMode safety_mode_;
117+
bool in_reduced_mode_;
118+
bool immi_interface_installed_{ false };
119+
120+
// The following four fields are only valid if immi_interface_installed_ is true.
121+
std::bitset<32> immi_input_bits_;
122+
std::bitset<32> immi_output_bits_;
123+
float immi_voltage_24v_{ 0.0f };
124+
float immi_current_{ 0.0f };
125+
126+
uint32_t reserved_1_{ 0 };
127+
uint8_t operational_mode_selector_input_{ 0 };
128+
bool three_position_enabling_device_input_{ false };
129+
uint8_t reserved_2_{ 0 };
130+
};
131+
132+
} // namespace primary_interface
133+
} // namespace urcl
134+
135+
#endif // ifndef UR_CLIENT_LIBRARY_MASTERBOARD_DATA_H_INCLUDED
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
// -- BEGIN LICENSE BLOCK ----------------------------------------------
2+
// Copyright 2025 Universal Robots A/S
3+
//
4+
// Redistribution and use in source and binary forms, with or without
5+
// modification, are permitted provided that the following conditions are met:
6+
//
7+
// * Redistributions of source code must retain the above copyright
8+
// notice, this list of conditions and the following disclaimer.
9+
//
10+
// * Redistributions in binary form must reproduce the above copyright
11+
// notice, this list of conditions and the following disclaimer in the
12+
// documentation and/or other materials provided with the distribution.
13+
//
14+
// * Neither the name of the {copyright_holder} nor the names of its
15+
// contributors may be used to endorse or promote products derived from
16+
// this software without specific prior written permission.
17+
//
18+
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19+
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20+
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21+
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22+
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23+
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24+
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25+
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26+
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27+
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28+
// POSSIBILITY OF SUCH DAMAGE.
29+
// -- END LICENSE BLOCK ------------------------------------------------
30+
31+
#include "ur_client_library/primary/robot_state/masterboard_data.h"
32+
#include "ur_client_library/primary/abstract_primary_consumer.h"
33+
34+
#include <iomanip>
35+
#include <sstream>
36+
37+
namespace urcl
38+
{
39+
namespace primary_interface
40+
{
41+
MasterboardData::MasterboardData(const MasterboardData& pkg) : RobotState(RobotStateType::MASTERBOARD_DATA)
42+
{
43+
digital_input_bits_ = pkg.digital_input_bits_;
44+
digital_output_bits_ = pkg.digital_output_bits_;
45+
analog_input_range_0_ = pkg.analog_input_range_0_;
46+
analog_input_range_1_ = pkg.analog_input_range_1_;
47+
analog_input_0_ = pkg.analog_input_0_;
48+
analog_input_1_ = pkg.analog_input_1_;
49+
analog_output_domain_0_ = pkg.analog_output_domain_0_;
50+
analog_output_domain_1_ = pkg.analog_output_domain_1_;
51+
analog_output_0_ = pkg.analog_output_0_;
52+
analog_output_1_ = pkg.analog_output_1_;
53+
master_board_temperature_ = pkg.master_board_temperature_;
54+
robot_voltage_48v_ = pkg.robot_voltage_48v_;
55+
robot_current_ = pkg.robot_current_;
56+
master_io_current_ = pkg.master_io_current_;
57+
safety_mode_ = pkg.safety_mode_;
58+
in_reduced_mode_ = pkg.in_reduced_mode_;
59+
immi_interface_installed_ = pkg.immi_interface_installed_;
60+
immi_input_bits_ = pkg.immi_input_bits_;
61+
immi_output_bits_ = pkg.immi_output_bits_;
62+
immi_voltage_24v_ = pkg.immi_voltage_24v_;
63+
immi_current_ = pkg.immi_current_;
64+
reserved_1_ = pkg.reserved_1_;
65+
operational_mode_selector_input_ = pkg.operational_mode_selector_input_;
66+
three_position_enabling_device_input_ = pkg.three_position_enabling_device_input_;
67+
reserved_2_ = pkg.reserved_2_;
68+
}
69+
70+
bool MasterboardData::parseWith(comm::BinParser& bp)
71+
{
72+
bp.parse<uint32_t>(digital_input_bits_);
73+
bp.parse<uint32_t>(digital_output_bits_);
74+
bp.parse(analog_input_range_0_);
75+
bp.parse(analog_input_range_1_);
76+
bp.parse(analog_input_0_);
77+
bp.parse(analog_input_1_);
78+
bp.parse(analog_output_domain_0_);
79+
bp.parse(analog_output_domain_1_);
80+
bp.parse(analog_output_0_);
81+
bp.parse(analog_output_1_);
82+
bp.parse(master_board_temperature_);
83+
bp.parse(robot_voltage_48v_);
84+
bp.parse(robot_current_);
85+
bp.parse(master_io_current_);
86+
bp.parse(safety_mode_);
87+
bp.parse(in_reduced_mode_);
88+
bp.parse(immi_interface_installed_);
89+
90+
if (immi_interface_installed_)
91+
{
92+
bp.parse<uint32_t>(immi_input_bits_);
93+
bp.parse<uint32_t>(immi_output_bits_);
94+
bp.parse(immi_voltage_24v_);
95+
bp.parse(immi_current_);
96+
}
97+
98+
bp.parse(reserved_1_);
99+
bp.parse(operational_mode_selector_input_);
100+
bp.parse(three_position_enabling_device_input_);
101+
bp.parse(reserved_2_);
102+
103+
return true;
104+
}
105+
106+
bool MasterboardData::consumeWith(AbstractPrimaryConsumer& consumer)
107+
{
108+
return consumer.consume(*this);
109+
}
110+
111+
std::string MasterboardData::toString() const
112+
{
113+
std::stringstream os;
114+
os << std::boolalpha;
115+
os << "MasterboardData:" << std::endl;
116+
os << "Digital input bits: 0b" << digital_input_bits_ << std::endl;
117+
os << "Digital output bits: 0b" << digital_output_bits_ << std::endl;
118+
os << "Analog input range 0: " << unsigned(analog_input_range_0_) << std::endl;
119+
os << "Analog input range 1: " << unsigned(analog_input_range_1_) << std::endl;
120+
os << "Analog input 0: " << analog_input_0_ << std::endl;
121+
os << "Analog input 1: " << analog_input_1_ << std::endl;
122+
os << "Analog output domain 0: " << static_cast<int>(analog_output_domain_0_) << std::endl;
123+
os << "Analog output domain 1: " << static_cast<int>(analog_output_domain_1_) << std::endl;
124+
os << "Analog output 0: " << analog_output_0_ << std::endl;
125+
os << "Analog output 1: " << analog_output_1_ << std::endl;
126+
os << "Masterboard temperature: " << master_board_temperature_ << std::endl;
127+
os << "Robot voltage 48V: " << robot_voltage_48v_ << std::endl;
128+
os << "Robot current: " << robot_current_ << std::endl;
129+
os << "Master I/O current: " << master_io_current_ << std::endl;
130+
os << "Safety mode: " << safetyModeString(safety_mode_) << std::endl;
131+
os << "In reduced mode: " << in_reduced_mode_ << std::endl;
132+
os << "IMMI interface installed: " << immi_interface_installed_ << std::endl;
133+
if (immi_interface_installed_)
134+
{
135+
os << "IMMI input bits: 0b" << immi_input_bits_ << std::endl;
136+
os << "IMMI output bits: 0b" << immi_output_bits_ << std::endl;
137+
os << "IMMI voltage 24V: " << immi_voltage_24v_ << std::endl;
138+
os << "IMMI current: " << immi_current_ << std::endl;
139+
}
140+
os << "Operational mode selector input: " << unsigned(operational_mode_selector_input_) << std::endl;
141+
os << "Three position enabling device input: " << three_position_enabling_device_input_ << std::endl;
142+
143+
return os.str();
144+
}
145+
146+
} // namespace primary_interface
147+
} // namespace urcl

0 commit comments

Comments
 (0)