ros-industrial / ros_canopen

CANopen driver framework for ROS (http://wiki.ros.org/ros_canopen)
GNU Lesser General Public License v3.0
342 stars 274 forks source link

canopen_master: reading SDO response fails #317

Closed rostest closed 5 years ago

rostest commented 5 years ago

Hello,

I'm trying to use canopen_chain_node to communicate with a CAN device (can node id 0x0A). candump shows initialisation (communication reset) and the first SDO:

can0  000   [2]  82 0A                       # NMT to can-device 0x0A: 0x82, reset communication
can0  70A   [1]  00                          # can-device 0A responds with bootup-message
can0  60A   [8]  40 17 10 00 00 00 00 00     # canopen_chain_node sends SDO request object 1017
can0  58A   [8]  4B 17 10 00 00 00 00 00     # can-device 0A answers with SDO response object 1017 (value 0x00000000)

Unfortunately, canopen_chain_node does not receive the SDO response from can-device 0A and terminates with a canopen::TimeoutException:

[ INFO] [1549898105.070432799]: Initializing XXX
[ INFO] [1549898105.071024021]: Current state: 1 device error: system:0 internal_error: 0 (OK)
[ INFO] [1549898105.071415827]: Current state: 2 device error: system:0 internal_error: 0 (OK)
SDO sending to client_id=1546 entry=0x1017sub0 canstate.ready=1 canstate.driver_state=2
SDO sent successfully: client_id=1546 entry=0x1017sub0 msg.canid=60a msg.data.size=8 msg.data[0]=40 canstate.ready=1 canstate.driver_state=2
SDO timeout: client_id=1546 entry=0x1017sub0 msg.canid=60a msg.data.size=8  msg.data[0]=40 canstate.ready=1 canstate.driver_state=2
Did not receive a response message
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<canopen::TimeoutException> >'
  what():  SDO

The SDO request has been sent successfully, but "reader_.read(&msg,boost::chrono::seconds(1))" (canopen_master/src/sdo.cpp line 417) failed for some reason. I've added a few debug messages "SDO ..." in canopen_master/src/sdo.cpp.

Does anyone have an idea, what might cause this read error? Any hints are highly appreciated.

Thanks and best regards!

mathias-luedtke commented 5 years ago

Did you see additional lines in the candump after the SDO response? Please use -ta to log with time stamps.

rostest commented 5 years ago

Thanks for your response! Here's the complete candump:

 (1549966303.412790)  can0  000   [2]  82 0A                    # NMT to can-device 0x0A: 0x82, reset communication
 (1549966303.416507)  can0  70A   [1]  00                       # can-device 0A responses with bootup-message
 (1549966303.418194)  can0  60A   [8]  40 17 10 00 00 00 00 00  # canopen_chain_node sends SDO request object 1017
 (1549966303.420603)  can0  58A   [8]  4B 17 10 00 00 00 00 00  # can-device 0A answers with SDO response object 1017 (value 0x00000000)
 (1549966304.418698)  can0  60A   [8]  80 17 10 00 00 00 04 05  # abort message to can-device 0A after canopen::TimeoutException

The last abort message (0x80 ...) is already caused by the canopen::TimeoutException after the SDO timeout (read SDO response failed, "abort(0x05040000); // SDO protocol timed out." in sdo.cpp line 419).

mathias-luedtke commented 5 years ago

I would add some debug print in the handling code (SDOClient::processFrame) to see what's going on. Perhaps the response does not match the expected format. Do you have any special set-up? What ROS version do you use?

rostest commented 5 years ago

Thanks for the hint. I put some debug output into function SDOClient::processFrame, but the function is never called. Probably because it's called after the "if(!reader.read(&msg,boost::chrono::seconds(1))){...}" case, which is never reached (reader.read fails). ROS version is melodic with roscpp 1.14.3, no special setup.

mathias-luedtke commented 5 years ago

I put some debug output into function SDOClient::processFrame, but the function is never called.

It should get called.. Perhaps it's a race condition (or something similar). You could try to set a default for 1017 in your EDS.

rostest commented 5 years ago

Thanks again. Missing DefaultValues in the eds-file caused the canopen::TimeoutException when trying to read the first SDO response. SDO requests and responses work as expected, after adding DefaultValues in the eds-file for objects 1017 (Producer Heartbeat Time), 1800 (Transmit PDO Communication Parameter 1), 1801 (Transmit PDO Communication Parameter 2), 1A00 (Transmit PDO Mapping Parameter 1) and 1A02 (Transmit PDO Mapping Parameter 2) incl. their subindices. I suppose, canopen_master just presumes those DefaultValues. Checking their existence in advance could be a nice extension, but adding the required DefaultValues solves this issue.