├── .gitignore
├── ethercat_driver_ros2_examples.repos
├── ethercat_driver_ros2_examples
├── CMakeLists.txt
└── package.xml
├── ethercat_force_sensor
├── config
│ ├── easycat_config
│ │ ├── ForceSensor.bin
│ │ ├── ForceSensor.prj
│ │ ├── log_configuration.txt
│ │ ├── ForceSensor.h
│ │ ├── ForceSensor.ino
│ │ └── ForceSensor.xml
│ ├── controllers.yaml
│ └── slave_config.yaml
├── description
│ ├── config
│ │ └── force_sensor.config.xacro
│ └── ros2_control
│ │ └── force_sensor.ros2_control.xacro
├── CMakeLists.txt
├── package.xml
├── launch
│ └── force_sensor.launch.py
└── README.md
├── ethercat_slave_description
├── CMakeLists.txt
├── config
│ ├── omron
│ │ ├── omron_nx_ecc201_nx_od5256.yaml
│ │ └── omron_nx_ecc201_nx_id5442.yaml
│ ├── beckhoff
│ │ ├── beckhoff_el4132.yaml
│ │ ├── beckhoff_el2124.yaml
│ │ ├── beckhoff_el4134.yaml
│ │ ├── beckhoff_el3102.yaml
│ │ ├── beckhoff_el1008.yaml
│ │ ├── beckhoff_el1018.yaml
│ │ ├── beckhoff_el2008.yaml
│ │ ├── beckhoff_el2088.yaml
│ │ ├── beckhoff_el5101.yaml
│ │ └── beckhoff_el3104.yaml
│ ├── schneider
│ │ └── schneider_atv320.yaml
│ ├── advantech
│ │ ├── advantech_amax5051.yaml
│ │ └── advantech_amax5056.yaml
│ ├── ati
│ │ └── ati_ftsensor.yaml
│ ├── elmo
│ │ └── elmo_gold.yaml
│ ├── maxon
│ │ └── maxon_epos3.yaml
│ ├── technosoft
│ │ └── technosoft_ipos3604.yaml
│ └── synapticon
│ │ └── synapticon_somanet_circulo9.yaml
├── package.xml
└── README.md
├── ethercat_motor_drive
├── description
│ ├── config
│ │ └── motor_drive.config.xacro
│ └── ros2_control
│ │ └── motor_drive.ros2_control.xacro
├── CMakeLists.txt
├── package.xml
├── config
│ ├── controllers.yaml
│ ├── maxon_epos3_config.yaml
│ └── maxon_epos4_50_5_config.yaml
├── README.md
└── launch
│ └── motor_drive.launch.py
├── .docker
├── README.md
└── Dockerfile
├── .github
├── dependabot.yml
└── workflows
│ ├── ci-format.yml
│ └── ci.yml
├── README.md
├── CONTRIBUTING.md
├── .pre-commit-config.yaml
└── LICENSE
/.gitignore:
--------------------------------------------------------------------------------
1 | build/
2 | install/
3 | log/
4 | .vscode/
5 |
--------------------------------------------------------------------------------
/ethercat_driver_ros2_examples.repos:
--------------------------------------------------------------------------------
1 | repositories:
2 | ethercat_driver_ros2:
3 | type: git
4 | url: https://github.com/ICube-Robotics/ethercat_driver_ros2.git
5 | version: main
6 |
--------------------------------------------------------------------------------
/ethercat_driver_ros2_examples/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(ethercat_driver_ros2_examples NONE)
3 | find_package(ament_cmake REQUIRED)
4 | ament_package()
5 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/easycat_config/ForceSensor.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ICube-Robotics/ethercat_driver_ros2_examples/HEAD/ethercat_force_sensor/config/easycat_config/ForceSensor.bin
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/controllers.yaml:
--------------------------------------------------------------------------------
1 | controller_manager:
2 | ros__parameters:
3 | update_rate: 100 # Hz
4 |
5 | joint_state_broadcaster:
6 | type: joint_state_broadcaster/JointStateBroadcaster
7 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/easycat_config/ForceSensor.prj:
--------------------------------------------------------------------------------
1 | ForceSensor
2 | OUTPUTS_TAG
3 | INPUTS_TAG
4 | force_0
5 | int16_t
6 | force_1
7 | int16_t
8 | INFO_TAG
9 | 0x0000079A
10 | AB&T
11 | 0xDEADBEEF
12 | 0x00000001
13 | ForceSensor
14 | END_TAG
15 |
--------------------------------------------------------------------------------
/ethercat_slave_description/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(ethercat_slave_description)
3 | find_package(ament_cmake REQUIRED)
4 |
5 | install(
6 | DIRECTORY config
7 | DESTINATION share/${PROJECT_NAME}
8 | )
9 |
10 | ament_package()
11 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/description/config/motor_drive.config.xacro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/description/config/force_sensor.config.xacro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.docker/README.md:
--------------------------------------------------------------------------------
1 | # EtherCAT Driver ROS2 Docker Containers
2 | Provides a basic preconfigured docker container for development purposes. To use it, make sure you have [Docker](https://docs.docker.com/get-docker/) installed, then build and run the image :
3 |
4 | ```shell
5 | $ docker build --tag ethercat_driver:humble --file .docker/Dockerfile .
6 | $ docker run -it --privileged --network=host ethercat_driver:humble
7 | ```
8 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(ethercat_force_sensor)
3 | find_package(ament_cmake REQUIRED)
4 | find_package(rclcpp REQUIRED)
5 | find_package(ethercat_driver REQUIRED)
6 | find_package(ethercat_interface REQUIRED)
7 | find_package(ethercat_generic_slave REQUIRED)
8 |
9 | install(
10 | DIRECTORY config description launch
11 | DESTINATION share/${PROJECT_NAME}
12 | )
13 |
14 | ament_package()
15 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/slave_config.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for EasyCAT based ForceSensor Slave
2 | vendor_id: 0x0000079a
3 | product_id: 0xdeadbeef
4 | tpdo: # TxPDO
5 | - index: 0x1a00
6 | channels:
7 | - {index: 0x0006, sub_index: 1, type: int16, state_interface: force.0}
8 | - {index: 0x0006, sub_index: 2, type: int16, state_interface: force.1}
9 | sm: # Sync Manager
10 | - {index: 0, type: input, pdo: tpdo, watchdog: disable}
11 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.8)
2 | project(ethercat_motor_drive)
3 | find_package(ament_cmake REQUIRED)
4 | find_package(rclcpp REQUIRED)
5 | find_package(ethercat_driver REQUIRED)
6 | find_package(ethercat_interface REQUIRED)
7 | find_package(ethercat_generic_cia402_drive REQUIRED)
8 |
9 | install(
10 | DIRECTORY config description launch
11 | DESTINATION share/${PROJECT_NAME}
12 | )
13 |
14 | ament_package()
15 |
--------------------------------------------------------------------------------
/.docker/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG ROS_DISTRO="humble"
2 | FROM ros:${ROS_DISTRO}
3 |
4 | COPY . /ros2_dev/ethercat_driver_ros2_examples
5 |
6 | RUN apt update && \
7 | apt install autoconf libtool -y
8 | RUN mkdir ec_dev && cd ec_dev && \
9 | git clone https://gitlab.com/etherlab.org/ethercat.git && \
10 | cd ethercat && \
11 | git checkout stable-1.5 && \
12 | ./bootstrap && \
13 | ./configure --prefix=/usr/local/etherlab --disable-kernel && \
14 | make && make install
15 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/omron/omron_nx_ecc201_nx_od5256.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Omron NX ECC201 with id5442
2 | # Description : Omron EtherCAT Coupler NX_ECC201 with NX_OD5256 16-ch Digital Output module
3 | vendor_id: 0x00000083
4 | product_id: 0x00000083
5 | rpdo: #RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
6 | - index: 0x1604
7 | channels:
8 | - {index: 0x7022, sub_index: 0x01, type: uint16, command_interface: d_output}
9 | sm: # Sync Manager
10 | - {index: 2, type: output, pdo: rpdo, watchdog: disable}
11 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 | - package-ecosystem: "github-actions"
9 | # Workflow files stored in the
10 | # default location of `.github/workflows`
11 | directory: "/"
12 | schedule:
13 | interval: "weekly"
14 |
--------------------------------------------------------------------------------
/.github/workflows/ci-format.yml:
--------------------------------------------------------------------------------
1 | # This is a format job. Pre-commit has a first-party GitHub action, so we use
2 | # that: https://github.com/pre-commit/action
3 |
4 | name: Format
5 |
6 | on:
7 | workflow_dispatch:
8 | pull_request:
9 |
10 | jobs:
11 | pre-commit:
12 | name: Format
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v3
16 | - uses: actions/setup-python@v5.1.0
17 | with:
18 | python-version: '3.10'
19 | - name: Install system hooks
20 | run: sudo apt install -qq clang-format-14 cppcheck
21 | - uses: pre-commit/action@v3.0.1
22 | with:
23 | extra_args: --all-files --hook-stage manual
24 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el4132.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL4132
2 | # Description : EtherCAT Terminal, 2-channel analog output, voltage, ±10 V, 16 bit.
3 | vendor_id: 0x00000002
4 | product_id: 0x10243052
5 | rpdo: # RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
6 | - index: 0x1600
7 | channels:
8 | - {index: 0x3001, sub_index: 0x01, type: int16, command_interface: analog_output.1, factor: 3276.7}
9 | - index: 0x1601
10 | channels:
11 | - {index: 0x3002, sub_index: 0x01, type: int16, command_interface: analog_output.2, factor: 3276.7}
12 | sm: # Sync Manager
13 | - {index: 2, type: output, pdo: rpdo, watchdog: enable}
14 |
--------------------------------------------------------------------------------
/ethercat_driver_ros2_examples/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ethercat_driver_ros2_examples
5 | 0.0.1
6 | Meta-package aggregating the ethercat_driver_ros2_examples packages and documentation
7 | Maciej Bednarczyk
8 | Apache License 2.0
9 |
10 | ament_cmake
11 | ethercat_force_sensor
12 |
13 |
14 | ament_cmake
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ethercat_motor_drive
5 | 0.0.1
6 | Package with instructions for running an EtherCAT compatible motor drive and use it in ROS2
7 | Maciej Bednarczyk
8 | Apache License 2.0
9 |
10 | ament_cmake
11 | ethercat_driver
12 | ethercat_interface
13 | ethercat_generic_cia402_drive
14 |
15 |
16 | ament_cmake
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ethercat_force_sensor
5 | 0.0.1
6 | Package with instructions for building a custom Force Sensor EtherCAT slave using strain gauges and EasyCAT and use it in ROS2
7 | Maciej Bednarczyk
8 | Apache License 2.0
9 |
10 | ament_cmake
11 | ethercat_driver
12 | ethercat_interface
13 | ethercat_generic_slave
14 |
15 |
16 | ament_cmake
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/config/controllers.yaml:
--------------------------------------------------------------------------------
1 | controller_manager:
2 | ros__parameters:
3 | update_rate: 100 # Hz
4 |
5 | joint_state_broadcaster:
6 | type: joint_state_broadcaster/JointStateBroadcaster
7 |
8 | trajectory_controller:
9 | type: joint_trajectory_controller/JointTrajectoryController
10 |
11 | velocity_controller:
12 | type: velocity_controllers/JointGroupVelocityController
13 |
14 | effort_controller:
15 | type: effort_controllers/JointGroupEffortController
16 |
17 | trajectory_controller:
18 | ros__parameters:
19 | command_interfaces:
20 | - position
21 | state_interfaces:
22 | - position
23 | joints:
24 | - joint_1
25 |
26 | velocity_controller:
27 | ros__parameters:
28 | joints:
29 | - joint_1
30 |
31 | effort_controller:
32 | ros__parameters:
33 | joints:
34 | - joint_1
35 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el2124.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL2124
2 | # Description : EtherCAT Terminal, 4-channel digital output, 5 V DC, 20 mA.
3 | vendor_id: 0x00000002
4 | product_id: 0x084c3052
5 | rpdo: # RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
6 | - index: 0x1600
7 | channels:
8 | - {index: 0x7000, sub_index: 0x01, type: bool, mask: 1, command_interface: d_output.1}
9 | - index: 0x1601
10 | channels:
11 | - {index: 0x7010, sub_index: 0x01, type: bool, mask: 2, command_interface: d_output.2}
12 | - index: 0x1602
13 | channels:
14 | - {index: 0x7020, sub_index: 0x01, type: bool, mask: 4, command_interface: d_output.3}
15 | - index: 0x1603
16 | channels:
17 | - {index: 0x7030, sub_index: 0x01, type: bool, mask: 8, command_interface: d_output.4}
18 | sm: # Sync Manager
19 | - {index: 0, type: output, pdo: rpdo, watchdog: enable}
20 |
--------------------------------------------------------------------------------
/ethercat_slave_description/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ethercat_slave_description
5 | 0.0.1
6 | Description package for EtherCAT slave modules
7 | Maciej Bednarczyk
8 | Apache-2.0
9 |
10 | ament_cmake
11 |
12 | ethercat_driver
13 | ethercat_interface
14 | ethercat_generic_slave
15 | ethercat_generic_cia402_drive
16 |
17 | ament_lint_auto
18 | ament_lint_common
19 |
20 |
21 | ament_cmake
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/description/ros2_control/force_sensor.ros2_control.xacro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ethercat_driver/EthercatDriver
9 | 0
10 | 100
11 |
12 |
13 |
14 |
15 |
16 |
17 | ethercat_generic_plugins/GenericEcSlave
18 | 0
19 | 0
20 | $(find ethercat_force_sensor)/config/slave_config.yaml
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el4134.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL4134
2 | # Description : EtherCAT Terminal, 4-channel analog output, voltage, ±10 V, 16 bit.
3 |
4 | vendor_id: 0x00000002
5 | product_id: 0x10263052
6 | rpdo: # RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
7 | - index: 0x1600
8 | channels:
9 | - {index: 0x7000, sub_index: 0x01, type: int16, command_interface: analog_output.1, factor: 3276.7}
10 | - index: 0x1601
11 | channels:
12 | - {index: 0x7010, sub_index: 0x01, type: int16, command_interface: analog_output.2, factor: 3276.7}
13 | - index: 0x1602
14 | channels:
15 | - {index: 0x7020, sub_index: 0x01, type: int16, command_interface: analog_output.3, factor: 3276.7}
16 | - index: 0x1603
17 | channels:
18 | - {index: 0x7030, sub_index: 0x01, type: int16, command_interface: analog_output.4, factor: 3276.7}
19 |
20 | sm: # Sync Manager
21 | - {index: 2, type: output, pdo: rpdo, watchdog: enable}
22 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el3102.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL3102
2 | # Description : EtherCAT Terminal, 2-channel analog input, voltage, ±10 V, 16 bit, differential.
3 | vendor_id: 0x00000002
4 | product_id: 0x0c1e3052
5 | tpdo: # TxPDO = transmit PDO Mapping (slave to ROS control, Master In From Slave Out -MISO-)
6 | - index: 0x1a00
7 | channels:
8 | - {index: 0x3101, sub_index: 0x01, type: uint8}
9 | - {index: 0x3101, sub_index: 0x02, type: int16, state_interface: analog_input.1, factor: 0.000305185}
10 | - index: 0x1a01
11 | channels:
12 | - {index: 0x3102, sub_index: 0x01, type: uint8}
13 | - {index: 0x3102, sub_index: 0x02, type: int16, state_interface: analog_input.2, factor: 0.000305185}
14 | sm: # Sync Manager
15 | - {index: 0, type: output, pdo: ~, watchdog: disable}
16 | - {index: 1, type: input, pdo: ~, watchdog: disable}
17 | - {index: 2, type: output, pdo: ~, watchdog: disable}
18 | - {index: 3, type: input, pdo: tpdo, watchdog: disable}
19 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/schneider/schneider_atv320.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Schneider ATV320 drive
2 | # Description: Velocity Control only
3 | vendor_id: 0x0800005a
4 | product_id: 0x00000389
5 | assign_activate: 0x0300 # DC Synch register
6 | auto_fault_reset: false # true = automatic fault reset, false = fault reset on rising edge command interface "reset_fault"
7 | rpdo: # RxPDO = receive PDO Mapping (ROS control to motor drive, Master Out to Slave In -MOSI-)
8 | - index: 0x1600
9 | channels:
10 | - {index: 0x6040, sub_index: 0x00, type: uint16, default: 0} # Control word
11 | - {index: 0x6042, sub_index: 0x00, type: int16, command_interface: velocity, default: 0} # Target velocity
12 | tpdo: # TxPDO = transmit PDO Mapping (motor drive to ROS control, Master In From Slave Out -MISO-)
13 | - index: 0x1a00
14 | channels:
15 | - {index: 0x6041, sub_index: 0x00, type: uint16} # Status word
16 | - {index: 0x6044, sub_index: 0x00, type: int16, state_interface: velocity} # Velocity actual value
17 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/advantech/advantech_amax5051.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Advantech AMAX-5051
2 | # Description : 8-ch Digital Input EtherCAT Slice IO Module
3 | vendor_id: 0x000013FE
4 | product_id: 0x00035051
5 | tpdo: # TxPDO = transmit PDO Mapping (slave to ROS control, Master In From Slave Out -MISO-)
6 | - index: 0x1a00
7 | channels:
8 | - {index: 0x3001, sub_index: 0x01, type: bool, mask: 1, state_interface: d_input.1}
9 | - {index: 0x3001, sub_index: 0x02, type: bool, mask: 2, state_interface: d_input.2}
10 | - {index: 0x3001, sub_index: 0x03, type: bool, mask: 4, state_interface: d_input.3}
11 | - {index: 0x3001, sub_index: 0x04, type: bool, mask: 8, state_interface: d_input.4}
12 | - {index: 0x3001, sub_index: 0x05, type: bool, mask: 16, state_interface: d_input.5}
13 | - {index: 0x3001, sub_index: 0x06, type: bool, mask: 32, state_interface: d_input.6}
14 | - {index: 0x3001, sub_index: 0x07, type: bool, mask: 64, state_interface: d_input.7}
15 | - {index: 0x3001, sub_index: 0x08, type: bool, mask: 128, state_interface: d_input.8}
16 | sm: # Sync Manager
17 | - {index: 0, type: input, pdo: tpdo, watchdog: disable}
18 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/description/ros2_control/motor_drive.ros2_control.xacro:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ethercat_driver/EthercatDriver
9 | 0
10 | 100
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | ethercat_generic_plugins/EcCiA402Drive
21 | 0
22 | 0
23 | 8
24 | $(find ethercat_motor_drive)/config/maxon_epos3_config.yaml
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/advantech/advantech_amax5056.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Advantech AMAX-5056
2 | # Description : 8-ch Sink-type Digital Output EtherCAT Slice IO Module
3 | vendor_id: 0x000013FE
4 | product_id: 0x00035056
5 | rpdo: # RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
6 | - index: 0x1600
7 | channels:
8 | - {index: 0x3101, sub_index: 0x01, type: bool, mask: 1, command_interface: d_output.1}
9 | - {index: 0x3101, sub_index: 0x02, type: bool, mask: 2, command_interface: d_output.2}
10 | - {index: 0x3101, sub_index: 0x03, type: bool, mask: 4, command_interface: d_output.3}
11 | - {index: 0x3101, sub_index: 0x04, type: bool, mask: 8, command_interface: d_output.4}
12 | - {index: 0x3101, sub_index: 0x05, type: bool, mask: 16, command_interface: d_output.5}
13 | - {index: 0x3101, sub_index: 0x06, type: bool, mask: 32, command_interface: d_output.6}
14 | - {index: 0x3101, sub_index: 0x07, type: bool, mask: 64, command_interface: d_output.7}
15 | - {index: 0x3101, sub_index: 0x08, type: bool, mask: 128, command_interface: d_output.8}
16 | sm: # Sync Manager
17 | - {index: 0, type: output, pdo: rpdo, watchdog: enable}
18 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/omron/omron_nx_ecc201_nx_id5442.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Omron NX ECC201 with id5442
2 | # Description : Omron EtherCAT Coupler NX_ECC201 with NX_ID5442 16-ch Digital Input module
3 | vendor_id: 0x00000083
4 | product_id: 0x00000083
5 | rpdo: #RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
6 | - index: 0x1604
7 | channels:
8 | - {index: 0x7022, sub_index: 0x01, type: uint16}
9 | tpdo: # TxPDO = transmit PDO Mapping (slave to ROS control, Master In From Slave Out -MISO-)
10 | - index: 0x1bf8
11 | channels:
12 | - {index: 0x3003, sub_index: 0x04, type: bit128}
13 | - {index: 0x3006, sub_index: 0x04, type: bit128}
14 | - index: 0x1bff
15 | channels:
16 | - {index: 0x2002, sub_index: 0x01, type: uint8}
17 | - index: 0x1bf4
18 | channels:
19 | - {index: 0x0000, sub_index: 0x00, type: bit8}
20 | - index: 0x1a00
21 | channels:
22 | - {index: 0x6002, sub_index: 0x01, type: uint16, state_interface: d_input}
23 | sm: # Sync Manager
24 | - {index: 0, type: output, pdo: ~, watchdog: disable}
25 | - {index: 1, type: input, pdo: ~, watchdog: disable}
26 | - {index: 2, type: output, pdo: rpdo, watchdog: disable}
27 | - {index: 3, type: input, pdo: tpdo, watchdog: disable}
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ethercat_driver_ros2_examples
2 | [](https://opensource.org/licenses/Apache-2.0)
3 | [](https://github.com/ICube-Robotics/ethercat_driver_ros2_examples/actions/workflows/ci.yml)
4 |
5 | Example repository for the [EtherCAT Driver ROS2 stack](https://github.com/ICube-Robotics/ethercat_driver_ros2).
6 |
7 | This repository contains the following example packages :
8 | - EtherCAT compatible CIA402 motor drive (example using Maxon EPOS3)
9 | - Custom Force Sensor EtherCAT slave using strain gauges and EasyCAT
10 | - Example configuration files for the some EtherCAT modules
11 |
12 | ## Contacts ##
13 | 
14 |
15 | [ICube Laboratory](https://icube.unistra.fr), [University of Strasbourg](https://www.unistra.fr/), France
16 |
17 | __Manuel Yguel:__ [yguel@unistra.fr](mailto:yguel@unistra.fr), @github: [yguel](https://github.com/yguel)
18 |
19 | __Laurent Barbé:__ [laurent.barbe@unistra.fr](mailto:laurent.barbe@unistra.fr)
20 |
21 | __Philippe Zanne:__ [philippe.zanne@unistra.fr](mailto:philippe.zanne@unistra.fr)
22 |
23 | __Maciej Bednarczyk:__ [m.bednarczyk@unistra.fr](mailto:m.bednarczyk@unistra.fr), @github: [mcbed](https://github.com/mcbed)
24 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el1008.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL1008
2 | # Description : EtherCAT Terminal, 8-channel digital input, 24 V DC, 3 ms.
3 | vendor_id: 0x00000002
4 | product_id: 0x03f03052
5 | tpdo: # TxPDO = transmit PDO Mapping (slave to ROS control, Master In From Slave Out -MISO-)
6 | - index: 0x1a00
7 | channels:
8 | - {index: 0x6000, sub_index: 0x01, type: bool, mask: 1, state_interface: d_input.1}
9 | - index: 0x1a01
10 | channels:
11 | - {index: 0x6010, sub_index: 0x01, type: bool, mask: 2, state_interface: d_input.2}
12 | - index: 0x1a02
13 | channels:
14 | - {index: 0x6020, sub_index: 0x01, type: bool, mask: 4, state_interface: d_input.3}
15 | - index: 0x1a03
16 | channels:
17 | - {index: 0x6030, sub_index: 0x01, type: bool, mask: 8, state_interface: d_input.4}
18 | - index: 0x1a04
19 | channels:
20 | - {index: 0x6040, sub_index: 0x01, type: bool, mask: 16, state_interface: d_input.5}
21 | - index: 0x1a05
22 | channels:
23 | - {index: 0x6050, sub_index: 0x01, type: bool, mask: 32, state_interface: d_input.6}
24 | - index: 0x1a06
25 | channels:
26 | - {index: 0x6060, sub_index: 0x01, type: bool, mask: 64, state_interface: d_input.7}
27 | - index: 0x1a07
28 | channels:
29 | - {index: 0x6070, sub_index: 0x01, type: bool, mask: 128, state_interface: d_input.8}
30 | sm: # Sync Manager
31 | - {index: 0, type: input, pdo: tpdo, watchdog: disable}
32 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el1018.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL1018
2 | # Description : EtherCAT Terminal, 8-channel digital input, 24 V DC, 10 us.
3 | vendor_id: 0x00000002
4 | product_id: 0x03fa3052
5 | tpdo: # TxPDO = transmit PDO Mapping (slave to ROS control, Master In From Slave Out -MISO-)
6 | - index: 0x1a00
7 | channels:
8 | - {index: 0x6000, sub_index: 0x01, type: bool, mask: 1, state_interface: d_input.1}
9 | - index: 0x1a01
10 | channels:
11 | - {index: 0x6010, sub_index: 0x01, type: bool, mask: 2, state_interface: d_input.2}
12 | - index: 0x1a02
13 | channels:
14 | - {index: 0x6020, sub_index: 0x01, type: bool, mask: 4, state_interface: d_input.3}
15 | - index: 0x1a03
16 | channels:
17 | - {index: 0x6030, sub_index: 0x01, type: bool, mask: 8, state_interface: d_input.4}
18 | - index: 0x1a04
19 | channels:
20 | - {index: 0x6040, sub_index: 0x01, type: bool, mask: 16, state_interface: d_input.5}
21 | - index: 0x1a05
22 | channels:
23 | - {index: 0x6050, sub_index: 0x01, type: bool, mask: 32, state_interface: d_input.6}
24 | - index: 0x1a06
25 | channels:
26 | - {index: 0x6060, sub_index: 0x01, type: bool, mask: 64, state_interface: d_input.7}
27 | - index: 0x1a07
28 | channels:
29 | - {index: 0x6070, sub_index: 0x01, type: bool, mask: 128, state_interface: d_input.8}
30 | sm: # Sync Manager
31 | - {index: 0, type: input, pdo: tpdo, watchdog: disable}
32 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el2008.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL2008
2 | # Description : EtherCAT Terminal, 8-channel digital output, 24 V DC, 0.5 A.
3 | vendor_id: 0x00000002
4 | product_id: 0x07d83052
5 | rpdo: # RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
6 | - index: 0x1600
7 | channels:
8 | - {index: 0x7000, sub_index: 0x01, type: bool, mask: 1, command_interface: d_output.1}
9 | - index: 0x1601
10 | channels:
11 | - {index: 0x7010, sub_index: 0x01, type: bool, mask: 2, command_interface: d_output.2}
12 | - index: 0x1602
13 | channels:
14 | - {index: 0x7020, sub_index: 0x01, type: bool, mask: 4, command_interface: d_output.3}
15 | - index: 0x1603
16 | channels:
17 | - {index: 0x7030, sub_index: 0x01, type: bool, mask: 8, command_interface: d_output.4}
18 | - index: 0x1604
19 | channels:
20 | - {index: 0x7040, sub_index: 0x01, type: bool, mask: 16, command_interface: d_output.5}
21 | - index: 0x1605
22 | channels:
23 | - {index: 0x7050, sub_index: 0x01, type: bool, mask: 32, command_interface: d_output.6}
24 | - index: 0x1606
25 | channels:
26 | - {index: 0x7060, sub_index: 0x01, type: bool, mask: 64, command_interface: d_output.7}
27 | - index: 0x1607
28 | channels:
29 | - {index: 0x7070, sub_index: 0x01, type: bool, mask: 128, command_interface: d_output.8}
30 | sm: # Sync Manager
31 | - {index: 0, type: output, pdo: rpdo, watchdog: enable}
32 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el2088.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL2088
2 | # Description : EtherCAT Terminal, 8-channel digital output, 24 V DC, 0.5 A, ground switching.
3 | vendor_id: 0x00000002
4 | product_id: 0x08283052
5 | rpdo: # RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
6 | - index: 0x1600
7 | channels:
8 | - {index: 0x7000, sub_index: 0x01, type: bool, mask: 1, command_interface: d_output.1}
9 | - index: 0x1601
10 | channels:
11 | - {index: 0x7010, sub_index: 0x01, type: bool, mask: 2, command_interface: d_output.2}
12 | - index: 0x1602
13 | channels:
14 | - {index: 0x7020, sub_index: 0x01, type: bool, mask: 4, command_interface: d_output.3}
15 | - index: 0x1603
16 | channels:
17 | - {index: 0x7030, sub_index: 0x01, type: bool, mask: 8, command_interface: d_output.4}
18 | - index: 0x1604
19 | channels:
20 | - {index: 0x7040, sub_index: 0x01, type: bool, mask: 16, command_interface: d_output.5}
21 | - index: 0x1605
22 | channels:
23 | - {index: 0x7050, sub_index: 0x01, type: bool, mask: 32, command_interface: d_output.6}
24 | - index: 0x1606
25 | channels:
26 | - {index: 0x7060, sub_index: 0x01, type: bool, mask: 64, command_interface: d_output.7}
27 | - index: 0x1607
28 | channels:
29 | - {index: 0x7070, sub_index: 0x01, type: bool, mask: 128, command_interface: d_output.8}
30 | sm: # Sync Manager
31 | - {index: 0, type: output, pdo: rpdo, watchdog: enable}
32 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/ati/ati_ftsensor.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for ATI EtherCAT F/T Sensor
2 | # Description : ATI EtherCAT F/T Sensor
3 | vendor_id: 0x00000732
4 | product_id: 0x26483052
5 | rpdo: # RxPDO
6 | - index: 0x1601
7 | channels:
8 | - {index: 0x7010, sub_index: 0x01, type: uint32} # Control 1
9 | - {index: 0x7010, sub_index: 0x02, type: uint32} # Control 2
10 | tpdo: # TxPDO
11 | - index: 0x1a00
12 | channels:
13 | - {index: 0x6000, sub_index: 0x01, type: int32, state_interface: force.x, factor: 1e-6, offset: 0.0} # Fx/Gage0
14 | - {index: 0x6000, sub_index: 0x02, type: int32, state_interface: force.y, factor: 1e-6, offset: 0.0} # Fy/Gage1
15 | - {index: 0x6000, sub_index: 0x03, type: int32, state_interface: force.z, factor: 1e-6, offset: 0.0} # Fz/Gage2
16 | - {index: 0x6000, sub_index: 0x04, type: int32, state_interface: torque.x, factor: 1e-6, offset: 0.0} # Tx/Gage3
17 | - {index: 0x6000, sub_index: 0x05, type: int32, state_interface: torque.y, factor: 1e-6, offset: 0.0} # Ty/Gage4
18 | - {index: 0x6000, sub_index: 0x06, type: int32, state_interface: torque.z, factor: 1e-6, offset: 0.0} # Tz/Gage5
19 | - {index: 0x6010, sub_index: 0x00, type: uint32} # Status Code
20 | - {index: 0x6020, sub_index: 0x00, type: uint32} # Sample Counter
21 | sm: # Sync Manager
22 | - {index: 0, type: output, pdo: ~, watchdog: disable}
23 | - {index: 1, type: input, pdo: ~, watchdog: disable}
24 | - {index: 2, type: output, pdo: rpdo, watchdog: enable}
25 | - {index: 3, type: input, pdo: tpdo, watchdog: disable}
26 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/easycat_config/log_configuration.txt:
--------------------------------------------------------------------------------
1 |
2 | Easy Configurator, configuration engine V_3_3
3 |
4 | log created on Thu Apr 13 11:45:58 2023
5 |
6 | Analyzing the project file
7 |
8 | Easy Configurator project ForceSensor.prj
9 |
10 | OUTPUTS_TAG
11 | INPUTS_TAG
12 | Line 5 --- force_0 int16_t
13 | Line 6 --- force_1 int16_t
14 | INFO_TAG
15 | 0x0000079A
16 | AB&T
17 | 0xDEADBEEF
18 | 0x00000001
19 | ForceSensor
20 | ForceSensor
21 | END_TAG
22 |
23 | The ForceSensor.prj configuration file is correct
24 |
25 | ByteNumOut 0
26 | ByteNumIn 4
27 | PdoNumOut 0
28 | PdoNumIn 2
29 |
30 | Creating the ForceSensor.xml file
31 |
32 | PROJECT_TAG ForceSensor.prj
33 | VENDOID_TAG 0000079A
34 | VEN_NAM_TAG AB&T
35 | PRO_COD_TAG DEADBEEF
36 | REVISIO_TAG 00000001
37 | DEV_NAM_TAG ForceSensor
38 | DEV_NAM_TAG ForceSensor
39 |
40 | FIRST_TAG
41 |
42 | Input entries
43 |
44 | #x6
45 | 1
46 | 16
47 | force_0
48 | INT
49 |
50 |
51 | #x6
52 | 2
53 | 16
54 | force_1
55 | INT
56 |
57 |
58 | LAST_TAG
59 |
60 | The ForceSensor.xml file has been created
61 |
62 | Creating the ForceSensor.h file
63 |
64 | #define CUST_BYTE_NUM_OUT 0
65 | #define CUST_BYTE_NUM_IN 4
66 | #define TOT_BYTE_NUM_ROUND_OUT 0
67 | #define TOT_BYTE_NUM_ROUND_IN 4
68 |
69 |
70 | Output entries
71 |
72 | Input entries
73 | int16_t force_0;
74 | int16_t force_1;
75 |
76 | The ForceSensor.h file has been created
77 |
78 | Creating the ForceSensor.bin file
79 |
80 |
81 | The ForceSensor.bin file has been created
82 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/easycat_config/ForceSensor.h:
--------------------------------------------------------------------------------
1 | // Copyright 2023, ICube Laboratory, University of Strasbourg
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | #ifndef ETHERCAT_FORCE_SENSOR__CONFIG__EASYCAT_CONFIG__FORCESENSOR_H_
16 | #define ETHERCAT_FORCE_SENSOR__CONFIG__EASYCAT_CONFIG__FORCESENSOR_H_
17 |
18 | //-------------------------------------------------------------------//
19 | // //
20 | // This file has been created by the Easy Configurator tool //
21 | // //
22 | // Easy Configurator project ForceSensor.prj
23 | // //
24 | //-------------------------------------------------------------------//
25 |
26 |
27 | #define CUST_BYTE_NUM_OUT 0
28 | #define CUST_BYTE_NUM_IN 4
29 | #define TOT_BYTE_NUM_ROUND_OUT 0
30 | #define TOT_BYTE_NUM_ROUND_IN 4
31 |
32 | //---- output buffer ----
33 | typedef union {
34 | uint8_t Byte[TOT_BYTE_NUM_ROUND_OUT];
35 | struct
36 | {
37 | } Cust;
38 | } PROCBUFFER_OUT;
39 |
40 | //---- input buffer ----
41 | typedef union {
42 | uint8_t Byte[TOT_BYTE_NUM_ROUND_IN];
43 | struct
44 | {
45 | int16_t force_0;
46 | int16_t force_1;
47 | } Cust;
48 | } PROCBUFFER_IN;
49 |
50 | #endif // ETHERCAT_FORCE_SENSOR__CONFIG__EASYCAT_CONFIG__FORCESENSOR_H_
51 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/elmo/elmo_gold.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Elmo Gold drive
2 | vendor_id: 0x0000009a
3 | product_id: 0x00030924
4 | assign_activate: 0x0300 # DC Synch register
5 | period: 100 # Hz
6 | auto_fault_reset: false # true = automatic fault reset, false = fault reset on rising edge command interface "reset_fault"
7 | sdo: # sdo data to be transferred at drive startup
8 | - {index: 0x60C2, sub_index: 1, type: int8, value: 10} # Set interpolation time for cyclic modes to 10 ms
9 | - {index: 0x60C2, sub_index: 2, type: int8, value: -3} # Set base 10-3s
10 | - {index: 0x6098, sub_index: 0, type: int8, value: 35}
11 | rpdo: # RxPDO = receive PDO Mapping (ROS control to motor drive, Master Out to Slave In -MOSI-)
12 | - index: 0x1607
13 | channels:
14 | - {index: 0x607a, sub_index: 0, type: int32, command_interface: position, default: .nan} # Target position
15 | - {index: 0x60ff, sub_index: 0, type: int32, command_interface: velocity, default: 0} # Target velocity
16 | - {index: 0x6071, sub_index: 0, type: int16, command_interface: effort, default: -5} # Target torque
17 | - {index: 0x6072, sub_index: 0, type: int16, default: 1000} # Max torque
18 | - {index: 0x6040, sub_index: 0, type: uint16, default: 0} # Control word
19 | - {index: 0x6060, sub_index: 0, type: int8, default: 8} # Mode of operation
20 | tpdo: # TxPDO = transmit PDO Mapping (motor drive to ROS control, Master In From Slave Out -MISO-)
21 | - index: 0x1a07
22 | channels:
23 | - {index: 0x6064, sub_index: 0, type: int32, state_interface: position} # Position actual value
24 | - {index: 0x606c, sub_index: 0, type: int32, state_interface: velocity} # Velocity actual value
25 | - {index: 0x6077, sub_index: 0, type: int16, state_interface: effort} # Torque actual value
26 | - {index: 0x6041, sub_index: 0, type: uint16} # Status word
27 | - {index: 0x6061, sub_index: 0, type: int8} # Mode of operation display
28 | - {index: 0x2205, sub_index: 1, type: int16, state_interface: analog_input1} # Analog input
29 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/README.md:
--------------------------------------------------------------------------------
1 | # ethercat_motor_drive
2 |
3 | This repository contains the instructions for running an EtherCAT compatible motor drive and use it in ROS2 with [EtherCAT Driver ROS2 stack](https://github.com/ICube-Robotics/ethercat_driver_ros2).
4 |
5 | ## Required Hardware ##
6 | - Maxon EPOS3 motor drive
7 | - Compatible DC motor with encoder
8 |
9 | ## Usage ##
10 | ***Required setup : Ubuntu 22.04 LTS***
11 |
12 | 1. Install `ros2` packages. The current development is based of `ros2 humble`. Installation steps are described [here](https://docs.ros.org/en/humble/Installation.html).
13 | 2. Source your `ros2` environment:
14 | ```shell
15 | source /opt/ros/humble/setup.bash
16 | ```
17 | **NOTE**: The ros2 environment needs to be sources in every used terminal. If only one distribution of ros2 is used, it can be added to the `~/.bashrc` file.
18 | 3. Install `colcon` and its extensions :
19 | ```shell
20 | sudo apt install python3-colcon-common-extensions
21 | ```
22 | 3. Create a new ros2 workspace:
23 | ```shell
24 | mkdir ~/ros2_ws/src
25 | ```
26 | 4. Pull relevant packages, install dependencies, compile, and source the workspace by using:
27 | ```shell
28 | cd ~/ros2_ws
29 | git clone https://github.com/ICube-Robotics/ethercat_driver_ros2_examples.git src/ethercat_driver_ros2_examples
30 | vcs import src < ethercat_driver_ros2_examples.repos
31 | rosdep install --ignore-src --from-paths . -y -r
32 | colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --symlink-install --packages-select ethercat_motor_drive
33 | source install/setup.bash
34 | ```
35 | 5. Run the system:
36 | ```shell
37 | ros2 launch ethercat_motor_drive motor_drive.launch.py
38 | ```
39 |
40 | ## Contacts ##
41 | 
42 |
43 | [ICube Laboratory](https://icube.unistra.fr), [University of Strasbourg](https://www.unistra.fr/), France
44 |
45 | __Maciej Bednarczyk:__ [m.bednarczyk@unistra.fr](mailto:m.bednarczyk@unistra.fr), @github: [mcbed](https://github.com/mcbed)
46 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | push:
4 | branches: [ main ]
5 | pull_request:
6 | branches: [ main ]
7 | jobs:
8 | CI:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - name: Prepare
12 | run: |
13 | mkdir -p ${{github.workspace}}/src
14 | - uses: actions/checkout@v3
15 | with:
16 | path: src/ethercat_driver_ros2_examples
17 |
18 | - name: Build Docker Image
19 | uses: docker/build-push-action@v4
20 | with:
21 | tags: ethercat_driver_ros2_examples:humble
22 | file: .docker/Dockerfile
23 | push: false
24 |
25 | - name: Build
26 | uses: addnab/docker-run-action@v3
27 | with:
28 | image: ethercat_driver_ros2_examples:humble
29 | options: -v ${{github.workspace}}/:/ros/
30 | run: |
31 | apt update
32 | apt upgrade -y
33 | cd /ros
34 | . /opt/ros/humble/setup.sh
35 | vcs import src < src/ethercat_driver_ros2_examples/ethercat_driver_ros2_examples.repos
36 | rosdep install --ignore-src --from-paths . -y -r && \
37 | colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release
38 |
39 | - name: Tests
40 | uses: addnab/docker-run-action@v3
41 | with:
42 | image: ethercat_driver_ros2_examples:humble
43 | options: -v ${{github.workspace}}/:/ros/
44 | run: |
45 | apt update
46 | apt upgrade -y
47 | cd /ros
48 | . /opt/ros/humble/setup.sh
49 | rosdep install --ignore-src --from-paths . -y -r && \
50 | colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release
51 | colcon test
52 | colcon test-result
53 |
54 | - name: Upload Tests to Artifacts
55 | uses: actions/upload-artifact@v4
56 | if: always()
57 | with:
58 | name: test-results
59 | path: build/*/test_results/*/*.xml
60 |
61 | - name: Publish Unit Test Results
62 | uses: EnricoMi/publish-unit-test-result-action@v2
63 | if: always()
64 | with:
65 | files: build/*/test_results/*/*.xml
66 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/config/maxon_epos3_config.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Maxon EPOS3 drive
2 | vendor_id: 0x000000fb
3 | product_id: 0x64400000
4 | assign_activate: 0x0300 # DC Synch register
5 | auto_fault_reset: false # true = automatic fault reset, false = fault reset on rising edge command interface "reset_fault"
6 | sdo: # sdo data to be transferred at drive startup
7 | - { index: 0x60C2, sub_index: 1, type: int8, value: 10 } # Set interpolation time for cyclic modes to 10 ms
8 | - { index: 0x60C2, sub_index: 2, type: int8, value: -3 } # Set base 10-3s
9 | rpdo: # RxPDO = receive PDO 4 Mapping
10 | - index: 0x1603
11 | channels:
12 | - { index: 0x6040, sub_index: 0, type: uint16, default: 0 } # Control word
13 | - {
14 | index: 0x607a,
15 | sub_index: 0,
16 | type: int32,
17 | command_interface: position,
18 | default: .nan,
19 | } # Target position
20 | - { index: 0x60ff, sub_index: 0, type: int32, default: 0 } # Target velocity
21 | - { index: 0x6071, sub_index: 0, type: int16, default: 0 } # Target torque
22 | - { index: 0x60b0, sub_index: 0, type: int32, default: 0 } # Offset position
23 | - { index: 0x60b1, sub_index: 0, type: int32, default: 0 } # Offset velocity
24 | - { index: 0x60b2, sub_index: 0, type: int16, default: 0 } # Offset torque
25 | - { index: 0x6060, sub_index: 0, type: int8, default: 8 } # Mode of operation
26 | - { index: 0x2078, sub_index: 1, type: uint16, default: 0 } # Digital Output Functionalities
27 | - { index: 0x60b8, sub_index: 0, type: uint16, default: 0 } # Touch Probe Function
28 | tpdo: # TxPDO = transmit PDO 4 Mapping
29 | - index: 0x1a03
30 | channels:
31 | - { index: 0x6041, sub_index: 0, type: uint16 } # Status word
32 | - { index: 0x6064, sub_index: 0, type: int32, state_interface: position } # Position actual value
33 | - { index: 0x606c, sub_index: 0, type: int32, state_interface: velocity } # Velocity actual value
34 | - { index: 0x6077, sub_index: 0, type: int16, state_interface: effort } # Torque actual value
35 | - { index: 0x6061, sub_index: 0, type: int8 } # Mode of operation display
36 | - { index: 0x2071, sub_index: 1, type: int16 } # Digital Input Functionalities State
37 | - { index: 0x60b9, sub_index: 0, type: int16 } # Touch Probe Status
38 | - { index: 0x60ba, sub_index: 0, type: int32 } # Touch Probe Position 1 Positive Value
39 | - { index: 0x60bb, sub_index: 0, type: int32 } # Touch Probe Position 1 Negative Value
40 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/config/maxon_epos4_50_5_config.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Maxon EPOS4 50/5 drive
2 | vendor_id: 0x000000fb
3 | product_id: 0x63500000 # Product code
4 | assign_activate: 0x0300 # DC Synch register
5 | auto_fault_reset: false # true = automatic fault reset, false = fault reset on rising edge command interface "reset_fault"
6 | sdo: # sdo data to be transferred at drive startup
7 | - { index: 0x60C2, sub_index: 1, type: int8, value: 10 } # Set interpolation time for cyclic modes to 10 ms
8 | - { index: 0x60C2, sub_index: 2, type: int8, value: -3 } # Set base 10-3s
9 | rpdo: # RxPDO = receive PDO 4 Mapping
10 | - index: 0x1603
11 | channels:
12 | - { index: 0x6040, sub_index: 0, type: uint16, default: 0 } # Control word
13 | - {
14 | index: 0x607a,
15 | sub_index: 0,
16 | type: int32,
17 | command_interface: position,
18 | default: .nan,
19 | } # Target position
20 | - { index: 0x60ff, sub_index: 0, type: int32, default: 0 } # Target velocity
21 | - { index: 0x6071, sub_index: 0, type: int16, default: 0 } # Target torque
22 | - { index: 0x60b0, sub_index: 0, type: int32, default: 0 } # Offset position
23 | - { index: 0x60b1, sub_index: 0, type: int32, default: 0 } # Offset velocity
24 | - { index: 0x60b2, sub_index: 0, type: int16, default: 0 } # Offset torque
25 | - { index: 0x6060, sub_index: 0, type: int8, default: 8 } # Mode of operation
26 | - { index: 0x3150, sub_index: 1, type: uint16, default: 0 } # Digital Output Properties
27 | - { index: 0x60b8, sub_index: 0, type: uint16, default: 0 } # Touch Probe Function
28 | tpdo: # TxPDO = transmit PDO 4 Mapping
29 | - index: 0x1a03
30 | channels:
31 | - { index: 0x6041, sub_index: 0, type: uint16 } # Status word
32 | - { index: 0x6064, sub_index: 0, type: int32, state_interface: position } # Position actual value
33 | - { index: 0x606c, sub_index: 0, type: int32, state_interface: velocity } # Velocity actual value
34 | - { index: 0x6077, sub_index: 0, type: int16, state_interface: effort } # Torque actual value
35 | - { index: 0x6061, sub_index: 0, type: int8 } # Mode of operation display
36 | - { index: 0x3141, sub_index: 1, type: int16 } # Digital Input Properties
37 | - { index: 0x60b9, sub_index: 0, type: int16 } # Touch Probe Status
38 | - { index: 0x60ba, sub_index: 0, type: int32 } # Touch Probe Position 1 Positive edge
39 | - { index: 0x60bb, sub_index: 0, type: int32 } # Touch Probe Position 1 Negative edge
40 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/maxon/maxon_epos3.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Maxon EPOS3 drive
2 | vendor_id: 0x000000fb
3 | product_id: 0x64400000
4 | assign_activate: 0x0300 # DC Synch register
5 | auto_fault_reset: false # true = automatic fault reset, false = fault reset on rising edge command interface "reset_fault"
6 | sdo: # sdo data to be transferred at drive startup
7 | - {index: 0x60C2, sub_index: 1, type: int8, value: 10} # Set interpolation time for cyclic modes to 10 ms
8 | - {index: 0x60C2, sub_index: 2, type: int8, value: -3} # Set base 10-3s
9 | rpdo: # RxPDO = receive PDO Mapping (ROS control to motor drive, Master Out to Slave In -MOSI-)
10 | - index: 0x1603
11 | channels:
12 | - {index: 0x6040, sub_index: 0, type: uint16, default: 0} # Control word
13 | - {index: 0x607a, sub_index: 0, type: int32, command_interface: position, default: .nan} # Target position
14 | - {index: 0x60ff, sub_index: 0, type: int32, default: 0} # Target velocity
15 | - {index: 0x6071, sub_index: 0, type: int16, default: 0} # Target torque
16 | - {index: 0x60b0, sub_index: 0, type: int32, default: 0} # Offset position
17 | - {index: 0x60b1, sub_index: 0, type: int32, default: 0} # Offset velocity
18 | - {index: 0x60b2, sub_index: 0, type: int16, default: 0} # Offset torque
19 | - {index: 0x6060, sub_index: 0, type: int8, default: 8} # Mode of operation
20 | - {index: 0x2078, sub_index: 1, type: uint16, default: 0} # Digital Output Functionalities
21 | - {index: 0x60b8, sub_index: 0, type: uint16, default: 0} # Touch Probe Function
22 | tpdo: # TxPDO = transmit PDO Mapping (motor drive to ROS control, Master In From Slave Out -MISO-)
23 | - index: 0x1a03
24 | channels:
25 | - {index: 0x6041, sub_index: 0, type: uint16} # Status word
26 | - {index: 0x6064, sub_index: 0, type: int32, state_interface: position} # Position actual value
27 | - {index: 0x606c, sub_index: 0, type: int32, state_interface: velocity} # Velocity actual value
28 | - {index: 0x6077, sub_index: 0, type: int16, state_interface: effort} # Torque actual value
29 | - {index: 0x6061, sub_index: 0, type: int8} # Mode of operation display
30 | - {index: 0x2071, sub_index: 1, type: int16} # Digital Input Functionalities State
31 | - {index: 0x60b9, sub_index: 0, type: int16} # Touch Probe Status
32 | - {index: 0x60ba, sub_index: 0, type: int32} # Touch Probe Position 1 Positive Value
33 | - {index: 0x60bb, sub_index: 0, type: int32} # Touch Probe Position 1 Negative Value
34 |
--------------------------------------------------------------------------------
/ethercat_slave_description/README.md:
--------------------------------------------------------------------------------
1 | # ethercat_slave_description
2 | Collection of EtherCAT module example configurations for the `ethercat_driver`.
3 |
4 | ## Modules using `GenericEcSlave`
5 | The list of available example EtherCAT module configurations for the `GenericEcSlave` Hardware Interface plugin.
6 | ### Beckhoff
7 | - **Beckhoff_EL1008**: EtherCAT Terminal, 8-channel digital input, 24 V DC, 3 ms.
8 | - **Beckhoff_EL1018**: EtherCAT Terminal, 8-channel digital input, 24 V DC, 10 us.
9 | - **Beckhoff_EL2008**: EtherCAT Terminal, 8-channel digital output, 24 V DC, 0.5 A.
10 | - **Beckhoff_EL2088**: EtherCAT Terminal, 8-channel digital output, 24 V DC, 0.5 A, ground switching.
11 | - **Beckhoff_EL2124**: EtherCAT Terminal, 4-channel digital output, 5 V DC, 20 mA.
12 | - **Beckhoff_EL3102**: EtherCAT Terminal, 2-channel analog input, voltage, ±10 V, 16 bit, differential.
13 | - **Beckhoff_EL3104**: EtherCAT Terminal, 4-channel analog input, voltage, ±10 V, 16 bit, differential.
14 | - **Beckhoff_EL4132**: EtherCAT Terminal, 2-channel analog output, voltage, ±10 V, 16 bit.
15 | - **Beckhoff_EL4134**: EtherCAT Terminal, 4-channel analog output, voltage, ±10 V, 16 bit.
16 | - **Beckhoff_EL5101**: EtherCAT Terminal, 1-channel encoder interface, incremental, 5 V DC (DIFF RS422, TTL), 1 MHz.
17 |
18 | ### ATI
19 | - **ATI_FTSensor**: ATI EtherCAT F/T Sensor
20 |
21 | ### Advantech
22 | - **AMAX-5051**: Digital Input Module, 8-channel digital input, 24 V DC, 4 ms.
23 | - **AMAX-5056**: Sink-type Digital Output Module, 8-channel digital output, 24 V DC, 0.3 A.
24 |
25 | ### Omron
26 | - **Omron_NX_ECC201_NX_ID5442**: Omron EtherCAT Coupler NX_ECC201 with Input module NX_ID5442.
27 | - **Omron_NX_ECC201_NX_OD5256**: Omron EtherCAT Coupler NX_ECC201 with Output module NX_OD5256.
28 |
29 | ## Motor drive modules using `EcCiA402Drive`
30 | The list of available example EtherCAT motor drive module configurations for the `EcCiA402Drive` Hardware Interface plugin.
31 | ### Maxon
32 | - **EPOS3**: EPOS3 70/10 EtherCAT, digital positioning controller, 10 A, 11 - 70 VDC
33 | - Plugin : `EcCiA402Drive`
34 |
35 | ### Schneider Electric
36 | - **Schneider_ATV320**: Schneider Electric Variable frequency drive. Coupled with VW3A3601 communication card.
37 | - Plugin : `EcCiA402Drive`
38 |
39 | ### Elmo
40 | - **Elmo Gold**: Elmo Gold servo drive.
41 | - Plugin : `EcCiA402Drive`
42 |
43 | ### Technosoft
44 | - **Technosoft IPOS 3604**: Technosoft IPOS 3064 motor drive.
45 | - Plugin : `EcCiA402Drive`
46 |
47 | ### Synapticon
48 | - **Synapticon SOMANET Circulo 9**: Synapticon SOMANET Circulo 9 Safe Motion servo drive.
49 | - Plugin : `EcCiA402Drive`
50 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/technosoft/technosoft_ipos3604.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Technosoft IPOS 3604 drive
2 | vendor_id: 0x000001a3
3 | product_id: 0x01ab46e5
4 | assign_activate: 0x0330 # DC Synch register
5 | auto_fault_reset: false # true = automatic fault reset, false = fault reset on rising edge command interface "reset_fault"
6 | sdo: # sdo data to be transferred at drive startup
7 | - {index: 0x60C2, sub_index: 1, type: int8, value: 10} # Set interpolation time for cyclic modes to 10 ms
8 | - {index: 0x60C2, sub_index: 2, type: int8, value: -3} # Set base 10-3s
9 | rpdo: # RxPDO = receive PDO Mapping (ROS control to motor drive, Master Out to Slave In -MOSI-)
10 | - index: 0x1600
11 | channels:
12 | - {index: 0x6040, sub_index: 0, type: uint16, command_interface: control_word, default: 0} # Control word
13 | - {index: 0x607a, sub_index: 0, type: int32, command_interface: position} # Target position
14 | - index: 0x1601
15 | channels:
16 | - {index: 0x6060, sub_index: 0, type: int8, command_interface: mode_of_operation, default: 8} # Mode of operation
17 | - {index: 0x60ff, sub_index: 0, type: int32, command_interface: velocity, default: 0} # Target velocity
18 | - index: 0x1602
19 | channels:
20 | - {index: 0x2090, sub_index: 2, type: uint8, default: 3} # Digital outputs mask
21 | - {index: 0x2090, sub_index: 1, type: uint8, command_interface: digital_out, default: 0} # Digital outputs value
22 | tpdo: # TxPDO = transmit PDO Mapping (motor drive to ROS control, Master In From Slave Out -MISO-)
23 | - index: 0x1a00
24 | channels:
25 | - {index: 0x6041, sub_index: 0, type: uint16, state_interface: status_word} # Status word
26 | - {index: 0x6064, sub_index: 0, type: int32, state_interface: position} # Position actual value
27 | - index: 0x1a01
28 | channels:
29 | - {index: 0x6061, sub_index: 0, type: int8, state_interface: mode_of_operation} # Mode of operation display
30 | - {index: 0x606c, sub_index: 0, type: int32, state_interface: velocity} # Velocity actual value 65536 = 1 encoder increment/sample (internal driver slow loop : 1khz )
31 | - index: 0x1a02
32 | channels:
33 | - {index: 0x6077, sub_index: 0, type: int16, state_interface: effort} # Torque actual value
34 | - {index: 0x208F, sub_index: 2, type: uint8, state_interface: digital_in} # Digital Inputs value
35 | - index: 0x1a03
36 | channels:
37 | - {index: 0x2046, sub_index: 0, type: int16, state_interface: analog_in.1} # Analog input value
38 | - {index: 0x2047, sub_index: 0, type: int16, state_interface: analog_in.2} # Analog input value
39 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el5101.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL5101
2 | # Description : EtherCAT Terminal, 1-channel encoder interface, incremental, 5 V DC (DIFF RS422, TTL), 1 MHz
3 | # Predefined PDO assignment for Standard 32-bit mode
4 | vendor_id: 0x00000002
5 | product_id: 0x13ed3052
6 | rpdo: # RxPDO = receive PDO Mapping (ROS control to slave, Master Out to Slave In -MOSI-)
7 | - index: 0x1603
8 | channels:
9 | - {index: 0x7010, sub_index: 0x01, type: bool} # Enable latch C
10 | - {index: 0x7010, sub_index: 0x02, type: bool} # Enable latch extern on positive edge
11 | - {index: 0x7010, sub_index: 0x03, type: bool, mask: 4, command_interface: reset} # Set counter
12 | - {index: 0x7010, sub_index: 0x04, type: bool} # Enable latch extern on negative edge
13 | - {index: 0x0000, sub_index: 0x00, type: bit4} # Gap
14 | - {index: 0x0000, sub_index: 0x00, type: bit8} # Gap
15 | - {index: 0x7010, sub_index: 0x11, type: int32, default: 0} # Set counter value
16 | tpdo: # TxPDO = transmit PDO Mapping (slave to ROS control, Master In From Slave Out -MISO-)
17 | - index: 0x1a04
18 | channels:
19 | - {index: 0x6010, sub_index: 0x01, type: bool} # Latch C valid
20 | - {index: 0x6010, sub_index: 0x02, type: bool} # Latch extern valid
21 | - {index: 0x6010, sub_index: 0x03, type: bool} # Set counter done
22 | - {index: 0x6010, sub_index: 0x04, type: bool} # Counter underflow
23 | - {index: 0x6010, sub_index: 0x05, type: bool} # Counter overflow
24 | - {index: 0x6010, sub_index: 0x06, type: bool} # Status of input status
25 | - {index: 0x6010, sub_index: 0x07, type: bool} # Open circuit
26 | - {index: 0x6010, sub_index: 0x08, type: bool} # Extrapolation stall
27 | - {index: 0x6010, sub_index: 0x09, type: bool} # Status of input A
28 | - {index: 0x6010, sub_index: 0x0a, type: bool} # Status of input B
29 | - {index: 0x6010, sub_index: 0x0b, type: bool} # Status of input C
30 | - {index: 0x6010, sub_index: 0x0c, type: bool} # Status of input gate
31 | - {index: 0x6010, sub_index: 0x0d, type: bool} # Status of extern latch
32 | - {index: 0x1c32, sub_index: 0x20, type: bool} # Sync error
33 | - {index: 0x1804, sub_index: 0x07, type: bool} # TxPDO-State
34 | - {index: 0x1804, sub_index: 0x09, type: bool} # TxPDO-Toggle
35 | - {index: 0x6010, sub_index: 0x11, type: int32, state_interface: position} # Counter value
36 | - {index: 0x6010, sub_index: 0x12, type: int32} # Latch value
37 | sm: # Sync Manager
38 | - {index: 0, type: output, pdo: ~, watchdog: disable}
39 | - {index: 1, type: input, pdo: ~, watchdog: disable}
40 | - {index: 2, type: output, pdo: rpdo, watchdog: disable}
41 | - {index: 3, type: input, pdo: tpdo, watchdog: disable}
42 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/launch/force_sensor.launch.py:
--------------------------------------------------------------------------------
1 | # Copyright 2023 ICube Laboratory, University of Strasbourg
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | from launch import LaunchDescription
16 | from launch.substitutions import Command, FindExecutable, PathJoinSubstitution, LaunchConfiguration
17 | from launch.actions import DeclareLaunchArgument
18 |
19 | from launch_ros.actions import Node
20 | from launch_ros.substitutions import FindPackageShare
21 |
22 |
23 | def generate_launch_description():
24 |
25 | # Declare arguments
26 | declared_arguments = []
27 | declared_arguments.append(
28 | DeclareLaunchArgument(
29 | 'description_file',
30 | default_value='force_sensor.config.xacro',
31 | description='URDF/XACRO description file with the sensor.',
32 | )
33 | )
34 |
35 | description_file = LaunchConfiguration('description_file')
36 |
37 | # Get URDF via xacro
38 | robot_description_content = Command(
39 | [
40 | PathJoinSubstitution([FindExecutable(name="xacro")]),
41 | " ",
42 | PathJoinSubstitution(
43 | [
44 | FindPackageShare("ethercat_force_sensor"),
45 | "description/config",
46 | description_file,
47 | ]
48 | ),
49 | ]
50 | )
51 | robot_description = {"robot_description": robot_description_content}
52 |
53 | robot_controllers = PathJoinSubstitution(
54 | [
55 | FindPackageShare("ethercat_force_sensor"),
56 | "config",
57 | "controllers.yaml",
58 | ]
59 | )
60 |
61 | control_node = Node(
62 | package="controller_manager",
63 | executable="ros2_control_node",
64 | parameters=[robot_description, robot_controllers],
65 | output="both",
66 | )
67 |
68 | joint_state_broadcaster_spawner = Node(
69 | package="controller_manager",
70 | executable="spawner",
71 | arguments=["joint_state_broadcaster", "-c", "/controller_manager"],
72 | )
73 |
74 | nodes = [
75 | control_node,
76 | joint_state_broadcaster_spawner,
77 | ]
78 |
79 | return LaunchDescription(
80 | declared_arguments +
81 | nodes)
82 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing Guidelines
2 | Thank you for your interest in contributing to `ethercat_driver_ros2_examples`. Whether it's a bug report, new feature, correction, or additional documentation, we greatly value feedback and contributions from the community.
3 |
4 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary information to effectively respond to your bug report or contribution.
5 |
6 |
7 | ## Reporting Bugs/Feature Requests
8 | We welcome you to use the GitHub issue tracker to report bugs or suggest features.
9 |
10 | When filing an issue, please check [existing open][issues], or [recently closed][closed-issues], issues to make sure somebody else hasn't already reported the issue.
11 |
12 | Please try to include as much information as you can. Details like these are incredibly useful:
13 |
14 | * A reproducible test case or series of steps
15 | * The version of our code being used
16 | * Any modifications you've made relevant to the bug
17 | * Anything unusual about your environment or deployment
18 |
19 |
20 | ## Contributing via Pull Requests
21 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
22 |
23 | 1. You are working against the latest source on the *main* branch.
24 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
25 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
26 |
27 | To send us a pull request, please:
28 |
29 | 1. Fork the repository.
30 | 2. Modify the source; please focus on the specific change you are contributing.
31 | If you also reformat all the code, it will be hard for us to focus on your change.
32 | 3. Ensure local tests pass.
33 | 4. Commit to your fork using clear commit messages.
34 | 5. Send a pull request, answering any default questions in the pull request interface.
35 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
36 |
37 | GitHub provides additional documentation on [forking a repository](https://help.github.com/articles/fork-a-repo/) and [creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
38 |
39 |
40 | ## Licensing
41 | Any contribution that you make to this repository will be under the Apache 2 License, as dictated by that [license](http://www.apache.org/licenses/LICENSE-2.0.html):
42 |
43 | ~~~
44 | 5. Submission of Contributions. Unless You explicitly state otherwise,
45 | any Contribution intentionally submitted for inclusion in the Work
46 | by You to the Licensor shall be under the terms and conditions of
47 | this License, without any additional terms or conditions.
48 | Notwithstanding the above, nothing herein shall supersede or modify
49 | the terms of any separate license agreement you may have executed
50 | with Licensor regarding such Contributions.
51 | ~~~
52 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/synapticon/synapticon_somanet_circulo9.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Synapticon SOMANET Circulo 9 Safe Motion, Firmware Version 5.1.3
2 | vendor_id: 0x000022d2
3 | product_id: 0x00000302
4 | assign_activate: 0x0300 # DC Synch register
5 | auto_fault_reset: false # true = automatic fault reset, false = fault reset on rising edge command interface "reset_fault"
6 | rpdo: # RxPDO = receive PDO Mapping (ROS control to motor drive, Master Out to Slave In -MOSI-)
7 | - index: 0x1600
8 | channels:
9 | - {index: 0x6040, sub_index: 0, type: uint16, default: 0} # Control word
10 | - {index: 0x607a, sub_index: 0, type: int32, command_interface: position, default: .nan} # Target position
11 | - {index: 0x60ff, sub_index: 0, type: int32, default: 0} # Target velocity
12 | - {index: 0x6071, sub_index: 0, type: int16, default: 0} # Target torque
13 | - {index: 0x60b2, sub_index: 0, type: int16, default: 0} # Offset torque
14 | - {index: 0x6060, sub_index: 0, type: int8, default: 8} # Mode of operation
15 | - {index: 0x2701, sub_index: 0, type: uint32, default: 0} # Tuning command
16 | - index: 0x1601
17 | channels:
18 | - {index: 0x60fe, sub_index: 1, type: uint32, default: 0} # Digital Outputs: Physical Outputs
19 | - {index: 0x60fe, sub_index: 2, type: uint32, default: 0} # Digital Outputs: Bit Mask
20 | - index: 0x1602
21 | channels:
22 | - {index: 0x60b1, sub_index: 0, type: int32, default: 0} # Offset velocity
23 | - {index: 0x2703, sub_index: 0, type: uint32, default: 0} # User MOSI
24 |
25 | tpdo: # TxPDO = transmit PDO Mapping (motor drive to ROS control, Master In From Slave Out -MISO-)
26 | - index: 0x1a00
27 | channels:
28 | - {index: 0x6041, sub_index: 0, type: uint16} # Status word
29 | - {index: 0x6064, sub_index: 0, type: int32, state_interface: position} # Position actual value
30 | - {index: 0x606c, sub_index: 0, type: int32, state_interface: velocity} # Velocity actual value
31 | - {index: 0x6077, sub_index: 0, type: int16, state_interface: effort} # Torque actual value
32 | - {index: 0x6061, sub_index: 0, type: int8} # Mode of operation display
33 | - {index: 0x60f4, sub_index: 0, type: int32} # Following error actual value
34 | - index: 0x1a01
35 | channels:
36 | - {index: 0x2401, sub_index: 0, type: uint16} # Analog input 1
37 | - {index: 0x2402, sub_index: 0, type: uint16} # Analog input 2
38 | - {index: 0x2403, sub_index: 0, type: uint16} # Analog input 3
39 | - {index: 0x2404, sub_index: 0, type: uint16} # Analog input 4
40 | - {index: 0x2702, sub_index: 0, type: uint32} # Tuning status
41 | - index: 0x1a02
42 | channels:
43 | - {index: 0x60fd, sub_index: 0, type: uint32} # Digital Inputs
44 | - index: 0x1a03
45 | channels:
46 | - {index: 0x2704, sub_index: 0, type: uint32} # User MISO
47 | - {index: 0x20f0, sub_index: 0, type: uint32} # Timestamp
48 | - {index: 0x60fc, sub_index: 0, type: int32} # Position demand internal value
49 | - {index: 0x606b, sub_index: 0, type: int32} # Velocity demand value
50 | - {index: 0x6074, sub_index: 0, type: int16} # Torque demand
51 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/README.md:
--------------------------------------------------------------------------------
1 | # ethercat_force_sensor
2 |
3 | This repository contains the instructions for building a custom Force Sensor EtherCAT slave using strain gauges and EasyCAT and use it in ROS2 with [EtherCAT Driver ROS2 stack](https://github.com/ICube-Robotics/ethercat_driver_ros2).
4 |
5 | ## Required Hardware ##
6 | | | |
7 | |---|---
8 | | [Arduino Uno](https://store.arduino.cc/products/arduino-uno-rev3) |
9 | | [Load Cell / Wheatstone Amplifier Shield (2ch)](https://eu.robotshop.com/products/strain-gauge-load-cell-amplifier-shield-2ch) |
|
10 | | [EasyCAT Shield for Arduino](https://www.bausano.net/en/hardware/easycat.html) |
11 | | [5 Kg Micro Load Cell](https://eu.robotshop.com/products/micro-load-cell-5-kg) |
12 |
13 |
14 |
15 | ## EasyCAT configuration ##
16 | Use the [EasyConfigurator](https://www.bausano.net/images/arduino-easycat/EasyConfigurator_UserManual.pdf) tool to load the [ForceSensor](config/easycat_config/ForceSensor.prj) file and write the configuration to the slave EEPROM.
17 |
18 | Open the [ForceSensor](config/easycat_config/ForceSensor.ino) Arduino project in the [Arduino IDE](https://www.arduino.cc/en/software) and upload it to the Arduino board.
19 |
20 | ## Usage ##
21 | ***Required setup : Ubuntu 22.04 LTS***
22 |
23 | 1. Install `ros2` packages. The current development is based of `ros2 humble`. Installation steps are described [here](https://docs.ros.org/en/humble/Installation.html).
24 | 2. Source your `ros2` environment:
25 | ```shell
26 | source /opt/ros/humble/setup.bash
27 | ```
28 | **NOTE**: The ros2 environment needs to be sources in every used terminal. If only one distribution of ros2 is used, it can be added to the `~/.bashrc` file.
29 | 3. Install `colcon` and its extensions :
30 | ```shell
31 | sudo apt install python3-colcon-common-extensions
32 | ```
33 | 3. Create a new ros2 workspace:
34 | ```shell
35 | mkdir ~/ros2_ws/src
36 | ```
37 | 4. Pull relevant packages, install dependencies, compile, and source the workspace by using:
38 | ```shell
39 | cd ~/ros2_ws
40 | git clone https://github.com/ICube-Robotics/ethercat_driver_ros2_examples.git src/ethercat_driver_ros2_examples
41 | vcs import src < ethercat_driver_ros2_examples.repos
42 | rosdep install --ignore-src --from-paths . -y -r
43 | colcon build --cmake-args -DCMAKE_BUILD_TYPE=Release --symlink-install --packages-select ethercat_force_sensor
44 | source install/setup.bash
45 | ```
46 | 5. Run the system:
47 | ```shell
48 | ros2 launch ethercat_force_sensor force_sensor.launch.py
49 | ```
50 |
51 | ## Contacts ##
52 | 
53 |
54 | [ICube Laboratory](https://icube.unistra.fr), [University of Strasbourg](https://www.unistra.fr/), France
55 |
56 | __Maciej Bednarczyk:__ [m.bednarczyk@unistra.fr](mailto:m.bednarczyk@unistra.fr), @github: [mcbed](https://github.com/mcbed)
57 |
--------------------------------------------------------------------------------
/ethercat_slave_description/config/beckhoff/beckhoff_el3104.yaml:
--------------------------------------------------------------------------------
1 | # Configuration file for Beckhoff EL3104
2 | # Description : EtherCAT Terminal, 4-channel analog input, voltage, ±10 V, 16 bit, differential.
3 | vendor_id: 0x00000002
4 | product_id: 0x0c203052
5 | tpdo: # TxPDO = transmit PDO Mapping (slave to ROS control, Master In From Slave Out -MISO-)
6 | - index: 0x1a00
7 | channels:
8 | - {index: 0x6000, sub_index: 0x01, type: bool} # Underrange
9 | - {index: 0x6000, sub_index: 0x02, type: bool} # Overrange
10 | - {index: 0x6000, sub_index: 0x03, type: bit2} # Limit 1
11 | - {index: 0x6000, sub_index: 0x05, type: bit2} # Limit 2
12 | - {index: 0x6000, sub_index: 0x07, type: bool} # Error
13 | - {index: 0x0000, sub_index: 0x00, type: bool} # Gap
14 | - {index: 0x0000, sub_index: 0x00, type: bit5} # Gap
15 | - {index: 0x6000, sub_index: 0x0e, type: bool} # Sync error
16 | - {index: 0x6000, sub_index: 0x0f, type: bool} # TxPDO State
17 | - {index: 0x6000, sub_index: 0x10, type: bool} # TxPDO Toggle
18 | - {index: 0x6000, sub_index: 0x11, type: int16, state_interface: analog_input.1, factor: 0.000305185} # Value
19 | - index: 0x1a02
20 | channels:
21 | - {index: 0x6010, sub_index: 0x01, type: bool} # Underrange
22 | - {index: 0x6010, sub_index: 0x02, type: bool} # Overrange
23 | - {index: 0x6010, sub_index: 0x03, type: bit2} # Limit 1
24 | - {index: 0x6010, sub_index: 0x05, type: bit2} # Limit 2
25 | - {index: 0x6010, sub_index: 0x07, type: bool} # Error
26 | - {index: 0x0000, sub_index: 0x00, type: bool} # Gap
27 | - {index: 0x0000, sub_index: 0x00, type: bit5} # Gap
28 | - {index: 0x6010, sub_index: 0x0e, type: bool} # Sync error
29 | - {index: 0x6010, sub_index: 0x0f, type: bool} # TxPDO State
30 | - {index: 0x6010, sub_index: 0x10, type: bool} # TxPDO Toggle
31 | - {index: 0x6010, sub_index: 0x11, type: int16, state_interface: analog_input.2, factor: 0.000305185}
32 | - index: 0x1a04
33 | channels:
34 | - {index: 0x6020, sub_index: 0x01, type: bool} # Underrange
35 | - {index: 0x6020, sub_index: 0x02, type: bool} # Overrange
36 | - {index: 0x6020, sub_index: 0x03, type: bit2} # Limit 1
37 | - {index: 0x6020, sub_index: 0x05, type: bit2} # Limit 2
38 | - {index: 0x6020, sub_index: 0x07, type: bool} # Error
39 | - {index: 0x0000, sub_index: 0x00, type: bool} # Gap
40 | - {index: 0x0000, sub_index: 0x00, type: bit5} # Gap
41 | - {index: 0x6020, sub_index: 0x0e, type: bool} # Sync error
42 | - {index: 0x6020, sub_index: 0x0f, type: bool} # TxPDO State
43 | - {index: 0x6020, sub_index: 0x10, type: bool} # TxPDO Toggle
44 | - {index: 0x6020, sub_index: 0x11, type: int16, state_interface: analog_input.3, factor: 0.000305185}
45 | - index: 0x1a06
46 | channels:
47 | - {index: 0x6030, sub_index: 0x01, type: bool} # Underrange
48 | - {index: 0x6030, sub_index: 0x02, type: bool} # Overrange
49 | - {index: 0x6030, sub_index: 0x03, type: bit2} # Limit 1
50 | - {index: 0x6030, sub_index: 0x05, type: bit2} # Limit 2
51 | - {index: 0x6030, sub_index: 0x07, type: bool} # Error
52 | - {index: 0x0000, sub_index: 0x00, type: bool} # Gap
53 | - {index: 0x0000, sub_index: 0x00, type: bit5} # Gap
54 | - {index: 0x6030, sub_index: 0x0e, type: bool} # Sync error
55 | - {index: 0x6030, sub_index: 0x0f, type: bool} # TxPDO State
56 | - {index: 0x6030, sub_index: 0x10, type: bool} # TxPDO Toggle
57 | - {index: 0x6030, sub_index: 0x11, type: int16, state_interface: analog_input.4, factor: 0.000305185}
58 | sm: # Sync Manager
59 | - {index: 3, type: input, pdo: tpdo, watchdog: enable}
60 |
--------------------------------------------------------------------------------
/ethercat_motor_drive/launch/motor_drive.launch.py:
--------------------------------------------------------------------------------
1 | # Copyright 2023 ICube Laboratory, University of Strasbourg
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | from launch import LaunchDescription
16 | from launch.substitutions import Command, FindExecutable, PathJoinSubstitution, LaunchConfiguration
17 | from launch.actions import DeclareLaunchArgument
18 |
19 | from launch_ros.actions import Node
20 | from launch_ros.substitutions import FindPackageShare
21 |
22 |
23 | def generate_launch_description():
24 |
25 | # Declare arguments
26 | declared_arguments = []
27 | declared_arguments.append(
28 | DeclareLaunchArgument(
29 | 'description_file',
30 | default_value='motor_drive.config.xacro',
31 | description='URDF/XACRO description file with the axis.',
32 | )
33 | )
34 |
35 | description_file = LaunchConfiguration('description_file')
36 |
37 | # Get URDF via xacro
38 | robot_description_content = Command(
39 | [
40 | PathJoinSubstitution([FindExecutable(name="xacro")]),
41 | " ",
42 | PathJoinSubstitution(
43 | [
44 | FindPackageShare("ethercat_motor_drive"),
45 | "description/config",
46 | description_file,
47 | ]
48 | ),
49 | ]
50 | )
51 | robot_description = {"robot_description": robot_description_content}
52 |
53 | robot_controllers = PathJoinSubstitution(
54 | [
55 | FindPackageShare("ethercat_motor_drive"),
56 | "config",
57 | "controllers.yaml",
58 | ]
59 | )
60 |
61 | control_node = Node(
62 | package="controller_manager",
63 | executable="ros2_control_node",
64 | parameters=[robot_description, robot_controllers],
65 | output="both",
66 | )
67 | robot_state_pub_node = Node(
68 | package="robot_state_publisher",
69 | executable="robot_state_publisher",
70 | output="both",
71 | parameters=[robot_description],
72 | )
73 |
74 | joint_state_broadcaster_spawner = Node(
75 | package="controller_manager",
76 | executable="spawner",
77 | arguments=["joint_state_broadcaster", "-c", "/controller_manager"],
78 | )
79 |
80 | trajectory_controller_spawner = Node(
81 | package="controller_manager",
82 | executable="spawner",
83 | arguments=["trajectory_controller", "-c", "/controller_manager"],
84 | )
85 |
86 | # velocity_controller_spawner = Node(
87 | # package="controller_manager",
88 | # executable="spawner",
89 | # arguments=["velocity_controller", "-c", "/controller_manager"],
90 | # )
91 |
92 | # effort_controller_spawner = Node(
93 | # package="controller_manager",
94 | # executable="spawner",
95 | # arguments=["effort_controller", "-c", "/controller_manager"],
96 | # )
97 |
98 | nodes = [
99 | control_node,
100 | robot_state_pub_node,
101 | joint_state_broadcaster_spawner,
102 | trajectory_controller_spawner,
103 | # velocity_controller_spawner,
104 | # effort_controller_spawner,
105 | ]
106 |
107 | return LaunchDescription(
108 | declared_arguments +
109 | nodes)
110 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | # To use:
2 | #
3 | # pre-commit run -a
4 | #
5 | # Or:
6 | #
7 | # pre-commit install # (runs every time you commit in git)
8 | #
9 | # To update this file:
10 | #
11 | # pre-commit autoupdate
12 | #
13 | # See https://github.com/pre-commit/pre-commit
14 |
15 | repos:
16 | # Standard hooks
17 | - repo: https://github.com/pre-commit/pre-commit-hooks
18 | rev: v4.4.0
19 | hooks:
20 | - id: check-added-large-files
21 | - id: check-ast
22 | - id: check-case-conflict
23 | - id: check-docstring-first
24 | - id: check-merge-conflict
25 | - id: check-symlinks
26 | - id: check-xml
27 | - id: check-yaml
28 | - id: debug-statements
29 | - id: end-of-file-fixer
30 | - id: mixed-line-ending
31 | - id: trailing-whitespace
32 | exclude_types: [rst]
33 | - id: fix-byte-order-marker
34 |
35 |
36 | # Python hooks
37 | - repo: https://github.com/asottile/pyupgrade
38 | rev: v3.3.1
39 | hooks:
40 | - id: pyupgrade
41 | args: [--py36-plus]
42 |
43 | # PyDocStyle
44 | - repo: https://github.com/PyCQA/pydocstyle
45 | rev: 6.3.0
46 | hooks:
47 | - id: pydocstyle
48 | args: ["--ignore=D100,D101,D102,D103,D104,D105,D106,D107,D203,D212,D404"]
49 |
50 | - repo: https://github.com/pycqa/flake8
51 | rev: 6.0.0
52 | hooks:
53 | - id: flake8
54 | args: ["--extend-ignore=E501"]
55 |
56 | # Uncrustify
57 | - repo: local
58 | hooks:
59 | - id: ament_uncrustify
60 | name: ament_uncrustify
61 | description: Uncrustify.
62 | stages: [commit]
63 | entry: ament_uncrustify
64 | language: system
65 | files: \.(h\+\+|h|hh|hxx|hpp|cuh|c|cc|cpp|cu|c\+\+|cxx|tpp|txx)$
66 | args: ["--reformat"]
67 |
68 | # CPP hooks
69 | - repo: local
70 | hooks:
71 | - id: clang-format
72 | name: clang-format
73 | description: Format files with ClangFormat.
74 | entry: clang-format-14
75 | language: system
76 | files: \.(c|cc|cxx|cpp|frag|glsl|h|hpp|hxx|ih|ispc|ipp|java|js|m|proto|vert)$
77 | args: ['-fallback-style=none', '-i']
78 |
79 | # - repo: local
80 | # hooks:
81 | # - id: ament_cppcheck
82 | # name: ament_cppcheck
83 | # description: Static code analysis of C/C++ files.
84 | # stages: [commit]
85 | # entry: ament_cppcheck
86 | # language: system
87 | # files: \.(h\+\+|h|hh|hxx|hpp|cuh|c|cc|cpp|cu|c\+\+|cxx|tpp|txx)$
88 |
89 | # Maybe use https://github.com/cpplint/cpplint instead
90 | - repo: local
91 | hooks:
92 | - id: ament_cpplint
93 | name: ament_cpplint
94 | description: Static code analysis of C/C++ files.
95 | stages: [commit]
96 | entry: ament_cpplint
97 | language: system
98 | files: \.(h\+\+|h|hh|hxx|hpp|cuh|c|cc|cpp|cu|c\+\+|cxx|tpp|txx)$
99 | args: ["--linelength=100", "--filter=-whitespace/newline"]
100 |
101 | # Cmake hooks
102 | - repo: local
103 | hooks:
104 | - id: ament_lint_cmake
105 | name: ament_lint_cmake
106 | description: Check format of CMakeLists.txt files.
107 | stages: [commit]
108 | entry: ament_lint_cmake
109 | language: system
110 | files: CMakeLists\.txt$
111 |
112 | # Copyright
113 | - repo: local
114 | hooks:
115 | - id: ament_copyright
116 | name: ament_copyright
117 | description: Check if copyright notice is available in all files.
118 | stages: [commit]
119 | entry: ament_copyright
120 | language: system
121 |
122 | # Docs - RestructuredText hooks
123 | - repo: https://github.com/PyCQA/doc8
124 | rev: v1.1.1
125 | hooks:
126 | - id: doc8
127 | args: ['--max-line-length=100', '--ignore=D001']
128 | exclude: CHANGELOG\.rst$
129 |
130 | - repo: https://github.com/pre-commit/pygrep-hooks
131 | rev: v1.10.0
132 | hooks:
133 | - id: rst-backticks
134 | exclude: CHANGELOG\.rst$
135 | - id: rst-directive-colons
136 | - id: rst-inline-touching-normal
137 |
138 | # Spellcheck in comments and docs
139 | # skipping of *.svg files is not working...
140 | - repo: https://github.com/codespell-project/codespell
141 | rev: v2.2.2
142 | hooks:
143 | - id: codespell
144 | args: ['--write-changes']
145 | exclude: CHANGELOG\.rst|\.(svg|pyc)$
146 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/easycat_config/ForceSensor.ino:
--------------------------------------------------------------------------------
1 | #define CUSTOM
2 | #include "ForceSensor.h"
3 | #include "EasyCAT.h" // EasyCAT library to interface the LAN9252
4 | #include // SPI library
5 |
6 | EasyCAT EASYCAT(8); // EasyCAT istantiation
7 |
8 | const int Ana0 = A0; // analog input 0
9 | const int Ana1 = A1; // analog input 1
10 |
11 | unsigned long Millis = 0;
12 | unsigned long PreviousMillis = 0;
13 |
14 |
15 | //---- setup ---------------------------------------------------------------------------------------
16 |
17 | void setup()
18 | {
19 | Serial.begin(9600); // serial line initialization
20 | //(used only for debug)
21 |
22 | Serial.print ("\nEasyCAT - Generic EtherCAT slave\n"); // print the banner
23 |
24 | //---- initialize the EasyCAT board -----
25 |
26 | if (EASYCAT.Init() == true) // initialization
27 | { // successfully completed
28 | Serial.print ("initialized"); //
29 | } //
30 |
31 | else // initialization failed
32 | { // the EasyCAT board was not recognized
33 | Serial.print ("initialization failed"); //
34 | // The most common reason is that the SPI
35 | // chip select chosen on the board doesn't
36 | // match the one chosen by the firmware
37 |
38 | pinMode(13, OUTPUT); // stay in loop for ever
39 | // with the Arduino led blinking
40 | while(1) //
41 | { //
42 | digitalWrite (13, LOW); //
43 | delay(500); //
44 | digitalWrite (13, HIGH); //
45 | delay(500); //
46 | } //
47 | }
48 |
49 | PreviousMillis = millis();
50 | }
51 |
52 |
53 | //---- main loop ----------------------------------------------------------------------------------------
54 |
55 | void loop() // In the main loop we must call ciclically the
56 | { // EasyCAT task and our application
57 | //
58 | // This allows the bidirectional exachange of the data
59 | // between the EtherCAT master and our application
60 | //
61 | // The EasyCAT cycle and the Master cycle are asynchronous
62 | //
63 |
64 | EASYCAT.MainTask(); // execute the EasyCAT task
65 |
66 | Application(); // user applications
67 |
68 | }
69 |
70 | //---- user application ------------------------------------------------------------------------------
71 |
72 | void Application ()
73 |
74 | {
75 | uint16_t Analog0;
76 | uint16_t Analog1;
77 |
78 | Millis = millis(); // As an example for this application
79 | if (Millis - PreviousMillis >= 10) // we choose a cycle time of 10 mS
80 | { //
81 | PreviousMillis = Millis; //
82 |
83 | // --- analog inputs management ---
84 |
85 | Analog0 = analogRead(Ana0); // read analog input 0
86 | Analog0 = Analog0 << 6; // normalize it on 16 bits
87 | EASYCAT.BufferIn.Cust.force_0 = Analog0; // and put the result into
88 | // input Byte 0
89 |
90 | Analog1 = analogRead(Ana1); // read analog input 1
91 | Analog1 = Analog1 << 6; // normalize it on 16 bits
92 | EASYCAT.BufferIn.Cust.force_1 = Analog1; // and put the result into
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/ethercat_force_sensor/config/easycat_config/ForceSensor.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | #x0000079A
36 | AB&T
37 | 424dd6020000000000003600000028000000100000000e0000000100180000000000a0020000c40e0000c40e000000000000000000004cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb1224cb122ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff241cedffffff241cedffffff241ced241cedffffffffffffffffff241ced241ced241cedffffff241cedffffffffffff241cedffffff241cedffffff241cedffffff241cedffffff241cedffffff241cedffffffffffff241cedffffffffffff241cedffffff241cedffffff241cedffffff241cedffffff241cedffffff241cedffffffffffff241cedffffffffffff241cedffffff241cedffffff241cedffffff241cedffffffffffff241cedffffffffffffffffff241cedffffffffffff241ced241ced241cedffffff241ced241cedffffffffffff241cedffffff241cedffffffffffff241cedffffffffffff241cedffffff241cedffffff241cedffffff241cedffffff241cedffffff241cedffffffffffff241cedffffffffffff241cedffffff241cedffffff241cedffffff241cedffffffffffff241cedffffffffffffffffff241cedffffffffffff241cedffffff241cedffffff241cedffffff241cedffffffffffffffffffffffffffffffffffff241cedffffffffffffffffff241cedffffffffffffffffff241cedffffffffffffffffffffffffffffffffffff241ced241ced241cedffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
38 |
39 |
40 |
41 |
42 | SSC_Device
43 | EasyCAT
44 | 424dd6020000000000003600000028000000100000000e0000000100180000000000a0020000c40e0000c40e00000000000000000000241ced241ced241ced241cedffffff241cedffffffffffffffffff241cedffffffffffffffffff241cedffffffffffff241cedffffffffffffffffffffffff241cedffffffffffffffffff241cedffffffffffffffffff241cedffffffffffff241cedffffffffffffffffffffffff241ced241ced241ced241ced241cedffffffffffffffffff241cedffffffffffff241cedffffffffffffffffffffffff241cedffffffffffffffffff241cedffffffffffffffffff241cedffffffffffff241cedffffffffffffffffffffffff241ced241cedffffff241ced241cedffffff241cedffffff241cedffffff241ced241ced241ced241ced241cedffffffffffff241ced241ced241cedffffffffffff241ced241ced241ced241ced241cedffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff241ced241ced241cedffffffffffff241ced241ced241cedffffff241ced241ced241cedffffff241ced241ced241ced241cedffffffffffffffffff241cedffffffffffff241cedffffffffffffffffff241cedffffffffffffffffff241ced241cedffffffffffffffffffffffff241ced241cedffffffffffff241ced241ced241cedffffff241ced241ced241ced241ced241cedffffffffffffffffffffffffffffff241cedffffff241cedffffffffffffffffff241cedffffff241ced241cedffffffffffffffffffffffff241ced241ced241cedffffff241ced241ced241cedffffff241cedffffff241ced241cedffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff241ced241ced241cedffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | ForceSensor
57 |
58 | SSC_Device
59 | Inputs
60 |
61 |
62 | Inputs
63 |
64 |
65 |
66 |
67 | #x1A00
68 | Inputs
69 |
70 | #x6
71 | 1
72 | 16
73 | force_0
74 | INT
75 |
76 |
77 | #x6
78 | 2
79 | 16
80 | force_1
81 | INT
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | SM_Sync or Async
91 | SM_Sync or Async
92 | #x0000
93 |
94 |
95 |
96 | DC_Sync
97 | DC_Sync
98 | #x300
99 | 0
100 | 2000200000
101 |
102 |
103 |
104 |
105 |
106 |
107 | 4096
108 | 8003006EFF00FF000000
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------