diff --git a/canopen/sphinx/application/diff_drive.rst b/canopen/sphinx/application/diff_drive.rst new file mode 100644 index 000000000..52a7fd314 --- /dev/null +++ b/canopen/sphinx/application/diff_drive.rst @@ -0,0 +1,2 @@ +Differential Drive Controller +============================= diff --git a/canopen/sphinx/application/trinamic.rst b/canopen/sphinx/application/trinamic.rst index a4330c93f..a289774b2 100644 --- a/canopen/sphinx/application/trinamic.rst +++ b/canopen/sphinx/application/trinamic.rst @@ -11,11 +11,14 @@ Getting started If you haven't already done so, follow the steps in the :doc:`../user-guide/configuration`. +To know more about how to create a configuration follow this steps: :doc:`../user-guide/how-to-create-a-configuration`. + Configuration ------------- - +- Create new package named ``trinamic_pd42_can``. To know how to create a package follow the documentation provided in `ROS2 `_ +- Follow the configuration folder tree steps as per the :doc:`../user-guide/configuration`. . - Create a new folder in the ``config`` folder of your configuration package. Name it ``single-pd42``. -- Download ``.eds`` file from `Trinamic `_ and place ``TMCM-1270.eds`` in the ``single-pd42`` folder. +- Download ``.eds`` file from `Trinamic Github `_ and place ``TMCM-1270.eds`` in the ``single-pd42`` folder. - Create a ``bus.yml`` file in the ``single-pd42`` folder with the following content: .. code-block:: yaml @@ -50,7 +53,7 @@ Configuration node_id: 1 -- Edit the ``CMakeLists.txt`` file in the ``config`` folder of your configuration package and add the following lines: +- Edit the ``CMakeLists.txt`` file in the package and add the following lines: .. code-block:: cmake @@ -93,7 +96,91 @@ Configuration ament_package() -- Create launch file in folder ``launch`` and add the following content: +- Create a source file in the ``src`` folder ``position_tick_motor.cpp`` and add the follow lines. + + .. code-block:: cpp + + + #include + #include + #include + + #include "canopen_interfaces/srv/co_target_double.hpp" + #include "rclcpp/rclcpp.hpp" + #include "std_srvs/srv/trigger.hpp" + int main(int argc, char * argv[]) + { + rclcpp::init(argc, argv); + + std::shared_ptr node = rclcpp::Node::make_shared("position_tick_motor_node"); + + RCLCPP_INFO(node->get_logger(), "Position Tick Motor Node Started"); + rclcpp::Client::SharedPtr init_client = + node->create_client("/trinamic_pd42/init"); + rclcpp::Client::SharedPtr mode_client = + node->create_client("/trinamic_pd42/cyclic_position_mode"); + rclcpp::Client::SharedPtr target_client = + node->create_client("/trinamic_pd42/target"); + + while (!init_client->wait_for_service(std::chrono::seconds(1)) && + !mode_client->wait_for_service(std::chrono::seconds(1)) && + !target_client->wait_for_service(std::chrono::seconds(1))) + { + if (!rclcpp::ok()) + { + RCLCPP_ERROR(node->get_logger(), "Interrupted while waiting for the service. Exiting."); + return 0; + } + RCLCPP_INFO(node->get_logger(), "service not available, waiting again..."); + } + + auto trigger_req = std::make_shared(); + auto result = init_client->async_send_request(trigger_req); + if (rclcpp::spin_until_future_complete(node, result) == rclcpp::FutureReturnCode::SUCCESS) + { + RCLCPP_INFO(node->get_logger(), "Init service called successfully"); + } + else + { + RCLCPP_ERROR(node->get_logger(), "Failed to call init service"); + } + + result = mode_client->async_send_request(trigger_req); + if (rclcpp::spin_until_future_complete(node, result) == rclcpp::FutureReturnCode::SUCCESS) + { + RCLCPP_INFO(node->get_logger(), "Config position mode service called successfully"); + } + else + { + RCLCPP_ERROR(node->get_logger(), "Failed to call config service"); + } + + RCLCPP_INFO(node->get_logger(), "Starting to send target values"); + + auto targer_req = std::make_shared(); + double target = 0; + while (rclcpp::ok()) + { + targer_req->target = target; + auto res = target_client->async_send_request(targer_req); + if (rclcpp::spin_until_future_complete(node, res) == rclcpp::FutureReturnCode::SUCCESS) + { + RCLCPP_INFO(node->get_logger(), "Set Target: %.2f", target); + } + else + { + RCLCPP_ERROR(node->get_logger(), "Failed to call target service"); + } + rclcpp::sleep_for(std::chrono::seconds(1)); + + target += 1.0; + if (target >= 105.0) target = 0; + } + + return 0; + } + +- Create a launch file ``file_name.launch.py`` in folder ``launch`` and add the following content: .. code-block:: python @@ -168,7 +255,7 @@ Configuration Running the example ------------------- -To begin, follow the instructions for :doc:`../quickstart/operation`, which can be done using either a virtual or peak CAN interface. +To begin, follow the instructions for :doc:`../quickstart/setup-network`, which can be done using either a virtual or peak CAN interface. If you prefer to use a real CAN interface, you will need to modify the launch file by changing the ``can_interface_name`` argument to ``can0``. Additionally, if you are using real hardware, you should comment out the fake slave launch by adding a *#* in front of the line *ld.add_action(slave_node_1)*. diff --git a/canopen/sphinx/examples/service-interface-examples.rst b/canopen/sphinx/examples/service-interface-examples.rst new file mode 100644 index 000000000..c00604d49 --- /dev/null +++ b/canopen/sphinx/examples/service-interface-examples.rst @@ -0,0 +1,66 @@ +Service Interface Examples +========================== + +Before running these examples, ensure that to :ref:`start the vcan0 interface `. +You can find these examples in the ``canopen_test`` package. + +Proxy Driver Examples +--------------------- +A proxy driver provides a simple way to forward CANopen functionalities for a specific device using ROS2 services and messages. For more details on the proxy driver, see :doc:`../user-guide/proxy-driver`. + +Configuring ``bus.yaml`` +~~~~~~~~~~~~~~~~~~~~~~~~ +The configuration for the proxy driver is specified in the ``bus.yaml`` file. Here's an example configuration: + +.. code-block:: yaml + + options: + dcf_path: "@BUS_CONFIG_PATH@" + + master: + node_id: 1 + driver: "ros2_canopen::MasterDriver" + package: "canopen_master_driver" + + defaults: + dcf: "simple.eds" + driver: "ros2_canopen::ProxyDriver" + package: "canopen_proxy_driver" + polling: true + period: 10 + + nodes: + proxy_device_1: + node_id: 2 + proxy_device_2: + node_id: 3 + +For further details about the configuration, refer to :doc:`../user-guide/configuration`. Additionally, add ``cogen_dcf(simple)`` in the *CMakeLists.txt* file to generate the necessary artifacts for the proxy driver. + +Running the Proxy Driver Examples +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +To launch the proxy driver setup, use the following command: + +.. code-block:: bash + + $ ros2 launch canopen_tests proxy_setup.launch.py + +Verify that all services are available by running the ROS2 topic and service list commands. To conduct a test: + +.. code-block:: bash + + $ ros2 topic pub /proxy_device_1/tpdo canopen_interfaces/msg/COData "{ index: 0x4000, subindex: 0, data: 200 }" + +Check the output by running: + +.. code-block:: bash + + $ ros2 topic echo /proxy_device_1/rpdo + +.. note:: + + These examples use a fake slave device. Running on actual hardware may yield different results. + Always refer to the device's documentation for specific details. + +CiA402 Driver Examples +----------------------- diff --git a/canopen/sphinx/index.rst b/canopen/sphinx/index.rst index 01a3abc0d..25a579a3d 100644 --- a/canopen/sphinx/index.rst +++ b/canopen/sphinx/index.rst @@ -9,7 +9,7 @@ This is the documentation of the ROS2 CANopen stack. :glob: quickstart/installation - quickstart/operation + quickstart/setup-network quickstart/examples .. toctree:: @@ -17,14 +17,17 @@ This is the documentation of the ROS2 CANopen stack. :caption: User Guide :glob: - user-guide/operation - user-guide/configuration - user-guide/master - user-guide/proxy-driver - user-guide/cia402-driver - user-guide/how-to-create-a-configuration - user-guide/how-to-create-a-cia301-system - user-guide/how-to-create-a-robot-system + user-guide/1_operation + user-guide/2_interface + user-guide/3_configuration + user-guide/4_how_to_guide + +.. toctree:: + :maxdepth: 1 + :caption: Examples + :glob: + + examples/service-interface-examples .. toctree:: @@ -37,7 +40,8 @@ This is the documentation of the ROS2 CANopen stack. developers-guide/architecture developers-guide/new-driver developers-guide/new-master - API Reference + developers-guide/new-device-manager + API Reference .. toctree:: :maxdepth: 1 diff --git a/canopen/sphinx/quickstart/installation.rst b/canopen/sphinx/quickstart/installation.rst index 35fc07c8d..589a112ee 100644 --- a/canopen/sphinx/quickstart/installation.rst +++ b/canopen/sphinx/quickstart/installation.rst @@ -1,11 +1,36 @@ Installation =============================== -Clone ros2_canopen into your ROS2 workspace's source folder, install dependencies and -build with colcon and your done. +- Clone ros2_canopen into your ROS2 workspace's source folder, install dependencies and build with colcon and your done. +- In order to create a workspace + +.. code-block:: console + + $ mkdir -p ~/name_ws/src + $ cd ~/name_ws/src + +.. note:: + Change the ``name_ws`` to your desired workspace name. .. code-block:: console $ git clone https://github.com/ros-industrial/ros2_canopen.git $ cd .. + $ source /opt/ros/ros_distro/setup.bash # Replace the *ros distro as per your need. $ rosdep install --from-paths src/ros2_canopen --ignore-src -r -y $ colcon build + $ source install/setup.bash + +.. note:: + Kindly check the branch as per your configuration before cloning the repository. + +Testing with pre-release binaries +--------------------------------- +To test the package with pre-release binaries, you must first set up your ROS2 workspace to use the ROS2 pre-release repositories. +To do this, follow the instructions +`here `_ . +After that, you can install the packages using the following command, + +.. code-block:: console + + $ sudo apt update + $ sudo apt install ros--canopen # Replace with your ROS2 distro diff --git a/canopen/sphinx/quickstart/operation.rst b/canopen/sphinx/quickstart/setup-network.rst similarity index 72% rename from canopen/sphinx/quickstart/operation.rst rename to canopen/sphinx/quickstart/setup-network.rst index 9229fbf96..d3ff5aa0e 100644 --- a/canopen/sphinx/quickstart/operation.rst +++ b/canopen/sphinx/quickstart/setup-network.rst @@ -2,6 +2,16 @@ Setup CAN Controller ==================== .. _quick-start-setup-can-controller: +To interact with the CAN controller you can use ``can-utils`` in order to know the output of the controller. + +.. code-block:: console + + $ sudo apt install can-utils + $ candump + +.. note:: + This step is only required in order to know the output of the controller. One can skip this step to proceed with the setup of the controller. + **Option 1**: Virtual CANController .. code-block:: console @@ -11,6 +21,7 @@ Setup CAN Controller $ sudo ip link set vcan0 txqueuelen 1000 $ sudo ip link set up vcan0 + **Option 2**: Peak CANController .. code-block:: console diff --git a/canopen/sphinx/user-guide/1_operation.rst b/canopen/sphinx/user-guide/1_operation.rst new file mode 100644 index 000000000..573a471ea --- /dev/null +++ b/canopen/sphinx/user-guide/1_operation.rst @@ -0,0 +1,10 @@ +Operations +========== + +.. toctree:: + :maxdepth: 1 + :caption: Operation + :glob: + + 1_operation/1_operation_modes + 1_operation/2_operation_interface diff --git a/canopen/sphinx/user-guide/2_interface.rst b/canopen/sphinx/user-guide/2_interface.rst new file mode 100644 index 000000000..8c2269162 --- /dev/null +++ b/canopen/sphinx/user-guide/2_interface.rst @@ -0,0 +1,15 @@ +Interfaces +========== + + +.. toctree:: + :maxdepth: 1 + :caption: Configuration + :glob: + + 2_interface/1_interface_overview + 2_interface/2_master_interface + 2_interface/3_proxy_interface + 2_interface/4_cia402_interface + 2_interface/5_ros2_control_interface + 2_interface/6_ros2_controllers diff --git a/canopen/sphinx/user-guide/3_configuration.rst b/canopen/sphinx/user-guide/3_configuration.rst new file mode 100644 index 000000000..334a0ef47 --- /dev/null +++ b/canopen/sphinx/user-guide/3_configuration.rst @@ -0,0 +1,11 @@ +Configuration +============== + +.. toctree:: + :maxdepth: 1 + :caption: Configuration + :glob: + + 3_configuration/1_bus_configuration + 3_configuration/2_cmake_configuration + 3_configuration/3_device_configuration diff --git a/canopen/sphinx/user-guide/3_configuration/1_bus_configuration.rst b/canopen/sphinx/user-guide/3_configuration/1_bus_configuration.rst new file mode 100644 index 000000000..9c160a909 --- /dev/null +++ b/canopen/sphinx/user-guide/3_configuration/1_bus_configuration.rst @@ -0,0 +1,2 @@ +Bus Configuration +================= diff --git a/canopen/sphinx/user-guide/4_how_to_guide.rst b/canopen/sphinx/user-guide/4_how_to_guide.rst new file mode 100644 index 000000000..9c79b573a --- /dev/null +++ b/canopen/sphinx/user-guide/4_how_to_guide.rst @@ -0,0 +1,2 @@ +How to create your own CANopen Package +====================================== diff --git a/canopen/sphinx/user-guide/cia402-driver.rst b/canopen/sphinx/user-guide/_old/cia402-driver.rst similarity index 100% rename from canopen/sphinx/user-guide/cia402-driver.rst rename to canopen/sphinx/user-guide/_old/cia402-driver.rst diff --git a/canopen/sphinx/user-guide/configuration.rst b/canopen/sphinx/user-guide/_old/configuration.rst similarity index 92% rename from canopen/sphinx/user-guide/configuration.rst rename to canopen/sphinx/user-guide/_old/configuration.rst index 6c17704ab..9adbaf36b 100644 --- a/canopen/sphinx/user-guide/configuration.rst +++ b/canopen/sphinx/user-guide/_old/configuration.rst @@ -9,13 +9,13 @@ Consequently, the structure of the configuration package should look as follows: :: - {package_name} + {package_name} ├── config │ ├── {bus_config_name_1} - │ | ├── bus.yml - │ | ├── {device1}.eds - │ | ├── {device...}.eds - │ | └── {slave_n}.eds + │ │ ├── bus.yml + │ │ ├── {device1}.eds + │ │ ├── {device...}.eds + │ │ └── {slave_n}.eds │ └── {bus_config_name_2} │ ├── bus.yml │ ├── {device1}.eds @@ -23,14 +23,14 @@ Consequently, the structure of the configuration package should look as follows: │ └── {slave_n}.eds ├── launch │ ├── {bus_config_name_1}.launch.py - | └── {bus_config_name_1}.launch.py + │ └── {bus_config_name_1}.launch.py ├── CMakeLists.txt └── package.xml - +See section :doc:`how-to-create-a-configuration` for more details. Bus Configuration File -============================ +----------------------- The ros2_canopen stack relies on a YAML configuration file that is used for configuring the bus topology and specifying configurations for @@ -39,7 +39,7 @@ EDS/DCF file applies to them, which parameters of the EDS/DCF files should be overwritten and which drivers should be used to control the devices. Structure ---------- +'''''''''' The YAML configuration file has the following sections: @@ -63,7 +63,7 @@ The YAML configuration file has the following sections: Options Section ---------------- +'''''''''''''''' The options section holds general options. Right now these are only the following. .. csv-table:: Options Configuration @@ -77,7 +77,7 @@ The options section holds general options. Right now these are only the followin Master Section --------------- +'''''''''''''''' The master section has a number of configuration options. These are not unique to ros2_canopen but come from the lely core library. Below you find a list of possible configuration items. @@ -113,8 +113,8 @@ but come from the lely core library. Below you find a list of possible configura boot_time; The timeout for booting mandatory slaves in ms (default: 0, see object 1F89). boot_timeout; The timeout for booting all slaves in ms (default: 2000ms). -Device Section --------------- +Defaults Section +'''''''''''''''''' The device configuration enables configuring the characteristics of the connected CANopen device. @@ -157,19 +157,11 @@ device. Further references ------------------- +################### The dcfgen documentation gives more details on the usage of the dcfgen tool for generating DCF: https://opensource.lely.com/canopen/docs/dcf-tools/ -Variables ---------- - -``@BUS_CONFIG_PATH@:`` Automatic config path definition if configuration package structure is followed. - - - - Configuration Package CMake -=========================== +--------------------------- In order to build the configuration package and generate the necessary runtime artifacts from the bus configuration file and eds/dcf files, the lely_core_libraries package contains an extra @@ -177,7 +169,7 @@ CMAKE macro. **cogen_dcf(target)** -Target: the name of the configuration (e.g. for config/{bus_config_name_1} is bus_config_name_1) +*Target: the name of the configuration (e.g. for config/{bus_config_name_1} is bus_config_name_1)* .. code-block:: diff --git a/canopen/sphinx/user-guide/how-to-create-a-cia301-system.rst b/canopen/sphinx/user-guide/_old/how-to-create-a-cia301-system.rst similarity index 100% rename from canopen/sphinx/user-guide/how-to-create-a-cia301-system.rst rename to canopen/sphinx/user-guide/_old/how-to-create-a-cia301-system.rst diff --git a/canopen/sphinx/user-guide/how-to-create-a-configuration.rst b/canopen/sphinx/user-guide/_old/how-to-create-a-configuration.rst similarity index 100% rename from canopen/sphinx/user-guide/how-to-create-a-configuration.rst rename to canopen/sphinx/user-guide/_old/how-to-create-a-configuration.rst diff --git a/canopen/sphinx/user-guide/how-to-create-a-robot-system.rst b/canopen/sphinx/user-guide/_old/how-to-create-a-robot-system.rst similarity index 100% rename from canopen/sphinx/user-guide/how-to-create-a-robot-system.rst rename to canopen/sphinx/user-guide/_old/how-to-create-a-robot-system.rst diff --git a/canopen/sphinx/user-guide/master.rst b/canopen/sphinx/user-guide/_old/master.rst similarity index 100% rename from canopen/sphinx/user-guide/master.rst rename to canopen/sphinx/user-guide/_old/master.rst diff --git a/canopen/sphinx/user-guide/_old/operation.rst b/canopen/sphinx/user-guide/_old/operation.rst new file mode 100644 index 000000000..602c5af99 --- /dev/null +++ b/canopen/sphinx/user-guide/_old/operation.rst @@ -0,0 +1,57 @@ +Operation of the ROS2 CANopen Stack +=================================== + +The ROS2 CANopen stack provides flexible operation modes tailored to various application requirements. It can be configured in one of the following three ways: + +1. Simple Nodes Container +2. Managed Nodes Container +3. ROS 2 Control System Interface + +Simple Nodes Container +---------------------- +The Simple Nodes Container bundles the master with all slave driver nodes into a specialized container known as the device container. All nodes within +this container are simple ROS 2 nodes, offering publish, subscribe, and service interfaces. Once the device container is launched, all contained nodes +are immediately operational. + +**Purpose**: This container is designed for scenarios requiring a straightforward, easy-to-launch interface without the need for real-time control, +such as those offered by *ros2_control*. + +For more information on configuring and utilizing these interfaces, see :doc:`operation/service-interface`. + +Managed Nodes Container +----------------------- +The Managed Nodes Container operates similarly to the Simple Nodes Container, with the key difference being the use of lifecycle nodes and a dedicated +lifecycle manager. This manager allows for sophisticated control over the lifecycle of all nodes in the container, enhancing fault recovery and system manageability. +For more information on lifecycle nodes, refer to the `ROS 2 Node Lifecycle documentation `_. + +**Purpose**: Ideal for applications demanding enhanced runtime recovery options beyond simple restarts. + +For more information on configuring and utilizing these interfaces, see :doc:`operation/managed-service-interface`. + +ROS 2 Control System Interface +------------------------------ +Built on the foundation of the Simple Nodes Container, the ROS 2 Control System Interface integrates a hardware interface that facilitates direct control +over devices connected on the bus. It supports several system interfaces designed for specific control needs: + +- canopen_ros2_control/CANopenSystem +- canopen_ros2_control/CIA402System +- canopen_ros2_control/RobotSystem + +**Purpose**: These interfaces are suitable for applications requiring precise, low-latency control mechanisms. + +For more information on configuring and utilizing these interfaces, refer to :doc:`operation/ros2-control-interface`. + +Requirements for Setting Up the ROS2 CANopen Stack +-------------------------------------------------- +To start with ROS2 CANOpen Stack, you need to have the following prerequisites: + +To effectively implement and utilize the ROS2 CANopen stack, certain prerequisites must be met. Below is a comprehensive list of these requirements: + +1. **EDS or DCF Files**: You'll need the Electronic Data Sheet (EDS) or Device Configuration File (DCF) for each CANopen device. These files contain + crucial device-specific parameters and configuration details necessary for communication and operational functionality. + +2. **bus.yml File Configuration**: Prepare the ``bus.yml`` file, which outlines the bus topology and device-specific settings. This configuration file should specify details such as which devices are connected, the relevant EDS/DCF files, parameter overrides, and driver assignments for each device. + +3. **Network Configuration**: Set up and configure your network to match the requirements of your CANopen devices and the ROS2 CANopen stack. See :doc:`../quickstart/setup-network` + +These are the basic requirements, and continue with the following sections to learn more about the operation modes and how to set up the ROS2 CANopen stack. diff --git a/canopen/sphinx/user-guide/_old/operation/managed-service-interface.rst b/canopen/sphinx/user-guide/_old/operation/managed-service-interface.rst new file mode 100644 index 000000000..133a8fdd4 --- /dev/null +++ b/canopen/sphinx/user-guide/_old/operation/managed-service-interface.rst @@ -0,0 +1,50 @@ +Managed Service Interface +========================= + +Device Container with Managed Nodes +----------------------------------- +The device container operates as a ROS2 component manager with load and unload services disabled. It utilizes the Bus Configuration File (``bus.yml``) to +load devices. This container also offers a list service, which can be utilized with ros2cli to verify the loaded components. + +.. figure:: ../../images/device-manager.png + :alt: Device Manager Concept + + Overview of the device manager concept. + +Upon startup, the device container uses the bus description file to identify and load the appropriate drivers for each device, +including the CANopen master node. Initially, the nodes are in an unconfigured state. + +The default launch files from the ``canopen_core`` package automatically initiate the lifecycle manager node, which orchestrates +the sequencing and state transitions of all nodes within the container. Activating the lifecycle manager progresses all nodes from an +unconfigured to an active state in a predetermined sequence. + +.. note:: + + For custom implementations, it is crucial to configure and activate the master node before setting up any driver nodes to ensure proper system functionality. + +Bus Configuration +----------------- +The bus configuration specific to this interface must incorporate driver classes designated as lifecycle drivers. The master driver within +this setup dictates whether the ``bus.yml`` is considered a managed or an unmanaged service interface. + +.. csv-table:: Available Driver Components + :header: "Package", "Component" + + canopen_master_driver, ros2_canopen::LifecycleMasterDriver + canopen_proxy_driver, ros2_canopen::LifecycleProxyDriver + canopen_402_driver, ros2_canopen::LifecycleCia402Driver + +Launching Parameters +-------------------- +The device manager's operation is guided by several crucial configuration parameters: + +.. csv-table:: Configuration Parameters + :header: "Parameter", "Type", "Description" + + bus_conf, string, (Mandatory) Path to the bus configuration YAML-file + master_dcf, string, (Mandatory) Path to the DCF file for the master node, typically generated by dcfgen as master.dcf. + master_bin, string, (Optional) Path to the concise DCF (.bin) file for master configuration, typically generated by dcfgen as master.bin. (default: "") + can_interface_name, string, (Mandatory) Name of the CAN interface to be used. (default: "vcan0") + +This section outlines the configuration and management of nodes within the ROS2 CANopen architecture, emphasizing the importance of lifecycle management +for robust device interaction and control. diff --git a/canopen/sphinx/user-guide/_old/operation/ros2-control-interface.rst b/canopen/sphinx/user-guide/_old/operation/ros2-control-interface.rst new file mode 100644 index 000000000..d6583e50d --- /dev/null +++ b/canopen/sphinx/user-guide/_old/operation/ros2-control-interface.rst @@ -0,0 +1,64 @@ +Hardware Interface +------------------ +This package provides multiple hardware interfaces for testing. Mainly the following: + +- canopen_ros2_control/CanopenSystem: A system interface for ProxyDrivers +- canopen_ros2_control/Cia402System: A system interface for Cia402Drivers +- canopen_ros2_control/RobotSystem: A system interface for Cia402Drivers in a robot configuration. + + +Robot System Interface +---------------------- +The Robot System Interface utilizes information from the robot's URDF (Unified Robot Description Format) to configure +and manage Cia402Drivers via the ros2_control hardware interface. The system configuration is determined by the ``bus.yml`` +file, and each joint's associated CANopen device is specified using the ``node_id``. + +**Configuration Example**: + +.. code-block:: xml + + + + canopen_ros2_control/RobotSystem + [path to bus.yml] + [path to master.dcf] + [can interface to be used] + [master.bin if it exists] + + + 3 + ... + + + 4 + ... + + + +.. note:: + For practical implementation examples, refer to the `canopen_tests` package. + +ROS2 Controllers +---------------- +The package provides several controllers optimized for different setups within the ROS2 framework: + +- **canopen_ros2_controllers/Cia402RobotController**: Integrates seamlessly with the Robot System Interface. +- **canopen_ros2_controllers/Cia402DeviceController**: Compatible with the Cia402System, facilitating device-specific controls. +- **canopen_ros2_controllers/CanopenProxyController**: Works with both CanopenSystem and Cia402System interfaces, providing versatile control options. + +Robot Controller Configuration +------------------------------ +The Robot Controller simplifies the operation of robotic joints, automatically managing their states through the ros2_controller lifecycle. +Once activated, the controller ensures that all drives are operational without requiring further user intervention. + +**Configuration Parameters**: + +.. code-block:: yaml + + robot_controller: + ros__parameters: + joints: # List of joints controlled by the controller + - joint1 + - joint2 + operation_mode: 1 # Operational mode of the controller + command_poll_freq: 5 # Frequency (Hz) at which the controller polls for command feedback diff --git a/canopen/sphinx/user-guide/operation/service-interface.rst b/canopen/sphinx/user-guide/_old/operation/service-interface.rst similarity index 100% rename from canopen/sphinx/user-guide/operation/service-interface.rst rename to canopen/sphinx/user-guide/_old/operation/service-interface.rst diff --git a/canopen/sphinx/user-guide/proxy-driver.rst b/canopen/sphinx/user-guide/_old/proxy-driver.rst similarity index 100% rename from canopen/sphinx/user-guide/proxy-driver.rst rename to canopen/sphinx/user-guide/_old/proxy-driver.rst diff --git a/canopen/sphinx/user-guide/operation.rst b/canopen/sphinx/user-guide/operation.rst deleted file mode 100644 index b683aa2f0..000000000 --- a/canopen/sphinx/user-guide/operation.rst +++ /dev/null @@ -1,48 +0,0 @@ -Operation -========= - -The ros2_canopen stack can be used in three different ways: - -* standard nodes container -* managed nodes container -* ros2_control system interface with standard nodes - - -Simple nodes container -"""""""""""""""""""""""" -The standard node container mode bundles the master and all slave driver nodes in one specialised -container called device container. All nodes are simple ROS 2 nodes and expose a publish and subscribe -as well as a service interfaces. Once the device container is started, all nodes are brought up -and ready to be used. - -**Purpose**: -The simple nodes container is thought for applications where the user needs a simple and -easy to launch interface and does not need any realtime control capabilities as provided by -ros2_control. - -Managed nodes container -"""""""""""""""""""""""""" -The managed nodes container has the same properties as the standard nodes container. -The exception is, that all nodes are lifecycle nodes and there is a special node called -lifecycle manager. The user can use the lifecycle manager to control the lifecycle of -all nodes in the container. - -**Purpose**: -The managed nodes container is thought for applications where the user wants to have -more runtime recovery options than killing and restarting the container. - - -ROS 2 control system interface -"""""""""""""""""""""""""""""" -The ros2_control interface is currently build on top of the simple nodes container. In -addition to the standard nodes container the ros2_control system interface provides a -hardware interface that can be used to control the devices on the bus. Currently, three -different system interfaces are provided: - -* canopen_ros2_control/CANopenSystem -* canopen_ros2_control/CIA402System -* canopen_ros2_control/RobotSystem - -**Purpose**: -The ROS 2 control system interfaces are thought for control applications that require -low latencies. diff --git a/canopen/sphinx/user-guide/operation/managed-service-interface.rst b/canopen/sphinx/user-guide/operation/managed-service-interface.rst deleted file mode 100644 index e7962b486..000000000 --- a/canopen/sphinx/user-guide/operation/managed-service-interface.rst +++ /dev/null @@ -1,52 +0,0 @@ -Managed Service Interface -============================ - - -Device Container with managed nodes -""""""""""""""""""""""""""""""""""" -The device container implements ROS2 component manager. The load and unload services are disabled. -Devices are loaded based on the Bus Configuration File (bus.yml). The device container provides -the list service, which can be used with ros2cli to check which components have been loaded. - -.. figure:: ../../images/device-manager.png - :alt: Device Manager Concept - - device manager concept - -The device container uses the bus description file to identify the correct drivers for each devices. -On launch it will load the CANopen master node and driver nodes and pass the appropriate configuration -data to the nodes. The nodes are now in unconfigured state. - -When using the default launch files in canopen_core the lifecycle manager node will automatically -be launched. The lifecycle manager takes care of sequencing the lifecycle of the different nodes in the -device container. By bringing the lifecycle_manager to active lifecycle state, all master and driver nodes -will be activated in correct sequence. - -If you choose to write your own lifecycle_manager, you'll need to remember, that the master needs -to be configured and activated before any driver node can be configured or activated. - - -Bus Configuration -""""""""""""""""" -The bus configuration for the managed service interface needs to use the driver classes that are marked as -lifecycle drivers. The master driver indicates whether the bus.yml will be treated as managed or un-managed -service interface. - -.. csv-table:: Available Driver Components - :header: "Package", "Component" - - canopen_master_driver, ros2_canopen::LifecycleMasterDriver - canopen_proxy_driver, ros2_canopen::LifecycleProxyDriver - canopen_402_driver, ros2_canopen::LifecycleCia402Driver - -Launching -""""""""""""" -The device manager has the following configuration parameters. - -.. csv-table:: Parameters - :header: "Parameter", "Type", "Description" - - bus_conf, string, (Mandatory) Path to the bus configuration YAML-file - master_dcf, string, (Mandatory) Path to the DCF file to be used by the master node. Usually generated by dcfgen as master.dcf. - master_bin, string, (Optional) Path to the concise DCF (.bin) file to be used to configure the master. Usually generated by dcfgen as master.bin. (default: "") - can_interface_name, string, (Mandatory) Name of the CAN interface to be used. (default: vcan0) diff --git a/canopen/sphinx/user-guide/operation/ros2-control-interface.rst b/canopen/sphinx/user-guide/operation/ros2-control-interface.rst deleted file mode 100644 index 5a9b66bd0..000000000 --- a/canopen/sphinx/user-guide/operation/ros2-control-interface.rst +++ /dev/null @@ -1,73 +0,0 @@ -Hardware Interface ------------------- -This package provides multiple hardware interfaces for testing. Mainly the following: - -- canopen_ros2_control/CanopenSystem: A system interface for ProxyDrivers -- canopen_ros2_control/Cia402System: A system interface for Cia402Drivers -- canopen_ros2_control/Cia402RobotSystem: A system interface for Cia402Drivers in a robot configuration (under development) - - -Robot System Interface -'''''''''''''''''''''' - -The robot system interface takes a number of inputs from the robot description (urdf). -It will make the Cia402Drivers available via the ros2_control hardware interface. -The bus has to still be defined in the bus.yml file. In the urdf you can the choose the -CANopen nodes that have a Cia402Driver attached to them. - -The ros2_control interface only works with non-lifecycle drivers right now. -For each joint in your urdf you can choose the attached CANopen device by using the -``node_id`` parameter. The ``node_id`` parameter is the CANopen node id of the device. - -.. code-block:: xml - - - - canopen_ros2_control/Cia402RobotSystem - [path to bus.yml] - [path to master.dcf] - [can interface to be used] - [master.bin if it exists] - - - 3 - ... - - - 3 - ... - - - -.. note:: - - You can find an example for the configuration in the ``canopen_tests`` package under robot_control. - - -ROS2 Controllers ----------------- -This package provides multiple controllers for testing. Mainly the following: - -- canopen_ros2_controllers/Cia402RobotController: Works with Robot System Interface -- canopen_ros2_controllers/Cia402DeviceController: Works with Cia402System -- canopen_ros2_controllers/CanopenProxyController: Works with CanopenSystem and Cia402System - -Robot Controller -'''''''''''''''' - -The robot controller enables bringing up the different joints of the robot automatically -by using the ros2_controller lifecycle. There is no need for further action, once the -controller is activated, the drives are ready to be used. - -The robot controller can be configured in the ros2_controllers.yaml with the following -parameters: - -.. code-block:: yaml - - robot_controller: - ros__parameters: - joints: # joints that are controlled by the controller - - joint1 - - joint2 - operation_mode: 1 # operation mode of the controller - command_poll_freq: 5 # frequency with which the controller polls for command feedback diff --git a/canopen_tests/CMakeLists.txt b/canopen_tests/CMakeLists.txt index f2f7c052a..8374bf3d9 100644 --- a/canopen_tests/CMakeLists.txt +++ b/canopen_tests/CMakeLists.txt @@ -10,7 +10,7 @@ find_package(ament_cmake REQUIRED) find_package(lely_core_libraries REQUIRED) -generate_dcf(simple) +cogen_dcf(simple) generate_dcf(canopen_system) cogen_dcf(cia402_system) cogen_dcf(cia402_namespaced_system) diff --git a/canopen_tests/config/simple/bus.yml b/canopen_tests/config/simple/bus.yml index 8b26d4e88..cc8bc0ae1 100644 --- a/canopen_tests/config/simple/bus.yml +++ b/canopen_tests/config/simple/bus.yml @@ -6,18 +6,15 @@ master: driver: "ros2_canopen::MasterDriver" package: "canopen_master_driver" -proxy_device_1: - node_id: 2 +defaults: dcf: "simple.eds" driver: "ros2_canopen::ProxyDriver" package: "canopen_proxy_driver" polling: true period: 10 -proxy_device_2: - node_id: 3 - dcf: "simple.eds" - driver: "ros2_canopen::ProxyDriver" - package: "canopen_proxy_driver" - polling: true - period: 10 +nodes: + proxy_device_1: + node_id: 2 + proxy_device_2: + node_id: 3