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
3839namespace 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+
4049hardware_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
339355return_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+
429542void URPositionHardwareInterface::handleRobotProgramState (bool program_running)
430543{
431544 if (!robot_program_running_ && program_running)
0 commit comments