Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ add_library(urcl
src/primary/robot_state/kinematics_info.cpp
src/primary/robot_state/robot_mode_data.cpp
src/primary/robot_state/configuration_data.cpp
src/primary/robot_state/masterboard_data.cpp
src/rtde/control_package_pause.cpp
src/rtde/control_package_setup_inputs.cpp
src/rtde/control_package_setup_outputs.cpp
Expand Down Expand Up @@ -190,4 +191,4 @@ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/ros_package_pa
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/share/${PROJECT_NAME}/hook/ros_package_path.dsv DESTINATION share/${PROJECT_NAME}/hook)
#### End iport ####

install(DIRECTORY resources DESTINATION share/${PROJECT_NAME})
install(DIRECTORY resources DESTINATION share/${PROJECT_NAME})
2 changes: 2 additions & 0 deletions include/ur_client_library/primary/abstract_primary_consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "ur_client_library/primary/robot_state/kinematics_info.h"
#include "ur_client_library/primary/robot_state/robot_mode_data.h"
#include "ur_client_library/primary/robot_state/configuration_data.h"
#include "ur_client_library/primary/robot_state/masterboard_data.h"
#include "ur_client_library/primary/robot_message/safety_mode_message.h"

namespace urcl
Expand Down Expand Up @@ -80,6 +81,7 @@ class AbstractPrimaryConsumer : public comm::IConsumer<PrimaryPackage>
virtual bool consume(ErrorCodeMessage& pkg) = 0;
virtual bool consume(RobotModeData& pkg) = 0;
virtual bool consume(ConfigurationData& pkg) = 0;
virtual bool consume(MasterboardData& pkg) = 0;
virtual bool consume(SafetyModeMessage& pkg) = 0;

private:
Expand Down
17 changes: 17 additions & 0 deletions include/ur_client_library/primary/primary_consumer.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "ur_client_library/primary/abstract_primary_consumer.h"
#include "ur_client_library/primary/robot_state/robot_mode_data.h"
#include "ur_client_library/primary/robot_state/masterboard_data.h"
#include "ur_client_library/ur/datatypes.h"
#include "ur_client_library/ur/version_information.h"

Expand Down Expand Up @@ -185,6 +186,20 @@ class PrimaryConsumer : public AbstractPrimaryConsumer
return true;
}

/*!
* \brief Handle a MasterboardData package
*
* \param pkg MasterboardData
*
* \returns True
*/
virtual bool consume(MasterboardData& pkg) override
{
std::scoped_lock lock(masterboard_data_mutex_);
masterboard_data_ = std::make_shared<MasterboardData>(pkg);
return true;
}

/*!
* \brief Set callback function which will be triggered whenever error code messages are received
*
Expand Down Expand Up @@ -267,6 +282,8 @@ class PrimaryConsumer : public AbstractPrimaryConsumer
std::mutex configuration_data_mutex_;
std::mutex safety_mode_mutex_;
std::shared_ptr<SafetyModeMessage> safety_mode_;
std::mutex masterboard_data_mutex_;
std::shared_ptr<MasterboardData> masterboard_data_;
Comment thread
cursor[bot] marked this conversation as resolved.
Outdated
};

} // namespace primary_interface
Expand Down
7 changes: 3 additions & 4 deletions include/ur_client_library/primary/primary_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "ur_client_library/primary/robot_message/error_code_message.h"
#include "ur_client_library/primary/robot_state/robot_mode_data.h"
#include "ur_client_library/primary/robot_state/configuration_data.h"
#include "ur_client_library/primary/robot_state/masterboard_data.h"
#include "ur_client_library/primary/robot_message/safety_mode_message.h"

namespace urcl
Expand Down Expand Up @@ -209,10 +210,8 @@ class PrimaryParser : public comm::Parser<PrimaryPackage>
{
case RobotStateType::ROBOT_MODE_DATA:
return new RobotModeData(type);

// return new rmd;
// case robot_state_type::MASTERBOARD_DATA:
// return new MBD;*/
case RobotStateType::MASTERBOARD_DATA:
return new MasterboardData(type);
case RobotStateType::KINEMATICS_INFO:
return new KinematicsInfo(type);
case RobotStateType::CONFIGURATION_DATA:
Expand Down
135 changes: 135 additions & 0 deletions include/ur_client_library/primary/robot_state/masterboard_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// -- BEGIN LICENSE BLOCK ----------------------------------------------
// Copyright 2026 Universal Robots A/S
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the {copyright_holder} nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// -- END LICENSE BLOCK ------------------------------------------------

#ifndef UR_CLIENT_LIBRARY_MASTERBOARD_DATA_H_INCLUDED
#define UR_CLIENT_LIBRARY_MASTERBOARD_DATA_H_INCLUDED

#include <bitset>

#include "ur_client_library/types.h"
#include "ur_client_library/primary/robot_state.h"
#include "ur_client_library/ur/datatypes.h"

namespace urcl
{
namespace primary_interface
{
/*!
* \brief The MasterboardData class handles the masterboard data sub-package sent as part of the
* Robot State message on the primary UR interface.
*
* This package contains information about the control box IOs, analog inputs/outputs, voltages,
* currents, temperatures, the safety mode, as well as information about the optional IMMI
* interface. See the Universal Robots primary/secondary guide for details:
* https://docs.universal-robots.com/tutorials/communication-protocol-tutorials/primary-secondary-guide.html
*/
class MasterboardData : public RobotState
{
public:
MasterboardData() = delete;

/*!
* \brief Creates a new MasterboardData object.
*
* \param type The type of RobotState message received
*/
MasterboardData(const RobotStateType type) : RobotState(type)
{
}

/*!
* \brief Creates a copy of a MasterboardData object.
*
* \param pkg The MasterboardData object to be copied
*/
MasterboardData(const MasterboardData& pkg);

virtual ~MasterboardData() = default;

/*!
* \brief Sets the attributes of the package by parsing a serialized representation of the
* package.
*
* \param bp A parser containing a serialized version of the package
*
* \returns True, if the package was parsed successfully, false otherwise
*/
virtual bool parseWith(comm::BinParser& bp);

/*!
* \brief Consume this specific package with a specific consumer.
*
* \param consumer Placeholder for the consumer calling this
*
* \returns true on success
*/
virtual bool consumeWith(AbstractPrimaryConsumer& consumer);

/*!
* \brief Produces a human readable representation of the package object.
*
* \returns A string representing the object
*/
virtual std::string toString() const;

std::bitset<32> digital_input_bits_;
std::bitset<32> digital_output_bits_;
uint8_t analog_input_range_0_;
uint8_t analog_input_range_1_;
double analog_input_0_;
double analog_input_1_;
char analog_output_domain_0_;
char analog_output_domain_1_;
double analog_output_0_;
double analog_output_1_;
float master_board_temperature_;
float robot_voltage_48v_;
float robot_current_;
float master_io_current_;
SafetyMode safety_mode_;
bool in_reduced_mode_;
bool immi_interface_installed_{ false };

// The following four fields are only valid if immi_interface_installed_ is true.
std::bitset<32> immi_input_bits_;
std::bitset<32> immi_output_bits_;
float immi_voltage_24v_{ 0.0f };
float immi_current_{ 0.0f };

uint32_t reserved_1_{ 0 };
uint8_t operational_mode_selector_input_{ 0 };
bool three_position_enabling_device_input_{ false };
uint8_t reserved_2_{ 0 };
};

} // namespace primary_interface
} // namespace urcl

#endif // ifndef UR_CLIENT_LIBRARY_MASTERBOARD_DATA_H_INCLUDED
147 changes: 147 additions & 0 deletions src/primary/robot_state/masterboard_data.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// -- BEGIN LICENSE BLOCK ----------------------------------------------
// Copyright 2025 Universal Robots A/S
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// * Neither the name of the {copyright_holder} nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
// -- END LICENSE BLOCK ------------------------------------------------

#include "ur_client_library/primary/robot_state/masterboard_data.h"
#include "ur_client_library/primary/abstract_primary_consumer.h"

#include <iomanip>
#include <sstream>

namespace urcl
{
namespace primary_interface
{
MasterboardData::MasterboardData(const MasterboardData& pkg) : RobotState(RobotStateType::MASTERBOARD_DATA)
{
digital_input_bits_ = pkg.digital_input_bits_;
digital_output_bits_ = pkg.digital_output_bits_;
analog_input_range_0_ = pkg.analog_input_range_0_;
analog_input_range_1_ = pkg.analog_input_range_1_;
analog_input_0_ = pkg.analog_input_0_;
analog_input_1_ = pkg.analog_input_1_;
analog_output_domain_0_ = pkg.analog_output_domain_0_;
analog_output_domain_1_ = pkg.analog_output_domain_1_;
analog_output_0_ = pkg.analog_output_0_;
analog_output_1_ = pkg.analog_output_1_;
master_board_temperature_ = pkg.master_board_temperature_;
robot_voltage_48v_ = pkg.robot_voltage_48v_;
robot_current_ = pkg.robot_current_;
master_io_current_ = pkg.master_io_current_;
safety_mode_ = pkg.safety_mode_;
in_reduced_mode_ = pkg.in_reduced_mode_;
immi_interface_installed_ = pkg.immi_interface_installed_;
immi_input_bits_ = pkg.immi_input_bits_;
immi_output_bits_ = pkg.immi_output_bits_;
immi_voltage_24v_ = pkg.immi_voltage_24v_;
immi_current_ = pkg.immi_current_;
reserved_1_ = pkg.reserved_1_;
operational_mode_selector_input_ = pkg.operational_mode_selector_input_;
three_position_enabling_device_input_ = pkg.three_position_enabling_device_input_;
reserved_2_ = pkg.reserved_2_;
}

bool MasterboardData::parseWith(comm::BinParser& bp)
{
bp.parse<uint32_t>(digital_input_bits_);
bp.parse<uint32_t>(digital_output_bits_);
bp.parse(analog_input_range_0_);
bp.parse(analog_input_range_1_);
bp.parse(analog_input_0_);
bp.parse(analog_input_1_);
bp.parse(analog_output_domain_0_);
bp.parse(analog_output_domain_1_);
bp.parse(analog_output_0_);
bp.parse(analog_output_1_);
bp.parse(master_board_temperature_);
bp.parse(robot_voltage_48v_);
bp.parse(robot_current_);
bp.parse(master_io_current_);
bp.parse(safety_mode_);
bp.parse(in_reduced_mode_);
bp.parse(immi_interface_installed_);

if (immi_interface_installed_)
{
bp.parse<uint32_t>(immi_input_bits_);
bp.parse<uint32_t>(immi_output_bits_);
bp.parse(immi_voltage_24v_);
bp.parse(immi_current_);
}

bp.parse(reserved_1_);
bp.parse(operational_mode_selector_input_);
bp.parse(three_position_enabling_device_input_);
bp.parse(reserved_2_);
Comment thread
urfeex marked this conversation as resolved.

return true;
}

bool MasterboardData::consumeWith(AbstractPrimaryConsumer& consumer)
{
return consumer.consume(*this);
}

std::string MasterboardData::toString() const
{
std::stringstream os;
os << std::boolalpha;
os << "MasterboardData:" << std::endl;
os << "Digital input bits: 0b" << digital_input_bits_ << std::endl;
os << "Digital output bits: 0b" << digital_output_bits_ << std::endl;
os << "Analog input range 0: " << unsigned(analog_input_range_0_) << std::endl;
os << "Analog input range 1: " << unsigned(analog_input_range_1_) << std::endl;
os << "Analog input 0: " << analog_input_0_ << std::endl;
os << "Analog input 1: " << analog_input_1_ << std::endl;
os << "Analog output domain 0: " << static_cast<int>(analog_output_domain_0_) << std::endl;
os << "Analog output domain 1: " << static_cast<int>(analog_output_domain_1_) << std::endl;
os << "Analog output 0: " << analog_output_0_ << std::endl;
os << "Analog output 1: " << analog_output_1_ << std::endl;
os << "Masterboard temperature: " << master_board_temperature_ << std::endl;
os << "Robot voltage 48V: " << robot_voltage_48v_ << std::endl;
os << "Robot current: " << robot_current_ << std::endl;
os << "Master I/O current: " << master_io_current_ << std::endl;
os << "Safety mode: " << safetyModeString(safety_mode_) << std::endl;
os << "In reduced mode: " << in_reduced_mode_ << std::endl;
os << "IMMI interface installed: " << immi_interface_installed_ << std::endl;
if (immi_interface_installed_)
{
os << "IMMI input bits: 0b" << immi_input_bits_ << std::endl;
os << "IMMI output bits: 0b" << immi_output_bits_ << std::endl;
os << "IMMI voltage 24V: " << immi_voltage_24v_ << std::endl;
os << "IMMI current: " << immi_current_ << std::endl;
}
os << "Operational mode selector input: " << unsigned(operational_mode_selector_input_) << std::endl;
os << "Three position enabling device input: " << three_position_enabling_device_input_ << std::endl;

return os.str();
}

} // namespace primary_interface
} // namespace urcl
Loading
Loading