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

Functioning with custom device driver. #46

Closed
8vin8 opened this issue Aug 22, 2022 · 12 comments
Closed

Functioning with custom device driver. #46

8vin8 opened this issue Aug 22, 2022 · 12 comments

Comments

@8vin8
Copy link

8vin8 commented Aug 22, 2022

Hello Team,

I am a newbie to CANopen and ROS2, I have gone through this https://ros-industrial.github.io/ros2_canopen/ as well, but not able to understand how can I add a device driver and not able to understand how this new repository is functioning. Do you have some more documentation where I can understanding how its working.
I have also gone through this documentation and implementation of master slave part https://opensource.lely.com/canopen/docs/installation/
I need more information how to add a device driver into this CANopen stack.

I would be grateful for your help.
Regards

@8vin8 8vin8 changed the title Functioning with different device driver. Functioning with new device driver. Aug 22, 2022
@8vin8 8vin8 changed the title Functioning with new device driver. Functioning with custom device driver. Aug 22, 2022
@8vin8 8vin8 closed this as completed Aug 22, 2022
@8vin8 8vin8 reopened this Aug 22, 2022
@hellantos
Copy link
Member

Hi,

Currently, there is no conprehensive documentation on driver development. We will add it once the interfaces are stable.

If you want to create a driver now, it can either inherit from ros2_canopen::BaseDriver or from ros2_canopen::ProxyDriver.
Both have an LelyBridge member called driver. The LelyBridge driver member provides functions to for reading and writing sdos as well as transmitting tpdo and nmt commands. (Check in lely_bridge.hpp file, there is some documentation)

You will also need to override on_nmt which is a callback tracking nmt_state of the slave and on_rpdo which is a callback for handling pdo messages sent by the slave. (Check in canopen_base_driver.hpp there is some documentation and check in canopen_proxy_driver.cpp for how to use it)

@8vin8
Copy link
Author

8vin8 commented Aug 29, 2022

Hallo Christoph,

Thank you very much for your reply.
I will try to implement it.

@8vin8 8vin8 closed this as completed Aug 29, 2022
@tback123
Copy link

Hi there,

Appologies I am also a bit new when it comes to CanOpen and the ros2_canopen library. I'm trying to create my own device driver using the ProxyDriver (or BaseDrive, i don't really mind), and I understand how to implenent the class but am not sure where to actually init the driver.

The doc string in canopen_base_driver.cpp states the init function does the following

Initializes the driver, adds it to the CANopen Master.
This function needs to be executed inside the masters
event loop or the masters thread!

My question: Where is the 'masters event loop'? I currently just have a configuration package with some launch files? I feel like I might be missing something fundamental here.

Appologies for the question, and thankyou in advance for your help!

Regards

@tback123
Copy link

Hey @ipa-cmh - Sorry to tag but wasn't sure if you would see the above question with the issue closed. Would really appreciate any direction.

Regards,
Tom

@8vin8 8vin8 reopened this Sep 27, 2022
@hellantos
Copy link
Member

Hi Tom,

We are currently reworking the strucutre for custom device drivers. What kind of device do you want to write a driver for?

Best

@tback123
Copy link

Hey Christoph,

Thankyou for getting back to me :)

I'm writing a driver for a custom device (are using an implementation of the CanOpen stack on a in-house designed stm32 based board). The device only needs to be able to send and recieve PDO's at a very basic level, so don't need much 'fancy' functionality.

We've written a driver based on the proxy driver, and it looks good, but am just not sure where to add the deivce to the configuration or how to launch it. Using ROS2 Galactic for reference.

Thank you again,
Tom

@hellantos
Copy link
Member

hellantos commented Oct 13, 2022

Hi Tom,

Sorry for the late answer. You would need to make it a component. Once that is done, you should be able to include it into the bus.yaml file.

TO make it a component you need to add:

#include "rclcpp_components/register_node_macro.hpp"
RCLCPP_COMPONENTS_REGISTER_NODE([namespace]::[DriverClass])

To the bottom of your drivers .cpp file.

In your CMakeLists.txt you need to make your driver a shared lib and add something like this:

rclcpp_components_register_nodes(lifecycle_base_driver "ros2_canopen::LifecycleBaseDriver")
set(node_plugins "${node_plugins}ros2_canopen::LifecycleBaseDriver;$<TARGET_FILE:lifecycle_base_driver >\n")

Also make sure you install the libraries you create.

@8vin8
Copy link
Author

8vin8 commented Oct 28, 2022

Hello Team and @ipa-cmh ,

For mock slave i am using simple.eds and slave.cpp file. (implementation of simple incremental counter)

When I launch the master and mock slave, i am able to get the data on the CAN bus but i am not able to get the data via ros topics: /proxy_device/tpdo and /proxy_device/rpdo.

Maybe I am missing something and I would be thankful for your help.
I have attached the logs below.

ros2 topic list -t
/device_container_node/transition_event [lifecycle_msgs/msg/TransitionEvent]
/parameter_events [rcl_interfaces/msg/ParameterEvent]
/proxy_device/nmt_state [std_msgs/msg/String]
/proxy_device/rpdo [canopen_interfaces/msg/COData]
/proxy_device/tpdo [canopen_interfaces/msg/COData]
/proxy_device/transition_event [lifecycle_msgs/msg/TransitionEvent]
/rosout [rcl_interfaces/msg/Log]


ros2 topic echo /proxy_device/tpdo
NOTHING ON TERMINAL

ros2 topic echo /proxy_device/rpdo
NOTHING ON TERMINAL


when Launch file is launched

  • Output on terminal:

ros2 launch canopen_proxy canopen_proxy.launch.py
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [launch.user]: /home/x/canopen_ws/install/canopen_proxy/share/canopen_proxy/config/proxy/bus.yml
[INFO] [launch.user]: /home/x/canopen_ws/install/canopen_proxy/share/canopen_proxy/config/proxy/master.dcf
[INFO] [launch.user]:
[INFO] [launch.user]: can0
[INFO] [slave_node-1]: process started with pid [50973]
[INFO] [device_container_node-2]: process started with pid [50975]
[device_container_node-2] [INFO] [1666961498.657146739] [device_container_node]: Found 2 devices
[device_container_node-2] [INFO] [1666961498.657248964] [device_container_node]: Found Master.
[device_container_node-2] [INFO] [1666961498.657385324] [device_container_node]: Load Library: /home/x/canopen_ws/install/canopen_core/lib/libmaster_node.so
[slave_node-1] [INFO] [1666961498.658349875] [proxy_device]: Slave is running
[device_container_node-2] [INFO] [1666961498.659078628] [device_container_node]: Found class: rclcpp_components::NodeFactoryTemplate<ros2_canopen::MasterNode>
[device_container_node-2] [INFO] [1666961498.659108067] [device_container_node]: Instantiate class: rclcpp_components::NodeFactoryTemplate<ros2_canopen::MasterNode>
[device_container_node-2] [INFO] [1666961498.661542965] [device_container_node]: Added node of type ros2_canopen::MasterNode with name "master" for node_id 1 to executor.
[device_container_node-2] [INFO] [1666961498.661577411] [device_container_node]: Adding master with node id 1
[device_container_node-2] [INFO] [1666961498.661790229] [master]: Master Node is Running
[device_container_node-2] NMT: entering reset application state
[device_container_node-2] NMT: entering reset communication state
[device_container_node-2] NMT: running as master
[device_container_node-2] NMT: entering pre-operational state
[device_container_node-2] NMT: entering operational state
[device_container_node-2] [INFO] [1666961498.681989290] [device_container_node]: Found Driver ros2_canopen::ProxyDriver with lazy_load false
[device_container_node-2] [INFO] [1666961498.682142328] [device_container_node]: Load Library: /home/x/canopen_ws/install/canopen_proxy_driver/lib/libcanopen_proxy_driver.so
[device_container_node-2] [INFO] [1666961498.683327362] [device_container_node]: Found class: rclcpp_components::NodeFactoryTemplate<ros2_canopen::ProxyDriver>
[device_container_node-2] [INFO] [1666961498.683353935] [device_container_node]: Instantiate class: rclcpp_components::NodeFactoryTemplate<ros2_canopen::ProxyDriver>
[device_container_node-2] [INFO] [1666961498.685967862] [device_container_node]: Added node of type ros2_canopen::ProxyDriver with name "proxy_device" for node_id 2 to executor.
[device_container_node-2] [INFO] [1666961498.686000995] [device_container_node]: Adding ros2_canopen::ProxyDriver for node id 2 to master loop.
[device_container_node-2] [INFO] [1666961498.688092262] [device_container_node]: List of active components:
[device_container_node-2] [INFO] [1666961498.688129494] [device_container_node]: 1 : /master
[device_container_node-2] [INFO] [1666961498.688139502] [device_container_node]: 2 : /proxy_device
[device_container_node-2] [INFO] [1666961498.688147207] [device_container_node]: Initialisation successful.
[INFO] [launch.user]: node 'slave_node' reached the 'inactive' state, 'activating'.
[slave_node-1] NMT: entering reset application state
[slave_node-1] NMT: entering reset communication state
[slave_node-1] NMT: running as slave
[slave_node-1] NMT: entering pre-operational state
[slave_node-1] NMT: entering operational state
[device_container_node-2] [INFO] [1666961498.896069129] [proxy_device]: Slave 2: Switched NMT state to START


candump output on terminal:

candump can0
can0 701 [1] 00
can0 000 [2] 82 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 602 [8] 40 00 10 00 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 602 [8] 80 00 10 00 00 00 04 05
can0 602 [8] 40 00 10 00 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 602 [8] 80 00 10 00 00 00 04 05
can0 602 [8] 40 00 10 00 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 702 [1] 00
can0 202 [4] 00 00 00 00
can0 182 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 602 [8] 80 00 10 00 00 00 04 05
can0 602 [8] 40 00 10 00 00 00 00 00
can0 582 [8] 43 00 10 00 00 00 00 00
can0 602 [8] 40 18 10 01 00 00 00 00
can0 582 [8] 43 18 10 01 60 03 00 00
can0 602 [8] 2B 17 10 00 64 00 00 00
can0 582 [8] 60 17 10 00 00 00 00 00
can0 602 [8] 23 00 14 01 02 02 00 80
can0 582 [8] 60 00 14 01 00 00 00 00
can0 602 [8] 2F 00 14 02 01 00 00 00
can0 582 [8] 60 00 14 02 00 00 00 00
can0 602 [8] 2F 00 16 00 00 00 00 00
can0 582 [8] 60 00 16 00 00 00 00 00
can0 602 [8] 23 00 16 01 20 00 00 40
can0 582 [8] 60 00 16 01 00 00 00 00
can0 602 [8] 2F 00 16 00 01 00 00 00
can0 582 [8] 60 00 16 00 00 00 00 00
can0 602 [8] 23 00 14 01 02 02 00 00
can0 080 [0]
can0 582 [8] 60 00 14 01 00 00 00 00
can0 202 [4] 00 00 00 00
can0 602 [8] 23 00 18 01 82 01 00 80
can0 582 [8] 60 00 18 01 00 00 00 00
can0 602 [8] 2F 00 18 02 01 00 00 00
can0 582 [8] 60 00 18 02 00 00 00 00
can0 602 [8] 2F 00 1A 00 00 00 00 00
can0 582 [8] 60 00 1A 00 00 00 00 00
can0 602 [8] 23 00 1A 01 20 00 01 40
can0 582 [8] 60 00 1A 01 00 00 00 00
can0 602 [8] 2F 00 1A 00 01 00 00 00
can0 582 [8] 60 00 1A 00 00 00 00 00
can0 602 [8] 23 00 18 01 82 01 00 00
can0 582 [8] 60 00 18 01 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 182 [4] 00 00 00 00
can0 702 [1] 05
can0 080 [0]
can0 202 [4] 01 00 00 00
can0 182 [4] 02 00 00 00
can0 080 [0]
can0 202 [4] 01 00 00 00
can0 182 [4] 02 00 00 00
can0 080 [0]
can0 202 [4] 02 00 00 00
can0 182 [4] 02 00 00 00
can0 080 [0]
can0 202 [4] 02 00 00 00
can0 182 [4] 02 00 00 00
can0 080 [0]

@hellantos
Copy link
Member

Regarding the tpdo topic, this is only subscribed to. If you publish messages to it, it will send them via tpdo.

The rpdo topic is the one that should show something.
The call back for publishing can be found in canopen_proxy_driver/include/node_interfaces/node_canopen_proxy_driver_impl.hpp

template <class NODETYPE>
void NodeCanopenProxyDriver<NODETYPE>::on_rpdo(ros2_canopen::COData d)
{
	if (this->activated_.load())
	{
		RCLCPP_INFO(
			this->node_->get_logger(),
			"Slave %hhu: Sent PDO index %hu, subindex %hhu, data %x",
			this->lely_driver_->get_id(),
			d.index_,
			d.subindex_,
			d.data_);
		auto message = canopen_interfaces::msg::COData();
		message.index = d.index_;
		message.subindex = d.subindex_;
		message.data = d.data_;
		message.type = static_cast<uint8_t>(d.type_);
		rpdo_publisher->publish(message);
	}
}

This will fail silently when the driver is not marked as activated. This might be the issue.
I will create a launch test in canopen_tests for this. Currently we only cover sdos with tests.

@8vin8
Copy link
Author

8vin8 commented Nov 2, 2022

Hallo @ipa-cmh ,

Thank you very much for taking the time to read my concern and replying.
I will figure it out.
Regards,
Vin

@8vin8
Copy link
Author

8vin8 commented Nov 4, 2022

Hallo Team and @ipa-cmh,

I am using the Galactic branch, and was using OnRpdoWrite function which might caused the above problem of "no data on ros topic /proxy_device/rpdo. When I removed the function, its working fine.
Thank you and sorry for the miscommunication.

Logs attached below.


[device_container_node-2] [INFO] [1667566652.409385929] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 1
[device_container_node-2] [INFO] [1667566653.289790524] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 2
[device_container_node-2] [INFO] [1667566654.169310239] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 3
[device_container_node-2] [INFO] [1667566655.069411589] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 4
[device_container_node-2] [INFO] [1667566655.956112383] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 5
[device_container_node-2] [INFO] [1667566656.849876955] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 6
[device_container_node-2] [INFO] [1667566657.729956659] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 7
[device_container_node-2] [INFO] [1667566658.629411400] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 8
[device_container_node-2] [INFO] [1667566659.509752275] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data 9
[device_container_node-2] [INFO] [1667566660.410078682] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data a
[device_container_node-2] [INFO] [1667566661.295442698] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data b
[device_container_node-2] [INFO] [1667566662.170084811] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data c
[device_container_node-2] [INFO] [1667566663.070003330] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data d
[device_container_node-2] [INFO] [1667566663.949613915] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data e
[device_container_node-2] [INFO] [1667566664.829365550] [proxy_device]: Slave 2: Sent PDO index 16385, subindex 0, data f

can0 701 [1] 05
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00
can0 080 [0]
can0 202 [4] 00 00 00 00

ros2 topic echo /proxy_device/rpdo
index: 16385
subindex: 0
data: 12
type: 0

index: 16385
subindex: 0
data: 13
type: 0

index: 16385
subindex: 0
data: 14
type: 0

index: 16385
subindex: 0
data: 15
type: 0

@hellantos
Copy link
Member

@8vin8 great thanks for the heads up!

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

No branches or pull requests

3 participants