-
Notifications
You must be signed in to change notification settings - Fork 19
Conversation
the mapping is not quite simple and might need to be discussed some more
Is this a forward-port of ros-industrial-attic#143? |
more of a rewrite as the code changed significantly, but yes I meant to reference that PR |
@simonschmeisser wrote:
The message docs say this:
For UR we could maybe see whether we could use some of the status codes that are sometimes printed in the log (on the TP) for certain events. But I wouldn't know where to find those. |
@simonschmeisser wrote:
ok. Well that PR includes some more logic for when |
I couldn't really follow that logic, so yes, I did not copy that on purpose. |
src/ros/mb_publisher.cpp
Outdated
msg.e_stopped.val = data.emergency_stopped; | ||
msg.in_motion.val = data.program_running; | ||
msg.in_error.val = data.protective_stopped; | ||
msg.motion_possible.val = (robot_mode_V3_X::RUNNING == data.robot_mode) ? industrial_msgs::TriState::ON : industrial_msgs::TriState::OFF; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking but data.robot_mode == robot_mode_V3_X::RUNNING
(reverse ordering) is probably preferred as this is the style used elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, yes, sorry, I was experimenting if I could get this away:
ur_modern_driver/src/ros/mb_publisher.cpp:41: Warnung: enumeral mismatch in conditional expression: ‘industrial_msgs::TriState_<std::allocator<void> >::<anonymous enum>’ vs ‘industrial_msgs::TriState_<std::allocator<void> >::<anonymous enum>’ [-Wenum-compare]
msg.motion_possible.val = (data.robot_mode == robot_mode_V3_X::RUNNING) ? industrial_msgs::TriState::ON : industrial_msgs::TriState::OFF;
^
Thank you very much for the PR @simonschmeisser, looks very good to me, my only comment is the above nitpick and I'd be more than happy to merge your contribution 😄 |
src/ros/mb_publisher.cpp
Outdated
|
||
msg.drives_powered.val = data.robot_power_on; | ||
msg.e_stopped.val = data.emergency_stopped; | ||
msg.in_motion.val = data.program_running; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't believe in_motion
is the same as program_running
, is it?
Not sure whether there is a way to determine the robot is in motion without a program, or whether that is even possible actually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can secondary programs contain motion commands? And do they then update program_running
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is if
but not iff
, ie there will always be a program running when it moves but having a program running does not signify that it will actually move. At least that's my understanding
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. But then this expression doesn't currently accurately encode the state of the robot, right?
It could be executing a program without any motion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
industrial_msgs::TriState::Unknown
then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't use this field except for decorative purposes, so I don't care from a consumer point of view
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't use this field except for decorative purposes, so I don't care from a consumer point of view
That's great, but if we add this (RobotStatus
) it should accurately encode the status of the robot.
If we can't derive something from what the robot provides us, then yes, I believe using TriState::Unknown
for now would be better.
src/ros/mb_publisher.cpp
Outdated
msg.drives_powered.val = data.robot_power_on; | ||
msg.e_stopped.val = data.emergency_stopped; | ||
msg.in_motion.val = data.program_running; | ||
msg.in_error.val = data.protective_stopped; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is protective_stopped
high for all errors that can occur?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there does not seem to be another way to be informed about errors looking at the format in robot_mode.h
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about emergency_stopped
? That would definitely be an 'in_error' situation, but that's not captured here at the moment. ros-industrial-attic#143 makes in_error
the union of protective_stopped
and emergency_stopped
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah okay, I thought of e-stopped more like a state and the error would appear separately once you try moving despite it being in e-stopped mode. But I can change it to said union. This would again ask for a place to define the "vendor specific" error codes and then setting error_code
to differentiate protective_stopped
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Vendor specific" means that the error codes are defined by the vendor. Not by us, for every vendor.
This field is typically populated by copying the error code that the robot controller gives you for different errors. On Fanucs fi you would be copying the code returned by the ERR_DATA(..)
Karel function (which is typically a 5 or 6 digit number).
Those codes are defined by Fanuc. We don't make them up ourselves.
UR has similar codes I believe (just take a look at the log on the TP), but I'm not sure we can retrieve those from somewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought of e-stopped more like a state and the error would appear separately once you try moving despite it being in e-stopped mode.
That could definitely be a way to implement it, but we would need a way to reliably determine which of the two it is. I don't have a scripting manual with me right now, but if there is a get_last_error_code()
function that we can use, then we can definitely do what you propose.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're correct. e_stopped
is the state, and in_error
should follow from whether the robot controller defines this as an error.
Let's keep what you have for now.
Sorry for the noise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
re: vendor specific codes: looking at a UR we have here I keep seeing C100A5
in the log whenever the robot is Robot changed mode: EMERGENCY STOPPED
.
Those are the codes that would go into error_code
.
src/ros/mb_publisher.cpp
Outdated
void MBPublisher::publishRobotStatus(SharedRobotModeData& data) | ||
{ | ||
industrial_msgs::RobotStatus msg; | ||
msg.drives_powered.val = data.robot_power_on; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can robot_power_on
ever be true
if real_robot_enabled
is false
? Perhaps in ur-sim
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
testing with ursim I get the following output in Poly:
0000d05h41m35.184s RobotInterface C102A0: Real Robot not connected - Simulating Robot
meanwhile the robot mode contains the following data:
when I turn off the robot:
robot_power_on: 0 physical robot: 0 real_robot: 1 mode: 3 (POWER_OFF)
when I turn on the robot but do not yet release the brakes (ON but not START):
robot_power_on: 1 physical robot: 0 real_robot: 1 mode: 5 (IDLE)
when I release the brakes:
robot_power_on: 1 physical robot: 0 real_robot: 1 mode: 7 (RUNNING)
so I'm not sure what real_robot_enabled is supposed to tell us, maybe there is a way to switch to moving a simulated robot on the actual controller?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so I'm not sure what
real_robot_enabled
is supposed to tell us, maybe there is a way to switch to moving a simulated robot on the actual controller?
There is a two-option selection bullet list at the bottom right or left (don't remember) that contains those two options. I've never used it, but IIRC you can use it to switch to a virtual robot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The difference between IDLE
and RUNNING
may indicate that RUNNING
would be better indicator of drives_powered
?
Edit: hm, no. That makes no sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, found that (for the reference: it is in 'Program Robot' -> 'Move' or 'I/O' but I can only change it to simulated in IO), real_robot_enabled then does turn to false. But this doesn't map to any of the industrial_msgs::RobotStatus fields does it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# Drive power status: True if drives are powered. Motion commands will
# automatically enable the drives if required. Drive power is not requred
# for possible motion
industrial_msgs/TriState drives_powered
So yes, maybe drives powered should be obtained from Mode == RUNNING as in that halfway on mode (breakes still on) it does not automatically start moving. But then drives_powered would be the same as motion_possible. And as far as I understand motion_possible is authorative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think drives_powered
should reflect the status of the drives (ie: robot_power_on
.
RUNNING
could then be used in the predicate for motion_possible
(ie: mode != RUNNING -> motion_possible = false
.
I think if you can add some comments (fi, why |
this allows to extract motion_possible and mode as well added comments for everything non obvious or disputable
Switching to using either version 1 or 3 of the data package instead of using the default type allows publishing some more info. I also commented everything and added const correctness. |
@Zagitta @gavanderhoorn anything else you would like me to modify? |
It looks good to me but since I'm not really involved in anything related to UR anymore I'll let @gavanderhoorn have the final say 😃 |
|
||
public: | ||
MBPublisher() : io_pub_(nh_.advertise<ur_msgs::IOStates>("ur_driver/io_states", 1)) | ||
, status_pub_(nh_.advertise<industrial_msgs::RobotStatus>("robot_status", 1)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this perhaps be published at "ur_driver/robot_status"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could, but that would make it non-compliant with other ros-i robot drivers.
A remap can fix that though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright yes that makes perfect sense, let's keep it as it is here then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well .. let's actually not.
All topics for the ur_driver
are below a ur_driver
namespace already, so having this one outside it breaks that.
If/when we need to make this driver ros-i compliant, we can either blanketly remap everything or update the topics.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'll add the prefix for consistencies sake?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that makes the most sense for now, yes.
Otherwise users would find all topics of the driver under the ur_driver
namespace, but a lone (and seemingly unrelated) /robot_status
topic in the global one.
I would be ok with merging this. My only question would be whether the duplication between @simonschmeisser: would it make sense to introduce a separate function that sets up and publishes the message that gets called from those two callbacks? |
@gavanderhoorn yes, I can add a generic |
If the version-specific fields are just regular primitive types, you could potentially create a |
I suggest following the approach here to keep things consistent 😃 |
@gavanderhoorn @Zagitta are you fine with the current state or should I change anything else? |
Thank you very much for your contribution 🎉 |
This adds a publisher for industrial_msgs::RobotStatus
the mapping is not quite unique and might need to be discussed some more. Especially
protective_stopped
is currently mapped toin_error
. There are probably other error states that should lead toin_error
as well and be assigned an uniqueerror_code
. @gavanderhoorn Do we have a generic list of such error_codes somewhere or are these "vendor specific" and if so where would I place an enum/message description?