Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to work with Heartbeat #288

Closed
ghanim-mukhtar opened this issue May 24, 2024 · 5 comments · Fixed by #294
Closed

How to work with Heartbeat #288

ghanim-mukhtar opened this issue May 24, 2024 · 5 comments · Fixed by #294
Labels
question Further information is requested

Comments

@ghanim-mukhtar
Copy link

ghanim-mukhtar commented May 24, 2024

Describe the question
I am using the library on an Embedded onboard PC the problem is if I send a non-zero command to my motors and for one reason or other the ROS application is shut down the robot keep moving with this command, very risky business.

So I want to set the motors (the slaves) to be consumers of a Heartbeat, the supplier already showed me how to activate it on their controllers so that is done. Now I need my master to send it.

I started following the exercise here with the virtual CAN to have a prove of concept. So I focused on the Service Interface with ros2 launch canopen_tests cia402_setup.launch.py and did the following:

  • In ros2_canopen/canopen_tests/config/cia402/bus.yml set the master heartbeat to 1000 ms
master:
  node_id: 1
  driver: "ros2_canopen::MasterDriver"
  package: "canopen_master_driver"
  sync_period: 10000
  heartbeat_producer: 1000

Which according to here should have the service: ~/set_heartbeat

  • Same file, set the slaves to be heartbeat consumers:
defaults:
  dcf: "cia402_slave.eds"
  driver: "ros2_canopen::Cia402Driver"
  package: "canopen_402_driver"
  period: 10
  revision_number: 0
  heartbeat_consumer: true

Which according to here
After that I checked:

  • Running nodes:
$ ros2 node list
/cia402_node_1
/launch_ros_204171
  • Status of /cia402_node_1:
$ ros2 service call /cia402_node_1/get_state lifecycle_msgs/srv/GetState
requester: making request: lifecycle_msgs.srv.GetState_Request()

response:
lifecycle_msgs.srv.GetState_Response(current_state=lifecycle_msgs.msg.State(id=3, label='active'))
  • Final the node info to see if I have the service ~/set_heartbeat there:
$ ros2 node info /cia402_node_1
/cia402_node_1
  Subscribers:
    /parameter_events: rcl_interfaces/msg/ParameterEvent
  Publishers:
    /cia402_node_1/transition_event: lifecycle_msgs/msg/TransitionEvent
    /parameter_events: rcl_interfaces/msg/ParameterEvent
    /rosout: rcl_interfaces/msg/Log
  Service Servers:
    /cia402_node_1/change_state: lifecycle_msgs/srv/ChangeState
    /cia402_node_1/describe_parameters: rcl_interfaces/srv/DescribeParameters
    /cia402_node_1/get_available_states: lifecycle_msgs/srv/GetAvailableStates
    /cia402_node_1/get_available_transitions: lifecycle_msgs/srv/GetAvailableTransitions
    /cia402_node_1/get_parameter_types: rcl_interfaces/srv/GetParameterTypes
    /cia402_node_1/get_parameters: rcl_interfaces/srv/GetParameters
    /cia402_node_1/get_state: lifecycle_msgs/srv/GetState
    /cia402_node_1/get_transition_graph: lifecycle_msgs/srv/GetAvailableTransitions
    /cia402_node_1/list_parameters: rcl_interfaces/srv/ListParameters
    /cia402_node_1/set_parameters: rcl_interfaces/srv/SetParameters
    /cia402_node_1/set_parameters_atomically: rcl_interfaces/srv/SetParametersAtomically
  Service Clients:

  Action Servers:

  Action Clients:

So we can see there no heartbeat service nor in the can trace, What I am missing here ? I expected the presence of the service and a continuous can trace every second, did I misunderstood that ?

Logs

Setup:

  • Device: EAC-3000 with processor: ARMv8 Processor rev 0 (v8l) × 8
  • OS: Native is: Ubuntu 20.04.5 LTS, but the application running on Docker container based on ros:humble-ros-base-jammy
  • ROS-Distro: humble
  • Branch/Commit: humble

Additional context
I tried to look up the code on my side and I was surprised to see that in neither:

  • canopen_master_driver/include/canopen_master_driver/node_interfaces/node_canopen_basic_master.hpp here, nor
  • canopen_master_driver/include/canopen_master_driver/node_interfaces/node_canopen_basic_master_impl.hpp here
    There is no use of canopen_interfaces/srv/co_heartbeat_id.hpp, and I even look through the whole repos and it is not used anywhere. I mean it is defined and built as we can see in canopen_interface here but not used afterwards.

Does this mean that I need to write the service myself?

@ghanim-mukhtar ghanim-mukhtar added the question Further information is requested label May 24, 2024
@hellantos hellantos linked a pull request Jul 19, 2024 that will close this issue
@hellantos
Copy link
Member

Hi, thanks for the comment and sorry for the confusion. We removed the service at some point because the possibility to fix heartbeat settings in the yaml for master and devices seemed sufficient. Actually this is a problem in the documentation. I have created PR #294 for adjusting this.

@ghanim-mukhtar
Copy link
Author

Hi, thanks for the comment and sorry for the confusion. We removed the service at some point because the possibility to fix heartbeat settings in the yaml for master and devices seemed sufficient. Actually this is a problem in the documentation. I have created PR #294 for adjusting this.

Thanks for the reply and the correction, but still for me I am a bit confused about how to set the heartbeat in such a way that the PC is producer and the motors are consumers. Can you provide yaml examples please ?

@hellantos
Copy link
Member

You would need to add heartbeat_producer: 1000 to master node and heartbeat_consumer: true to driver node in bus.yml.

@ghanim-mukhtar
Copy link
Author

Thanks for the tip, I will check and get back to you ASAP to conclude the issue

@ghanim-mukhtar
Copy link
Author

I did the test today and just wanted to double check something because I didn't get the behavior expected. I am in contact with our CANOpen motor controller to see if the error is in their side (most likely), meanwhile I have a small doubt about lily_core_libraries that I want to clear up with you.

Basically the bus.yml is configured as indicated above.

image

But after compiling I checked the resulting file cli.py in ~my_workspace/install/lely_core_libraries/lib/python3.10/site-packages/dcfgen/ and these caught my eyes (i attached it as .txt for your convenience):

image
image

So my question is: Is this normal ? I mean the fact that in this autogenerated cli.py in lily_core_libraries the slave class is set as not a consumer of heartbeat and master class is set as non producer of heartbeat ?

cli.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants