Skip to content

Commit 05d46c1

Browse files
committed
Added checks for internal robot state machine
1 parent d40e9c2 commit 05d46c1

File tree

2 files changed

+160
-0
lines changed

2 files changed

+160
-0
lines changed

ur_robot_driver/include/ur_robot_driver/hardware_interface.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,13 @@ using hardware_interface::status;
5555

5656
namespace ur_robot_driver
5757
{
58+
enum class PausingState
59+
{
60+
PAUSED,
61+
RUNNING,
62+
RAMPUP
63+
};
64+
5865
/*!
5966
* \brief The HardwareInterface class handles the interface between the ROS system and the main
6067
* driver. It contains the read and write methods of the main control loop and registers various ROS
@@ -86,6 +93,12 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
8693
return_type read() final;
8794
return_type write() final;
8895

96+
/*!
97+
* \brief Read and evaluate data in order to set robot status properties for industrial
98+
* robot status interface
99+
*/
100+
void extractRobotStatus();
101+
89102
/*!
90103
* \brief Callback to handle a change in the current state of the URCaps program running on the
91104
* robot. Executed only on the state change.
@@ -113,9 +126,40 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
113126
urcl::vector6d_t urcl_joint_efforts_;
114127
urcl::vector6d_t urcl_ft_sensor_measurements_;
115128
urcl::vector6d_t urcl_tcp_pose_;
129+
130+
// TODO exchange for industrial robot status interface
131+
enum class TriState : int8_t
132+
{
133+
UNKNOWN = -1,
134+
FALSE = 0,
135+
TRUE = 1,
136+
};
137+
enum class RobotMode : int8_t
138+
{
139+
UNKNOWN = -1,
140+
MANUAL = 1,
141+
AUTO = 2,
142+
};
143+
typedef std::int32_t ErrorCode;
144+
struct RobotStatus
145+
{
146+
RobotMode mode;
147+
TriState e_stopped;
148+
TriState drives_powered;
149+
TriState motion_possible;
150+
TriState in_motion;
151+
TriState in_error;
152+
ErrorCode error_code;
153+
};
154+
RobotStatus robot_status_resource_{};
155+
// END TODO
156+
116157
bool packet_read_;
117158

118159
uint32_t runtime_state_;
160+
bool position_controller_running_;
161+
bool velocity_controller_running_;
162+
bool controllers_initialized_;
119163

120164
std::bitset<18> actual_dig_out_bits_;
121165
std::bitset<18> actual_dig_in_bits_;
@@ -140,6 +184,9 @@ class URPositionHardwareInterface : public hardware_interface::SystemInterface
140184
bool non_blocking_read_;
141185
bool position_interface_in_use_;
142186

187+
PausingState pausing_state_;
188+
double pausing_ramp_up_increment_;
189+
143190
std::unique_ptr<urcl::UrDriver> ur_driver_;
144191
};
145192
} // namespace ur_robot_driver

ur_robot_driver/src/hardware_interface.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
*
2222
* \author Lovro Ivanov [email protected]
2323
* \author Andy Zelenak [email protected]
24+
* \author Marvin Große Besselmann [email protected]
2425
* \date 2020-11-9
2526
*
2627
*/
@@ -37,6 +38,14 @@ namespace rtde = urcl::rtde_interface;
3738

3839
namespace ur_robot_driver
3940
{
41+
static const std::bitset<11>
42+
in_error_bitset_(1 << urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_PROTECTIVE_STOPPED) |
43+
1 << urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_ROBOT_EMERGENCY_STOPPED) |
44+
1 << urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_EMERGENCY_STOPPED) |
45+
1 << urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_VIOLATION) |
46+
1 << urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_FAULT) |
47+
1 << urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_STOPPED_DUE_TO_SAFETY));
48+
4049
hardware_interface::return_type URPositionHardwareInterface::configure(const HardwareInfo& system_info)
4150
{
4251
info_ = system_info;
@@ -49,6 +58,13 @@ hardware_interface::return_type URPositionHardwareInterface::configure(const Har
4958
urcl_tcp_pose_ = { { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } };
5059
urcl_position_commands_ = { { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } };
5160
urcl_velocity_commands_ = { { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } };
61+
runtime_state_ = static_cast<uint32_t>(rtde::RUNTIME_STATE::STOPPED);
62+
pausing_state_ = PausingState::RUNNING;
63+
pausing_ramp_up_increment_ = 0.01;
64+
position_controller_running_ = false;
65+
velocity_controller_running_ = false;
66+
controllers_initialized_ = false;
67+
5268

5369
for (const hardware_interface::ComponentInfo& joint : info_.joints)
5470
{
@@ -338,6 +354,15 @@ void URPositionHardwareInterface::readBitsetData(const std::unique_ptr<rtde::Dat
338354

339355
return_type URPositionHardwareInterface::read()
340356
{
357+
robot_status_resource_.mode = RobotMode::UNKNOWN;
358+
robot_status_resource_.e_stopped = TriState::UNKNOWN;
359+
robot_status_resource_.drives_powered = TriState::UNKNOWN;
360+
robot_status_resource_.motion_possible = TriState::UNKNOWN;
361+
robot_status_resource_.in_motion = TriState::UNKNOWN;
362+
robot_status_resource_.in_error = TriState::UNKNOWN;
363+
robot_status_resource_.error_code = 0;
364+
365+
341366
std::unique_ptr<rtde::DataPackage> data_pkg = ur_driver_->getDataPackage();
342367

343368
if (data_pkg)
@@ -372,6 +397,42 @@ return_type URPositionHardwareInterface::read()
372397
readBitsetData<uint32_t>(data_pkg, "tool_analog_input_types", tool_analog_input_types_);
373398

374399
// TODO logic for sending other stuff to higher level interface
400+
extractRobotStatus();
401+
402+
// pausing state follows runtime state when pausing
403+
if (runtime_state_ == static_cast<uint32_t>(rtde::RUNTIME_STATE::PAUSED))
404+
{
405+
pausing_state_ = PausingState::PAUSED;
406+
}
407+
// When the robot resumed program execution and pausing state was PAUSED, we enter RAMPUP
408+
else if (runtime_state_ == static_cast<uint32_t>(rtde::RUNTIME_STATE::PLAYING) &&
409+
pausing_state_ == PausingState::PAUSED)
410+
{
411+
speed_scaling_combined_ = 0.0;
412+
pausing_state_ = PausingState::RAMPUP;
413+
}
414+
415+
if (pausing_state_ == PausingState::RAMPUP)
416+
{
417+
double speed_scaling_ramp = speed_scaling_combined_ + pausing_ramp_up_increment_;
418+
speed_scaling_combined_ = std::min(speed_scaling_ramp, speed_scaling_ * target_speed_fraction_);
419+
420+
if (speed_scaling_ramp > speed_scaling_ * target_speed_fraction_)
421+
{
422+
pausing_state_ = PausingState::RUNNING;
423+
}
424+
}
425+
else if (runtime_state_ == static_cast<uint32_t>(rtde::RUNTIME_STATE::RESUMING))
426+
{
427+
// We have to keep speed scaling on ROS side at 0 during RESUMING to prevent controllers from
428+
// continuing to interpolate
429+
speed_scaling_combined_ = 0.0;
430+
}
431+
else
432+
{
433+
// Normal case
434+
speed_scaling_combined_ = speed_scaling_ * target_speed_fraction_;
435+
}
375436

376437
return return_type::OK;
377438
}
@@ -426,6 +487,58 @@ return_type URPositionHardwareInterface::write()
426487
}
427488
}
428489

490+
void URPositionHardwareInterface::extractRobotStatus()
491+
{
492+
robot_status_resource_.mode =
493+
robot_status_bits_[urcl::toUnderlying(rtde::UrRtdeRobotStatusBits::IS_TEACH_BUTTON_PRESSED)] ? RobotMode::MANUAL :
494+
RobotMode::AUTO;
495+
496+
robot_status_resource_.e_stopped =
497+
safety_status_bits_[urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_EMERGENCY_STOPPED)] ? TriState::TRUE :
498+
TriState::FALSE;
499+
500+
// Note that this is true as soon as the drives are powered,
501+
// even if the brakes are still closed
502+
// which is in slight contrast to the comments in the
503+
// message definition
504+
robot_status_resource_.drives_powered =
505+
robot_status_bits_[urcl::toUnderlying(rtde::UrRtdeRobotStatusBits::IS_POWER_ON)] ? TriState::TRUE :
506+
TriState::FALSE;
507+
508+
// I found no way to reliably get information if the robot is moving
509+
robot_status_resource_.in_motion = TriState::UNKNOWN;
510+
511+
if ((safety_status_bits_ & in_error_bitset_).any())
512+
{
513+
robot_status_resource_.in_error = TriState::TRUE;
514+
}
515+
else
516+
{
517+
robot_status_resource_.in_error = TriState::FALSE;
518+
}
519+
520+
// Motion is not possible if controller is either in error or in safeguard stop.
521+
// TODO: Check status of robot program "external control" here as well
522+
if (robot_status_resource_.in_error == TriState::TRUE ||
523+
safety_status_bits_[urcl::toUnderlying(rtde::UrRtdeSafetyStatusBits::IS_SAFEGUARD_STOPPED)])
524+
{
525+
robot_status_resource_.motion_possible = TriState::FALSE;
526+
}
527+
// TODO The hardcoded 7 should be ur_dashboard_msgs::RobotMode::RUNNING exchange when msgs are built
528+
else if (robot_mode_ == 7)
529+
{
530+
robot_status_resource_.motion_possible = TriState::TRUE;
531+
}
532+
else
533+
{
534+
robot_status_resource_.motion_possible = TriState::FALSE;
535+
}
536+
537+
// the error code, if any, is not transmitted by this protocol
538+
// it can and should be fetched separately
539+
robot_status_resource_.error_code = 0;
540+
}
541+
429542
void URPositionHardwareInterface::handleRobotProgramState(bool program_running)
430543
{
431544
if (!robot_program_running_ && program_running)

0 commit comments

Comments
 (0)