SICKAG / sick_scan_xd

Based on the sick_scan drivers for ROS1, sick_scan_xd merges sick_scan, sick_scan2 and sick_scan_base repositories. The driver supports both Linux (native, ROS1, ROS2) and Windows (native and ROS2).
Apache License 2.0
101 stars 84 forks source link

Problem disconnecting and reconnecting picoScan on linux without ROS #316

Closed paulinelvne closed 5 months ago

paulinelvne commented 5 months ago

Hello, We have noticed a problem when switching the picoscan off and on again under linux without ROS. I've modified the sick_scan_api_test.cpp file so that it turns the lidar off and then on again using the same procedure :

 do
  {
    user_key = sick_scan_api_test_main(argc, argv, sick_scan_args, polling);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    printf("sick_scan_xd_api_test finished with user key '%c' (%d), re-initialize and repeat sick_scan_xd_api_test ...\n", (char)user_key, user_key);
  } while (user_key == 'R' || user_key == 'r');

  // Unload and exit
  printf("sick_scan_xd_api_test finishing...\n");
  if ((ret = SickScanApiUnloadLibrary()) != SICK_SCAN_API_SUCCESS)
    exitOnError("SickScanApiUnloadLibrary failed", ret);
  printf("sick_scan_xd_api_test finished successfully\n");

  std::this_thread::sleep_for(std::chrono::seconds(5));

  if ((ret = SickScanApiLoadLibrary(sick_scan_api_lib)) != SICK_SCAN_API_SUCCESS)
    exitOnError("SickScanApiLoadLibrary failed", ret);

  // (Re-)Initialize and run sick_scan_xd_api_test
  user_key = 0;
  do
  {
    user_key = sick_scan_api_test_main(argc, argv, sick_scan_args, polling);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    printf("sick_scan_xd_api_test finished with user key '%c' (%d), re-initialize and repeat sick_scan_xd_api_test ...\n", (char)user_key, user_key);
  } while (user_key == 'R' || user_key == 'r');

  // Unload and exit
  printf("sick_scan_xd_api_test finishing...\n");
  if ((ret = SickScanApiUnloadLibrary()) != SICK_SCAN_API_SUCCESS)
    exitOnError("SickScanApiUnloadLibrary failed", ret);
  printf("sick_scan_xd_api_test finished successfully\n");

On the first connection, all goes well and the lidar data is received (cf first picture). On the second connection, the .launch file is parsed, but on startup, the sick_scansegment_xd thread stops (cf second picture).

Thanks for your time

data_first_initialization data_second_initialization

rostest commented 5 months ago

Thanks for your feedback. We will analyze the reconnection to the picoScan after power down and up.

rostest commented 5 months ago

We were able to reproduce and fix the problem. Thanks for reporting! Please find an update in branch https://github.com/SICKAG/sick_scan_xd/tree/feature/api_reinitialize and retry.

paulinelvne commented 5 months ago

Hello, After testing the same test file as in my previous message, I still get "sick_scansegment_xd thread finishing" after "sick_scansegment_xd (sick_picoscan) started" on the second initialization (see lines in photo). Screenshot_1

rostest commented 5 months ago

Thanks for following up. Using the update in branch feature/api_reinitialize and your modified sick_scan_xd_api_test.cpp, I can not reproduce the error. Find a complete logfile attached of my build and run for details. 20240417_sick_scan_xd_api_log.zip

Make sure that the sick_scan_xd library is completely rebuild incl. make install. Maybe a previous sick_scan_xd library was still in the path and loaded by sick_scan_xd_api_test on runtime?

You can check which library is loaded during runtime by the following commands:

ps -elf | grep sick_scan_xd_api_test        # get pid of sick_scan_xd_api_test
cat /proc/<pid>/maps | grep libsick_scan_xd # get full library path of loaded libsick_scan_xd
ls -al <path>libsick_scan_xd_shared_lib.so  # check build time of loaded libsick_scan_xd
paulinelvne commented 5 months ago

Thank you very much for all this information. Indeed, the library of another folder was loading by default. Everything now works. Thanks again for your time

paulinelvne commented 5 months ago

Hello, after new tests I noticed something strange. When connecting with the wrong lidar address, despite the connection error messages "Tcp::open: Failed to open TCP connection to 192.168.12.23:2111, aborting", the ret variable is always equal to SICK_SCAN_API_SUCCESS which does not allow the example to stop. What's more, when you press a key on the keyboard to stop the example, you get stuck in the SickScanApiClose function, as you can see in the photo below. I'm also attaching your example, which I've modified slightly.

Thanks in advance Screenshot_3 sick_scan_test.zip

rostest commented 5 months ago

Thanks for your feedback, we will investigate the error.

Note that return value SICK_SCAN_API_SUCCESS means that the SickScanApiInit-function itself returned without error, i.e. the sending and receiving threads and queues have been started etc.pp. It does not necessarily mean that the lidar initialization has been completed (successfully or with error). Use functions SickScanApiGetStatus or SickScanApiRegisterDiagnosticMsg to get a status code and message (status_code defined in SICK_DIAGNOSTIC_STATUS is: OK=0 (normal operation), WARN=1 (warning), ERROR=2 (error, should not occure), INIT=3 (initialization after startup or reconnection), EXIT=4 (sick_scan_xd exiting)). During initialization (with or without success), the status code is SICK_DIAGNOSTIC_STATUS::INIT.

I noticed that ROS kinetic is used in your sick_scan_test.cpp file. If using ROS is an option, we recommend using ROS-1 or ROS-2. Under ROS you can subscribe to all messages and use its advantages like interprocess communication, message passing, pointcloud handling and visualization and integration of multiple lidars. Just make sure that each lidar is launched separately with different ip addresses and different ros topics.

paulinelvne commented 5 months ago

Thank you for all this information.

Unfortunately the use of ROS is not an option for us. We still have a problem closing the connection with a lidar. This happens when you want to connect to an address where there was no lidar (lidar off or error in the ip address), the connection doesn't close properly and it's impossible to connect again. I've attached the test file and the output file, where you can see that the "SickScanApiClose" function gets stuck. The test performed :

We have run this test on linux and windows and the same problem appears.

Thanks in advance !

test_sick_scan.zip

rostest commented 5 months ago

Thanks for following up and your informations. We could reproduce and fix the error. Please use the cumulative update in branch https://github.com/SICKAG/sick_scan_xd/tree/feature/api_reinitialize and retry. Note that SickScanApiClose() after SickScanApiInit with a wrong ip address may take some seconds due to TCP timeouts.

paulinelvne commented 5 months ago

Thank you very much for your feedback. Everything seems to work in callback. However, when I set the polling parameter to true, a core dumped error appears. I've attached the test file and the output file. The test performed :

Thanks in advance ! test_sick_scan.zip

rostest commented 5 months ago

Thanks for your feedback. We will analyze the problem.

Note that polling is not recommended for picoScan or multiScan devices (https://github.com/SICKAG/sick_scan_xd/blob/develop/doc/sick_scan_api/sick_scan_api.md):

image

rostest commented 5 months ago

We could reproduce and fix the problem. Please use the recent update in branch https://github.com/SICKAG/sick_scan_xd/tree/feature/api_reinitialize and rebuild.