Example of a ROS node using SOEM library
etorta opened this issue · comments
Dear Matthias,
I have to implement a connection between MoveIt and an ethercat board to control a manipulator.
I am new to ethercat and I found your library very useful. I do not know, however, how to use the library. Do you have perhaps an example you can share?
A ROS node that communicate simple doubles or structures to the ehtercat board.
Thank you in advance!
Elena
Hi @etorta,
great that you think this is useful. Please note though, that I did not implement this library. As noted in several places, this is merely packaging the original SOEM library for the use with ROS, such that we can release it into the ROS eco system.
Judging from your question, you should first look into the EtherCAT basics. There are quite a few resources on the internet. Simply sending doubles or structs will (usually) not work.
EtherCAT is only the transport layer for sending data using a (close to) realtime ethernet connection to a device. On top of that, there are a few specified communication protocols, that you can use. The most relevant one is CANOpen-over-EtherCAT (CoE). If this is the case with your hardware (you didn't mention what hardware you have, so this is something that you need to check), you additionally need to understand how CANOpen works. Again, quite a lot of resources on the internet.
So basically, what you need to check is:
- Is the "ethercat board" you mention an EtherCAT Slave? Or a Master? If the latter, this repo is not for you ;-)
- What protocol does your ethercat board speak?
- What data structures (depending on the protocol above) do you need to send/receive?
Without those answers, you will be lost right from the start.
I don't have an example ROS node I can share, but in this GIST you can find an example where I'm running two Elmo Gold DC Whistle motor controllers using CoE. Putting "ROS" around it is straight forward.
I'd also like to refer you to the documentation of the upstream project.
Please let me know if this helped. Thanks.
Hello,
I would like to have more information too. I would like to integrate SOEM with ROS. To be more precise, I would like to have a topic where I could set or read diferents DI/DO of my Beckhofff slave.
@etorta did you find a solution ? I'm trying to use the GIST given by @mgruhler now.
Best regards,
Maybe this one helps?
Thanks @mgruhler .
I'm using the first example you gave : Gist
I've add the "ROS part" to init a node but it doesn't work and don't understand why. Without the "ROS part", it works. With the "ROS part", the program seems to not have conection to my "eno1".
`int main(int argc, char *argv[])
{
std::string param;
ros::init(argc, argv, "talker");
ros::NodeHandle nh("~");
nh.getParam("argument", param);
ROS_INFO("Got parameter : %s", param.c_str());
int iret1;
printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n");
if (argc > 1)
{
/* create thread to handle slave error handling in OP /
iret1 = pthread_create( &thread1, NULL, &ecatcheck, (void ()) &ctime); // (void) &ctime
/* start cyclic part */
simpletest(argv[1]);
}
else
{
printf("Usage: simple_test ifname1\nifname = eth0 for example\n");
}
printf("End program\n");
ros::spin();
return (0);
}`
And the result :
rosrun isiss_ethercat ethercat_master eno1
[ INFO] [1614628275.552649644]: Got parameter : eno1
SOEM (Simple Open EtherCAT Master)
Simple test
Starting simple test
No socket connection on eno1
Excecute as root
End program
have you executed it as root? Is actually a cable connected to eno1
?
I'm sure it works with eno1 because when I launch "sudo ./ethercat_master eno1" without the "ROS part" in the code it works.
`int main(int argc, char *argv[])
{
/*std::string param;
char *eth;
ros::init(argc, argv, "talker");
ros::NodeHandle nh("~");
nh.getParam("argument", param);
ROS_INFO("Got parameter : %s", param.c_str());
eth = (char*)param.c_str();*/
//eth = (char *)alloca(param.size() + 1);
//memcpy(eth, param.c_str(), param.size() + 1);
int iret1;
printf("SOEM (Simple Open EtherCAT Master)\nSimple test\n");
if (argc > 1)
{
/* create thread to handle slave error handling in OP */
iret1 = pthread_create( &thread1, NULL, &ecatcheck, (void (*)) &ctime); // (void) &ctime
/* start cyclic part */
simpletest(argv[1]);
}
else
{
printf("Usage: simple_test ifname1\nifname = eth0 for example\n");
}
printf("End program\n");
return (0);
}`
and the result
`sudo ./ethercat_master eno1
SOEM (Simple Open EtherCAT Master)
Simple test
Starting simple test
ec_init on eno1 succeeded.
4 slaves found and configured.
Slave 1 has CA? false
Slave 2 has CA? false
Slave 3 has CA? false
Slave 4 has CA? true
Slave:1
Name:EK1100
Output size: 0bits
Input size: 0bits
State: 18
Delay: 0[ns]
Has DC: 1
Slave:2
Name:EL1809
Output size: 0bits
Input size: 16bits
State: 18
Delay: 0[ns]
Has DC: 1
Slave:3
Name:EL2809
Output size: 16bits
Input size: 0bits
State: 18
Delay: 0[ns]
Has DC: 1
Slave:4
Name:EL6224
Output size: 0bits
Input size: 48bits
State: 2
Delay: 0[ns]
Has DC: 1
Slaves mapped, state to SAFE_OP.
segments : 1 : 10 0 0 0
Request operational state for all slaves
Calculated workcounter 4
Operational state reached for all slaves.
Processdata cycle 1094, WKC 4, 04 00 I: 00 00 00 00 00 00 00 000
Processdata cycle 4000, WKC 4, 04 00 I: 00 00 00 00 00 00 00 000
Request init state for all slaves
End simple test, close socket
End program
`
And with the ROS part? Do you run this as root as well?
How are you launch a rosrun with sudo ? I've tried with a launch file and a launch-prefix="sudo".
<launch> <node name="talker" pkg="isiss_ethercat" type="ethercat_master" launch-prefix="sudo" output="screen"> </node> </launch>
Here the result :
EDIT : I doesn't put passwordless sudo ... So it doesn't work
`
roslaunch isiss_ethercat ethercat.launch
... logging to /home/valentin/.ros/log/e56c977a-7ad4-11eb-ae3b-a4bb6dcacd8e/roslaunch-valentin-Precision-3440-7981.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://valentin-Precision-3440:41255/
SUMMARY
PARAMETERS
- /rosdistro: melodic
- /rosversion: 1.14.10
NODES
/
talker (isiss_ethercat/ethercat_master)
ROS_MASTER_URI=http://localhost:11311
process[talker-1]: started with pid [7996]
sudo: pas de tty présent et pas de programme askpass spécifié
[talker-1] process has died [pid 7996, exit code 1, cmd sudo /home/valentin/catkin_ws/devel/lib/isiss_ethercat/ethercat_master __name:=talker __log:=/home/valentin/.ros/log/e56c977a-7ad4-11eb-ae3b-a4bb6dcacd8e/talker-1.log].
log file: /home/valentin/.ros/log/e56c977a-7ad4-11eb-ae3b-a4bb6dcacd8e/talker-1*.log
all processes on machine have died, roslaunch will exit
shutting down processing monitor...
... shutting down processing monitor complete
done
`
No, of course it doesn't accept that passwordless. This would be a security issue!
Either change your shell to root, source the ROS environment and try again.
Or, since you are using melodic, you could use ethercat_grant
as described directly in the Readme.
It works perfectly ! Thank you very much !
I've launch a terminal as root and I run my node and it works :D
Thanks again.
Happy to help.
This is probably fine for testing, but I'd suggest to go the ethercat_grant
way for a production system...
(As your question seems to be resolved, and the OP hasn't responded, I'll close this issue. Feel free to reopen if you feel that there is something else that needs to be added)
@etorta okay. Please let us know what you find, and please feel free to reopen, if you feel this is necessary.