heuristicus / spot_ros

ROS driver for controlling Boston Dynamics' Spot robot
https://heuristicus.github.io/spot_ros/
Other
268 stars 136 forks source link

Issue with PyKDL #101

Closed julianraheema closed 1 year ago

julianraheema commented 1 year ago

I have this error after launching: roslaunch spot_driver driver.launch

My settings: ROS: Melodic Python: 2, 3.6, and 3.8 are installed spot sdk: 2.3.5

I tried the solution in here https://github.com/orocos/orocos_kinematics_dynamics/issues/115, but no luck.

Traceback (most recent call last): File "/home/user1/src/catkin_ws/src/spot_ros/spot_driver/scripts/spot_ros", line 3, in from spot_driver.spot_ros import SpotROS File "/home/user1/src/catkin_ws/src/spot_ros/spot_driver/src/spot_driver/spot_ros.py", line 24, in import tf2_geometry_msgs File "/home/user1/src/catkin_ws/devel/lib/python3/dist-packages/tf2_geometry_msgs/init.py", line 34, in exec(fh.read()) File "", line 1, in File "/home/user1/src/catkin_ws/src/geometry2/tf2_geometry_msgs/src/tf2_geometry_msgs/tf2_geometry_msgs.py", line 31, in import PyKDL ImportError: dynamic module does not define module export function (PyInit_PyKDL) [spot/spot_ros-6] process has died [pid 14553, exit code 1, cmd /home/user1/src/catkin_ws/src/spot_ros/spot_driver/scripts/spot_ros joint_states:=/joint_states tf:=/tf __name:=spot_ros log:=/home/user1/.ros/log/7a8bb8da-a67b-11ed-bc52-9cb6d06c21cf/spot-spot_ros-6.log]. log file: /home/user1/.ros/log/7a8bb8da-a67b-11ed-bc52-9cb6d06c21cf/spot-spot_ros-6*.log

Thank you.

heuristicus commented 1 year ago

It may be that some of the points mentioned at https://github.com/heuristicus/spot_ros/issues/99 can help with this. But your best option is to switch to using noetic if you can. Also, you should update your SDK. 2.3.5 is now close to 2 years old.

dcolli23 commented 1 year ago

Hi, Is this driver tested with the newest Spot SDK? We're attempting to use this driver in our lab with Spot and Spot Core running version 3.2.X and are running into this PyKDL issue. This is further complicated by the fact that the Core runs Ubuntu 18.04 so we're somewhat forced to use Melodic over Noetic unless we want to jump into using Docker specifically for this driver.

I ask as we're weighing our options on if we should simply use the provided Python API and abandon ROS integration thanks to using a newer Spot and Core.

I'm asking here as I imagine anyone else using a Spot Core with 18.04 would run into similar issues.

Thanks!

heuristicus commented 1 year ago

Most of the driver is tested with the latest SDK. I don't have access to a spot core so I'm not sure what differences exist there. You might try using the melodic build instructions at https://github.com/heuristicus/spot_ros#building-for-melodic, but I've never personally used the driver on melodic so can't confirm if that actually works.

Part of the problem here is that the BD SDK expects use of python3, while the default on melodic is 2.7, which can lead to awkward mismatches.

There are notes here about installing the package pyKDL package from source, which may be an alternative option.

As a note, the place where we are currently using tf2_geometry_msgs is to transform poses to the body frame:

https://github.com/heuristicus/spot_ros/blob/bb82c29e9d51d12d57d53c8b4d4faecb600a1bc8/spot_driver/src/spot_driver/spot_ros.py#L594

These functions are only used to send trajectory commands to the robot to move if from where it currently is to a point relative to its current position, so if you do not need those, you can remove these lines and avoid the import:

https://github.com/heuristicus/spot_ros/blob/bb82c29e9d51d12d57d53c8b4d4faecb600a1bc8/spot_driver/src/spot_driver/spot_ros.py#L751-L888

If you do need the trajectory commands, there are a few options:

The code in the geometry msgs is here.

def do_transform_pose(pose, transform):
    f = transform_to_kdl(transform) * PyKDL.Frame(PyKDL.Rotation.Quaternion(pose.pose.orientation.x, pose.pose.orientation.y,
                                                                          pose.pose.orientation.z, pose.pose.orientation.w),
                                                PyKDL.Vector(pose.pose.position.x, pose.pose.position.y, pose.pose.position.z))
    res = PoseStamped()
    res.pose.position.x = f[(0, 3)]
    res.pose.position.y = f[(1, 3)]
    res.pose.position.z = f[(2, 3)]
    (res.pose.orientation.x, res.pose.orientation.y, res.pose.orientation.z, res.pose.orientation.w) = f.M.GetQuaternion()
    res.header = transform.header
    return res

In theory this could be replaced with a custom function to multiply transforms which does not use KDL.

Because we're using this function to transform frames which are not in the body frame to the body frame, another option is to remove the use of the _transform_pose_to_body_frame function entirely within the driver, and simply reject any transforms received which are not in the body frame.

julianraheema commented 1 year ago

Switching to Noetic solved my problem. Thank you.

dcolli23 commented 1 year ago

Thanks for the in-depth answer, @heuristicus! We'll try building with those instructions and if that doesn't work, we'll try using a Docker container that utilizes Noetic.