Giter Club home page Giter Club logo

robin's Introduction

ROBIN

ROBIN project Build status

A ROS-CODESYS shared memory bridge to map CODESYS variables to ROS topics.

This bridge is the result of the ROBIN project, a Focused Technical Project (FTP) of the ROSIN European project.

Getting started

The bridge is made up of two components:

  • A ROS package that doesn't require any manual configuration other than the installation of its dependencies. The package contains a ROS node that reads/writes data from/to shared memory spaces and publishes/receives messages to/from ROS topics.
  • A CODESYS library to be used in a CODESYS project created by the user. An example project is provided in robin_updater/src/robin_updater/cfg/codesys_project.xml. The library contains a Robin function block that reads/writes data from/to shared memory spaces and writes/reads it to CODESYS user-defined variables.

The following IEC 61131-3 data types are currently supported:

  • BOOL
  • BYTE
  • SINT, INT, DINT, LINT, USINT, UINT, UDINT, ULINT
  • REAL, LREAL
  • CHAR, STRING

As well as arrays and custom structs. The following standard ROS message packages are already defined as CODESYS structs and available on the Robin CODESYS library:

These variables have to be defined on both the CODESYS project and the ROS package. For arrays or for structs with string or array members, because these data types are handled as non-POD (Plain Old Data) objects in C++, the mapping between the C++ variables and the ROS messages has to be explicitly defined. However, an updater application was developed to automate most of this process. The user simply needs to define its desired variables on the CODESYS project and run the updater.

Prerequisites

Installation

  1. Install CODESYS library:

    1. Open CODESYS Development System V3
    2. Go to Tools->Library Repository->Install
    3. Find and select robin_bridge/src/robin.library
    4. Close the Library Repository dialog
  2. Create catkin workspace (if non-existent):

    mkdir -p ~/catkin_ws/src
    cd ~/catkin_ws
    catkin_make  # or 'catkin build'
    source ~/catkin_ws/devel/setup.bash
  3. Clone repository into catkin workspace (eg. ~/catkin_ws):

    cd ~/catkin_ws/src
    git clone https://github.com/ScalABLE40/robin
  4. Install updater package dependencies:

    rosdep install robin_updater
  5. Compile bridge package:

    cd ~/catkin_ws
    catkin_make robin  # or 'catkin build robin'

Usage

  1. Create CODESYS project. You can either:

    • Create your own project and add the Robin library to it.

      1. In the Devices tree, double click Library Manager and open the Add Library dialog
      2. Find and select the previously installed Robin library and click OK
      3. You can now use the Robin function block as shown in the Examples section
    • Create a new empty project and import the example project from codesys_project.xml.

      1. Go to Project->Import PLCopenXML...
      2. Find and select the XML file
      3. Select all items and click OK

    Variable length arrays are only partially supported in CODESYS. To make the updater interpret a regular fixed length array as a ROS variable length array, preceed its declaration with the line: {attribute 'robin_var_len'}.

  2. Make sure you can establish connection with the PLC. Go to the Devices tree, double click the Device and then:

    • Scan Network... for your PLC device.

    • Or add it manually Device->Options->Manage Favourite Devices...

  3. Go to Windows Search Bar->Services and make sure Windows OpenSSH Authentication Agent service is running (Startup type: Automatic).

  4. Run the updater application:

    1. Go to Tools->Scripting->Execute Script File...
    2. Open the script file robin_updater/src/robin_updater/src/robin_updater/start_update.py
      • If you don't have access to it from CODESYS, first copy it to your Windows system
    3. Input the requested information (target address and password) and follow the script's execution
      • NOTE: Password will be asked again during the script
  5. Launch the robin ROS node. Will restart codesyscontrol service and then launch the node:

    To avoid having to manually restart codesyscontrol after each update run:

    echo "$USER ALL=(ALL:ALL) NOPASSWD: /bin/systemctl * codesyscontrol" | sudo EDITOR="tee" visudo -f /etc/sudoers.d/allow_restart_codesyscontrol

    This will allow the command systemctl start/stop codesyscontrol to be run with sudo without having to input a password. The user must be in the sudo group.

    If your system does not have systemctl:

    echo "$USER ALL=(ALL:ALL) NOPASSWD: /usr/sbin/service codesyscontrol *" | sudo EDITOR="tee" visudo -f /etc/sudoers.d/allow_restart_codesyscontrol

    This will allow the command service codesyscontrol start/stop to be run with sudo without having to input a password. The user must be in the sudo group.

    roslaunch robin_bridge_generated run.launch

    If you prefer not to give those permissions run the node manually:

    rosrun robin_bridge_generated robin_node_generated

Examples

Example 1 Example 2 Example 3

License

License


rosin_logo

Supported by ROSIN - ROS-Industrial Quality-Assured Robot Software Components.
More information: rosin-project.eu

eu_flag

This project has received funding from the European Union’s Horizon 2020
research and innovation programme under grant agreement no. 732287.

robin's People

Contributors

carlosmccosta avatar henriquedomingos avatar nicola-sysdesign avatar rarrais avatar sergiodmlteixeira avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

robin's Issues

Library instalation error

Hello,

I ran into some problems at the very beginning.
When trying to instal Robin library, codesys shows error:

Failed to open managed library. Reason: The project handle 68 is invalid.

Turns out that no one on codesys forum knows what's causing this error.
I'm trying to communicate IFM CR711s with ROS Noetic.

Any ideas what's cause this problem?

Robin calls implicitly done?

Is there any possibility that by adding comments like {attribute 'robin_input/output'}, the iec variables are automatically read and write to the shared memory areas by some apps run in background? Does CodeSys provide such mechanism that we can read/write by symbol names?

semaphore timeouts before read or write

Hello,
I successfully implemented robin in melodic ROS container on my Toradex Verdin board.
I run Codesys runtime in other container and managed to import example project .xml in CODESYS V3.5 SP16 Patch 4 that is running on my Windows machine. After running start_update.py, building loging into Codesys I realized this.

Semaphore in the Codesys program timeouts on every read and write and nothing is written to shared memory. When I commented semaphore checking in robin library write and read function I was able to read and write data to shared memory and echo them in ROS container. When I uncommented the semaphore checks in read and write functions but this time SysSemProcessEnter returned ERR_OK and everything worked as it should. This happens after every reset.

Any idea what am I doing wrong ?

Problem with Strings and some general questions

Hello,

I am currently trying out this project with ubuntu 16.04 and ros kinetic. And I really like it so far, but while using I ran into some things I could not explain myself. By opening this issue I hope to find some answers:

  1. I was able to transfer numbers between codesys and ros by adding RobinSubscribers and Publishers to the robin_node.cpp. What I could not get to work is sending strings in either direction. While sending a String from ROS to Codesys the orignial strings gets altered: e.g. from "Hello" to something like "pF$02". After that the value can not be changed until a complete reset of the PLC. Sending a string from codesys to ros results in sending no string at all (no information published on topic). Did I forgot something or did I made a mistake?

Here is an excerpt of the lines I added:
robin_inst.cpp:

#include "robin_publisher.cpp"
#include "robin_subscriber.cpp"
#include "robin/structs.h"
#include "std_msgs/Int32.h"
#include "std_msgs/String.h"

template class RobinSubscriber<int32_t, std_msgs::Int32>;
template class RobinSubscriber<std::string, std_msgs::String>;
template class RobinPublisher<std::string, std_msgs::String>;
template class RobinPublisher<int32_t, std_msgs::Int32>;

robin_node.cpp

//works
RobinSubscriber<int32_t, std_msgs::Int32> pub_int32(nh, "pub_int32");
RobinPublisher<int32_t, std_msgs::Int32> sub_int32(nh, "sub_int32");

// does not work
RobinSubscriber<std::string, std_msgs::String> pub_string(nh, "pub_string");
RobinPublisher<std::string, std_msgs::String> sub_string(nh, "sub_string");

codesys

VAR_INPUT
 	sub_int32 : DINT;
	sub_string : STRING;
END_VAR
 
VAR_OUTPUT
	pub_int32 : DINT;
 	pub_string : STRING;
END_VAR
 
robin();
robin.write('sub_int32', sub_int32);
robin.write('sub_string', sub_string);
robin.read('pub_int32', pub_int32);
robin.read('pub_string', pub_string);
  1. I noticed that variables regardless of whether the content has changed or not gets published. On PLC-side this does not bother me, but in my opinion this is some what a problem on ROS-side. My problem with this behavior is, that for ROS every published message is a new information and triggers the callback functions of the subscrubers. In some of my usecases I need to intercept this by doing something like: "if old information == new information do nothing".
    The question I now ask myself is whether this behaviour is intended or not and if there is a possibility to do a interception of this behavior on plc-side or the code itself?

Beside that I would really appreciate if you could add/bring back an example for custom messages and and structs. Moreover I could not load the provided PLCopenXML because of an "Device not found" - Error. I tried to install some packages, but that did not solved the problem. Since the provided picture contains all information of the XML I could work around that.

Thanks in advance for any help you are able to provide.

hrdb

Custom messages from CodeSys structs: Error parsing ROS_TIME and ROS_DURATION

Hello,
I have been playing around with Robin in CodeSys with an Ubuntu 18.04 runtime system with ROS Melodic for a few days now. Really nice work! A very nice idea indeed to merge the two worlds of ROS and classical PLCs! In particular the generation of custom messages from a CodeSys struct comes in very handy!
In this context I have found a small bug with the ROS_TIME and ROS_DURATION data types that only occurs if one tries to assemble a custom message with them.
If we define a struct

TYPE TestStruct :
STRUCT
	var_time: ROS_TIME;
END_STRUCT
END_TYPE

and then define a program in structured text that simply writes it to ROS such as

PROGRAM ROS_PRG
VAR_INPUT
	struct_to_ros: TestStruct;
END_VAR
VAR
	robin: Robin;
END_VAR
robin();
robin.write('struct_to_ros', struct_to_ros);

and then call the Python start_update.py script then the script will end with an error

Output:
* * * * * * * * * * * * *
* * * Robin Updater * * *
* * * * * * * * * * * * *

Creating SSH key ...

Adding SSH key to agent ...
Identity added: C:\Users\lab\.ssh\robin_key (C:\Users\lab\.ssh\robin_key)

Adding SSH key to target ... Password will be required
[email protected]'s password:
[sudo] password for user: Accessing target through ssh... Ensure ssh service is ON. 
Connecting... 
sa-sha2-512)
warning: agent returned different signature type ssh-rsa (expected rsa-sha2-512)

Generating source code...

Generating new ros package robin_bridge_generated...

Recompiling...
NOTICE: Could not determine the width of the terminal. A default width of 80 will be used. This warning will only be printed once.
_______________________________________________________________________________
Errors << robin_bridge_generated:check /home/user/catkin_ws/logs/robin_bridge_generated/build.check.104.log
CMake Error at /home/user/catkin_ws/build/robin_bridge_generated/cmake/robin_bridge_generated-genmsg.cmake:3 (message):
  Could not find messages which
  '/home/user/catkin_ws/src/robin_bridge_generated/msg/TestStruct.msg'
  depends on.  Did you forget to specify generate_messages(DEPENDENCIES ...)?

  Cannot locate message [time] in package [std_msgs] with paths
  [['/opt/ros/melodic/share/std_msgs/cmake/../msg']]
Call Stack (most recent call first):
  /opt/ros/melodic/share/genmsg/cmake/genmsg-extras.cmake:307 (include)
  CMakeLists.txt:23 (generate_messages)


make: *** [cmake_check_build_system] Error 1
cd /home/user/catkin_ws/build/robin_bridge_generated; catkin build --get-env robin_bridge_generated | catkin env -si  /usr/bin/make cmake_check_build_system; cd -
...............................................................................
Failed << robin_bridge_generated:check           [ Exited with code 2 ]
Traceback (most recent call last):
  File "./updater.py", line 401, in <module>
    Updater().update(catkin_ws=catkin_ws)
  File "./updater.py", line 79, in update
    self._recompile_robin(catkin_ws)
  File "./updater.py", line 296, in _recompile_robin
    raise RuntimeError('Failed to recompile robin_bridge_generated package.')
RuntimeError: Failed to recompile robin_bridge_generated package.

and similarly for the ROS_DURATION data type.


Opening the robin/robin_updater/cfg/types.yml file and changing the ROS names to capital letters

66   ROS_TIME:
67       - Time
68       - Time
69       - std_msgs::Time
70   ROS_DURATION:
71       - Duration
72       - Duration
73       - std_msgs::Duration

(so lines 68 and 71 in capital as well) seems to fix it for me.

Custom messages from CodeSys structs: Error parsing Array of Strings

Hey again,
I have encountered another error when creating custom messages from CodeSys structs similar to the previously reported issue #10. When using the data type ARRAY[1..n] OF STRING as a message type in a custom struct such as

TYPE TestStruct :
STRUCT
	var_string: ARRAY[1..32] OF STRING;
END_STRUCT
END_TYPE

with a program in structured text

PROGRAM ROS_PRG
VAR_INPUT
	struct_to_codesys: TestStruct;
END_VAR
VAR
	robin: Robin;
END_VAR

that contains a subscriber (the corresponding publisher seems to work)

robin();
robin.read('struct_to_codesys', struct_to_codesys);

this results in the error message

* * * * * * * * * * * * *
* * * Robin Updater * * *
* * * * * * * * * * * * *

Creating SSH key ...

Adding SSH key to agent ...
Identity added: C:\Users\lab\.ssh\robin_key (C:\Users\lab\.ssh\robin_key)

Adding SSH key to target ... Password will be required
[email protected]'s password:
[sudo] password for user: Accessing target through ssh... Ensure ssh service is ON. 
Connecting... 
sa-sha2-512)
warning: agent returned different signature type ssh-rsa (expected rsa-sha2-512)

Generating source code...

Generating new ros package robin_bridge_generated...

Recompiling...
NOTICE: Could not determine the width of the terminal. A default width of 80 will be used. This warning will only be printed once.
_______________________________________________________________________________
Errors << robin_bridge_generated:make /home/user/catkin_ws/logs/robin_bridge_generated/build.make.118.log
/home/user/catkin_ws/src/robin_bridge_generated/src/robin_bridge_generated/robin_inst.cpp: In member function ?void RobinSubscriber<T1, T2>::write(const T2*) [with T1 = TestStruct; T2 = robin_bridge_generated::TestStruct_<std::allocator<void> >]?:
/home/user/catkin_ws/src/robin_bridge_generated/src/robin_bridge_generated/robin_inst.cpp:14:43: error: invalid conversion from ?char? to ?char*? [-fpermissive]
     std::snprintf((*shm_ptr_).var_string[i_0], sizeof((*shm_ptr_).var_string[i_0]), "%s", (*msg_ptr).var_string[i_0].c_str());
                   ~~~~~~~~~~~~~~~~~~~~~~~~^
In file included from /usr/include/features.h:424:0,
                 from /usr/include/x86_64-linux-gnu/c++/7/bits/os_defines.h:39,
                 from /usr/include/x86_64-linux-gnu/c++/7/bits/c++config.h:533,
                 from /usr/include/c++/7/cstdio:41,
                 from /home/user/catkin_ws/src/robin_bridge_generated/src/robin_bridge_generated/robin_inst.cpp:1:
/usr/include/x86_64-linux-gnu/bits/stdio2.h:61:1: note:   initializing argument 1 of ?int snprintf(char*, size_t, const char*, ...)?
 __NTH (snprintf (char *__restrict __s, size_t __n,
 ^
make[2]: *** [CMakeFiles/robin_inst_generated.dir/src/robin_bridge_generated/robin_inst.cpp.o] Error 1
make[1]: *** [CMakeFiles/robin_inst_generated.dir/all] Error 2
make: *** [all] Error 2
cd /home/user/catkin_ws/build/robin_bridge_generated; catkin build --get-env robin_bridge_generated | catkin env -si  /usr/bin/make --jobserver-fds=6,7 -j; cd -
WARNING: Could not encode unicode characters. Please set the PYTHONIOENCODING environment variable to see complete output. (i.e. PYTHONIOENCODING=UTF-8)
...............................................................................
Failed << robin_bridge_generated:make            [ Exited with code 2 ]
Traceback (most recent call last):
  File "./updater.py", line 401, in <module>
    Updater().update(catkin_ws=catkin_ws)
  File "./updater.py", line 79, in update
    self._recompile_robin(catkin_ws)
  File "./updater.py", line 296, in _recompile_robin
    raise RuntimeError('Failed to recompile robin_bridge_generated package.')
RuntimeError: Failed to recompile robin_bridge_generated package.

when executing the start_update.py script.


The reason for this seems to be that the script generates a message of the form

struct TestStruct
{
  char var_string[32];
};

in robin_generated/include/robin_bridge_generated/structs.h instead of

struct TestStruct
{
  char var_string[32][81];
};

I still have to look into more detail into the source code of updater.py and srcgen.py to propose a potential fix on a code level for it.

ROS2 support

Thank you for this wonderful work.
Does robin support ROS2?

ROS Noetic support

Hi, first of all I want to congratulate you to realize this amazing project which is incredibly useful to use ROS in industrial applications.
We are interested in using it with ROS Noetic too. Is there any plan to support it?
Thank you

Issues on Raspberry Pi 3

Hi,

I am currently trying to get this to work on a Raspberry Pi 3 with Raspbian Buster for a project at the institute i am working at. This is my first time working with ROS, so after having some issues actually getting ROS on the Raspberry Pi i managed to successfully install Kinetic on it. For that i followed these instructions using the ROS-Comm variant. One question right away: is it correct to create a new catkin workspace as per your installation instructions besides the one created during the initial installation of ROS Kinetic (ros_catkin_ws)?

My first issue: arriving at step 4 of the installation instructions the command rosdep install robin_updater returns:

ERROR: Rosdep cannot find all required resources to answer your query
Missing resource robin_updater
ROS path [0]=/opt/ros/kinetic/share/ros
ROS path [1]=/opt/ros/kinetic/share

Searching on Google for a bit one suggestion was to run the source command from Step 2 again. after that the command rosdep install robin_updater returns:

ERROR: the following packages/stacks could not have their rosdep keys resolved
to system dependencies:
robin_updater: No definition of [rostest] for OS [debian]

Consulting Google once again suggested adding --os=debian:buster to the command, however the same error is returned. I resorted to just skipping this command and continuing with step 5. This returned no errors so i proceeded to the Usage section.

(this is just a minor issue) At step 4 (running the updater application) when the command prompt opens and requests the password again i have to type it in 3 times until it finally accepts it. The updater finishes successfully with the following output:

* * * * * * * * * * * * *
* * * Robin Updater * * *
* * * * * * * * * * * * *

Creating SSH key ...

Adding SSH key to agent ...
Error connecting to agent: No such file or directory

Adding SSH key to target ... Password will be required
pi@raspberrypi's password:
touch: cannot touch '/home/pi/.ssh/authorized_keys': Permission denied
Accessing target through ssh... Ensure ssh service is ON. 
Connecting... 
pi@raspberrypi's password: 
pi@raspberrypi's password:

Generating source code...

Generating new ros package robin_bridge_generated...

Recompiling...

Restarting...
ROS master is not running.

Update finished.

Continuing to Step 5, the command roslaunch robin_bridge_generated run.launch returns:
[run.launch] is neither a launch file in package [robin_bridge_generated] nor is [robin_bridge_generated] a launch file name The traceback for the exception was written to the log file
Running the alternative command rosrun robin_bridge_generated robin_node_generated yields
[rospack] Error: package 'robin_bridge_generated' not found
Once again searching for a bit on Google suggested running the source command from Step 2 again. Running roslaunch robin_bridge_generated run.launch now yields:

... logging to /home/pi/.ros/log/643f17c2-f406-11ea-a6ff-b827ebe9bd6e/roslaunch-raspberrypi-1701.log
Checking log directory for disk usage. This may take awhile.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.

started roslaunch server http://raspberrypi:40893/

SUMMARY
========

PARAMETERS
 * /rosdistro: kinetic
 * /rosversion: 1.12.16

NODES
  /
    robin_bridge_generated (robin_bridge_generated/run.sh)

auto-starting new master
process[master]: started with pid [1711]
ROS_MASTER_URI=http://localhost:11311

setting /run_id to 643f17c2-f406-11ea-a6ff-b827ebe9bd6e
process[rosout-1]: started with pid [1724]
started core service [/rosout]
process[robin_bridge_generated-2]: started with pid [1727]

[ INFO]: Stopping codesyscontrol service ... Trying with systemctl

[ INFO]: Starting codesyscontrol service via systemctl

[ INFO]: Starting robin bridge ...


[rosrun] Couldn't find executable named robin_node_generated below /home/pi/catkin_ws/src/robin_bridge_generated
[robin_bridge_generated-2] process has died [pid 1727, exit code 3, cmd /home/pi/catkin_ws/src/robin_bridge_generated/launch/run.sh __name:=robin_bridge_generated __log:=/home/pi/.ros/log/643f17c2-f406-11ea-a6ff-b827ebe9bd6e/robin_bridge_generated-2.log].
log file: /home/pi/.ros/log/643f17c2-f406-11ea-a6ff-b827ebe9bd6e/robin_bridge_generated-2*.log

This is as far as i could go through the installation/usage with my very limited knowledge of ROS. I would appreciate it alot if you can help me resolve these problems.

Kind regards
Daniel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.