Codesys Ros2 [PROVEN • 2024]
Integrating CODESYS with ROS 2 allows you to combine the deterministic hardware control of industrial PLCs with the advanced motion planning and perception capabilities of the Robot Operating System. 🚀 Direct Integration Methods
Shared Memory Bridge (Recommended for High Speed): Use the ROBIN project (ScalABLE40/robin) for high-performance data exchange on the same hardware (e.g., Raspberry Pi, Beaglebone).
OPC UA Bridge: Set up an OPC UA Server in CODESYS and use a ROS 2 node as an OPC UA Client with libraries like asyncua (Python) or open62541 (C++). codesys ros2
MQTT Messaging: Use the CODESYS MQTT library to publish PLC variables to a broker and subscribe to them via a ros2_mqtt bridge for non-real-time tasks.
Micro-ROS Agent: For microcontrollers or lightweight PLCs, run a micro-ROS node directly on the target hardware to communicate with the ROS 2 Global Data Space. 🛠️ Strategic Setup: Why use both? Integrating CODESYS with ROS 2 allows you to
5.3 Determinism Impact
Inserting the CODESYS→ROS2 publisher at 1kHz increased the maximum PLC cycle time from 1.02ms to 1.19ms (17% increase). The worst-case occurred during DDS discovery heartbeats (every 3s). Using rclcpp::Publisher::publish() with pre-allocated messages eliminated dynamic memory inside the RT task.
Example Code
Here's an example code snippet in C++ that demonstrates how to integrate a CoDeSys controller with ROS 2: Option C: ROS 2 + EtherCAT (SoEM, IgH)
#include <ros2/ros2.hpp>
#include <industrial_ros2/industrial_ros2.hpp>
int main(int argc, char* argv[])
// Initialize ROS 2
rclcpp::init(argc, argv);
// Create a ROS 2 node
auto node = rclcpp::Node::create_node("co_de_sys_node");
// Create a CoDeSys controller object
industrial_ros2::CoDeSysController controller;
// Configure the CoDeSys controller
controller.configure("co_de_sys_controller");
// Start the CoDeSys controller
controller.start();
// Create a ROS 2 publisher
auto publisher = node->create_publisher<std_msgs::msg::String>("co_de_sys_topic", 10);
// Publish data from the CoDeSys controller
while (rclcpp::ok())
std_msgs::msg::String msg;
msg.data = controller.read_data();
publisher->publish(msg);
// Shutdown ROS 2
rclcpp::shutdown();
return 0;
Option C: ROS 2 + EtherCAT (SoEM, IgH)
- Bypass CODESYS entirely and make ROS 2 an EtherCAT master.
- Pros: Very tight integration (e.g.,
ros2_controlwithethercat_hardwareinterface). - Cons: You lose IEC 61131-3 environment. Hard real-time from Linux only.
The Synergy
By integrating the two, you build a hybrid system:
| Feature | Handled by CODESYS (PLC side) | Handled by ROS 2 (Edge/PC side) | | :--- | :--- | :--- | | Real-time control | Servo drives, hydraulic valves, temperature loops (<1ms) | High-level trajectory following (>10ms) | | Safety | Safety-rated PLC (ISO 13849) | Monitoring, but not SIL-rated logic | | I/O Handling | 24V digital, 4-20mA analog, EtherCAT slaves | Cameras, LiDARs, 3D sensors, microphones | | Algorithms | PID, motion control (CNC/Robotics) | SLAM, A*, MoveIt motion planning, YOLO vision | | Communication | Modbus TCP, Profinet, OPC UA | DDS (Fast-DDS, CycloneDDS), MQTT, WebSockets | | Deployment | Flash to non-volatile PLC memory | Docker containers, Kubernetes, snap packages |
Step 2: Write CODESYS PLC Logic
In your CODESYS project:
- Add the
ROS2 CoreandROS2 std_msgslibraries. - Declare variables:
PROGRAM Main VAR ros2_core : ROS2_CORE; sub_cmd_vel : ROS2_SUBSCRIBE; twist_msg : geometry_msgs__Twist; motor_speed_left : REAL; motor_speed_right : REAL; END_VAR - In the PLC cycle:
- Call
ros2_core()to initialize the DDS node (once). - Call
sub_cmd_vel(Execute:=TRUE, TopicName:= "/cmd_vel", Message:= twist_msg) - Map
twist_msg.linear.x(forward speed) andtwist_msg.angular.z(rotation) to your motor outputs.
- Call
1. One‑Click ROS 2 Interface Generation
- In CODESYS, right‑click any global variable or POU (Program Organization Unit) and select “Publish to ROS 2 Topic” or “Subscribe to ROS 2 Topic”.
- Automatically generates required ROS 2
.msgdefinitions (including complex data types like arrays, structs, enums). - Supports ROS 2 QoS settings (reliability, durability, history) configurable per variable.
