ros-drivers / omron

ROS driver for OMRON OS32C laser scanner.
18 stars 15 forks source link

Using more than 1 Omron at the same time is impossible #12

Closed Selano90 closed 6 years ago

Selano90 commented 8 years ago

I am using multiple Omron scanners simultaneously using the omron_os32c_driver ( http://wiki.ros.org/omron_os32c_driver ) but it does't work for more than 1 scanner in the same time. When i run the first scanner i have got no error but when i run the second it shows an error telling me that it can't connect to the socket knowing that i am using different IP adresses.

mikepurvis commented 8 years ago

My understanding is that this is a limitation of how the driver using UDP messages. We'd welcome a patch to the driver, or as a workaround, you can put the two scanners on different subnets, so that they don't interfere with each other.

Selano90 commented 8 years ago

In fact i have used different subnets but i have got the same error : process[omron_os32c_node-2]: started with pid [20452] process[omron_os32c_node_2-3]: started with pid [20471] [FATAL] [1459434249.186747802]: Exception caught opening session: bind

mikepurvis commented 8 years ago

Please show your launch file and the output of ifconfig. (Use three backticks to display xml)

Selano90 commented 8 years ago
$ ifconfig
eth0      Link encap:Ethernet  HWaddr 00:18:7d:98:c0:3b  
          inet addr:192.168.10.100  Bcast:192.168.10.255  Mask:255.255.255.0
          inet6 addr: fe80::218:7dff:fe98:c03b/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:18 errors:0 dropped:0 overruns:0 frame:0
          TX packets:166 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1342 (1.3 KB)  TX bytes:23285 (23.2 KB)
          Interrupt:20 Memory:f7f00000-f7f20000 

eth1      Link encap:Ethernet  HWaddr 00:18:7d:98:c0:3c  
          inet addr:192.168.0.100  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::218:7dff:fe98:c03c/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:208385 errors:0 dropped:1357 overruns:0 frame:0
          TX packets:9904 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:131896858 (131.8 MB)  TX bytes:1482502 (1.4 MB)
          Interrupt:18 Memory:f7d00000-f7d20000 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:68867 errors:0 dropped:0 overruns:0 frame:0
          TX packets:68867 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:10274641 (10.2 MB)  TX bytes:10274641 (10.2 MB)

wlan0     Link encap:Ethernet  HWaddr 80:a5:89:01:59:c0  
          inet addr:192.168.1.94  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::82a5:89ff:fe01:59c0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:618613 errors:0 dropped:0 overruns:0 frame:0
          TX packets:242634 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:433657817 (433.6 MB)  TX bytes:35143890 (35.1 MB)
Selano90 commented 8 years ago
<launch>

  <node pkg="omron_os32c_driver" type="omron_os32c_node" name="omron_os32c_node">
    <param name="host" value="192.168.0.11" />
    <remap from="scan" to="scan0" />
    <param name="frame_id" value="middle_torso_a_base_laser" />
    <param name="start_angle" value="1.0471975512" />
    <param name="end_angle" value="-1.0471975512" />
  </node>

 <node pkg="omron_os32c_driver" type="omron_os32c_node" name="omron_os32c_node_2">
    <param name="host" value="192.168.10.238" />
    <remap from="scan" to="scan1" />
    <param name="frame_id" value="middle_torso_b_base_laser" />
    <param name="start_angle" value="1.0471975512" />
    <param name="end_angle" value="-1.0471975512" />
 </node>

</launch> 
wassimhariri commented 8 years ago

I also have the same problem and almost a similar launch file...i also tried to create 2 separate nodes for each laser scanner but always the same error. I have contacted the maintainer and the author but unfortunatly didnt get any answer, and i have also posted the question on wiki bas also no clear answer, i hope this issue can be solved as soon as possible, and if someone worked with multiple omrons please share. Thanks a lot for your time and cooperation, looking forward to solve this error

mikepurvis commented 8 years ago

We never used this with multiple scanners, so you're going to need to do some work to figure out what the issue is. I suspect that one or more of the sockets is binding to 0.0.0.0 rather than the specific local IP. I'd start here:

https://github.com/ros-drivers/odva_ethernetip/blob/3aa7419ad2bf83dd4c6d2b5a23db6115e1c4f61b/src/session.cpp#L85

kshehata commented 8 years ago

Yes, I believe @mikepurvis is correct. The problem is that the socked for receiving IO connections is using the same port. Unfortunately, the port that the device calls back on cannot be changed easily (or at the very least, I'm not sure how to do that). I'd suggest that the best approach here is actually to have both sensors in the same node. You'll have to instantiate the OS32C class twice, but pass in the same IO class for that to work. I'm pretty sure that will work, but there might be a few bugs to work through. I wish I could help more, but I don't have access to a scanner, let alone two of them.

kshehata commented 8 years ago

Another idea: there are two ways to get data from the scanner. The default is to ask the device to send scan data as soon as it's available via UDP. If instead you poll via TCP, you could then launch two nodes. This would introduce latency on the received scans and would probably mean that you would only get range info and not reflectance, but it would allow you to run two nodes.

gavanderhoorn commented 8 years ago

@kshehata: I looked at the link @mikepurvis posted, but does the code bind to 0.0.0.0 or to an actual hostname/ip address? It should be possible to open the UDP port on a specific IP, which should (?) make running two nodes on two different IP addresses (no need for different subnets I believe).

kshehata commented 8 years ago

I think I've found it. The UDPSocket class binds to all local interfaces when you call open. If either at construct or before opening the localendpoint is changed to the address of the interface you want to use, it could be made to work on separate subnets.

gavanderhoorn commented 8 years ago

Makes sense, but it should probably also work with just two different IPs on the same interface.

wassimhariri commented 8 years ago

we tried using the suggestion of Mr. Shehata to instantiate the OS32C class twice, but unfortunatly it didnt work...it is still binding

gavanderhoorn commented 8 years ago

I think the idea is to get UdpSocket::open(..) to bind to an actual address, not just all locally existing interfaces (ie 0.0.0.0).

Creating two objects is something else entirely.

wassimhariri commented 8 years ago

yes i am trying to do the other suggestion, but lots of errors are occuring while catkin_make, any suggestions please how it can be done

andreucm commented 6 years ago

I'm experiencing the same issue with another device driver that is using the odva_ethernetip library. I've created a related question to ros answers forum: https://answers.ros.org/question/276962/odva_ethernetip-multiple-devices-in-the-same-machine/

mikepurvis commented 6 years ago

I think the ideal way to share a single connection would be to have all users of it be launched in the same process, for example as plugins to a single odva host node. Using pluginlib makes this fairly straightforward—simply define an interface similar to ControllerBase, but instead of just taking a pair of NodeHandles in your init method, also take a reference or handle to the eip connection object.

Anyway, doing this is obviously an architectural change, but I'd welcome such a PR.

reinzor commented 6 years ago

Solved by https://github.com/ros-drivers/omron/pull/15 using multiple subnets

Example:

Network configuration

auto eno1
iface eno1 inet static
address 192.168.1.2
netmask 255.255.255.0

auto eno1:0
iface eno1:0 inet static
address 192.168.2.2
netmask 255.255.255.0

Launch file

<?xml version="1.0"?>

<launch>

  <!-- Front lidar -->
  <node name="front_scan" pkg="omron_os32c_driver" type="omron_os32c_node">
    <param name="host" value="192.168.1.4" />
    <param name="local_ip" value="192.168.1.2" />
    <remap from="scan" to="front_scan" />
  </node>

  <!-- Rear lidar -->
  <node name="rear_scan" pkg="omron_os32c_driver" type="omron_os32c_node">
    <param name="host" value="192.168.2.4" />
    <param name="local_ip" value="192.168.2.2" />
    <remap from="scan" to="rear_scan" />
  </node>

</launch>
mitchallain commented 3 years ago

FWIW, we experienced issues similar to #29 when implementing multiple IP addresses/subnets on a single physical port. Publishing rate dropped from 12.8 to 6.7 Hz, and messages were intermittently dropped for larger periods of time (>500 ms).

Seems to be throwing std::length_error from buffer_reader.h while trying to deserialize measurement data, but we are going to revert to using multiple physical Ethernet ports, which works perfectly fine with the same driver configuration.