tier4/CalibrationTools

launch failed with error "package 'lexus_description' not found"

ajay1606 opened this issue ยท 19 comments

Hello,
Thanks for the very useful tools.

Am trying to run "Extrinsic ground-plane calibration (base-lidar)" using the launch file. But Launch terminates with the following error message.

Command:
ros2 launch extrinsic_calibration_manager calibration.launch.xml \ mode:=manual sensor_model:=aip_xx1 vehicle_model:=jpntaxi
Error:
ERROR] [launch]: Caught exception in launch (see debug for traceback): "package 'jpntaxi_description' not found, searching:

Command:
ros2 launch extrinsic_calibration_manager calibration.launch.xml \ mode:=ground_plane sensor_model:=aip_x1 vehicle_model:=lexus vehicle_id:=my_awesome_vehicle
Error:
ERROR] [launch]: Caught exception in launch (see debug for traceback): "package 'lexus_description' not found, searching:

image

Any suggestions, please?

Platform:

Ubuntu: 22.04
Ros: Humble
Calibration tools: humble branch

Hi, thanks for your interest in our tools.

This repository was at first intended for its use uniquely with autoware, so there are parts that assume you use it (as soon as the review process for the current PRs end I plan to refactor the code and make it more independent).

If you want to skip the use of autoware and use those sensors, please use add the specification logging_simulator:=False in the launch command. If you have any more doubts or problems let us know and help you !

@knzo25 Thank you so much for your quick response. And am able to launch command
ros2 launch extrinsic_calibration_manager calibration.launch.xml \ mode:=ground_plane sensor_model:=aip_x1 vehicle_model:=lexus vehicle_id:=my_awesome_vehicle logging_simulator:=False

But still unable to get the ground_plane module to successfully run. Am getting error like shown in the image.

image

Currently, our bag file is as follows:

Topic Name: /points_raw
Frame_id: base_link

Please could you guide to get successful run.

Hi, as the error message suggests, the sensor_kit_base_link does not exists.
Although you may want to calibrate directly base_link to your_lidar_frame, in autoware an additional sensor_kit_base_link frame exists (for example. if you were to mount your sensors in an additional structure over the vehicle, that would be considered the sensor kit).

If you do not have the frame, please set in your launcher (reference), the parent_frame to base_link. Also please keep in mind that the tool looks to calibrate between parent_frame and child_frame, so please make sure they match your use case.

Let un know if you have more doubts !

@knzo25 Thanks for your input. But still unable to get it to work. Am getting this
warning continuously in the terminal.

[extrinsic_ground_plane_calibrator-4] Warning: Invalid frame ID "velodyne_top" passed to canTransform argument source_frame - frame does not exist
[extrinsic_ground_plane_calibrator-4]          at line 93 in ./src/buffer_core.cpp

Any suggestions please !

Hi, as the line suggests you are missing the velodyne_top frame, which in our case, is the frame we try to calibrate.
I you need a more hands on support we would need both to see the code you are trying to execute (e.g., make a fork and prepare a branch) and the data in question.

@knzo25 Thank you so much for your kind assistance I have forked the repository as you suggested and updated the modifications currently am working with. Also, sample bag file was uploaded and the link can be found under ROSBAG Example in the section.

In the shared bag file, I have modified the lidar input point cloud topic frame id to "velodyne_top" to maintain consistency with autoware input frame id.

Thank you so much.

Hi, thanks for preparing the branch.
Unfortunately, I will be out due to some experiments for the following two days, so I will try your branch after I come back ๐Ÿ™

@knzo25 Have you got any chance to check our data ? It Would be very much helpful.

Hi, sorry for the delay.
I just checked the data and the code and understood the problem, but it seems we have a misunderstanding on how we perform the base calibration.

What this tool does is essentially find a plane in which we assume lies the base_link. However, just given this information, we can not know where exactly in this plane it lies. As such, we assume an initial calibration (which is not available in your data -> cause of the error message) that is used as a guess of where exactly the base_link lies. Thus, combining this initial calibration, and the plane we are sure the base_link lies, we can project the initial calibration into the plane, giving us the best bet of where the frame lies.

It is not possible just with a lidar mounted on the vehicle to estimate accurately the base_link (some other additional information, external features, sensors, etc are needed).

In your case, I recommend looking at out branch that implements a full base_link calibration. However, this tool requires several elements (tags) to work and id currently undergoing a drastic change (this is partially what got me busy this week)

Let me know if you have any doubts !

@knzo25 Thank you so much for your detailed explanation, it was very helpful in understanding this package more clearly.
By the way, how can input initial calibration params ? In the launch file link Is these following .YAML files are initial params ?


  <!-- extrinsic_calibration_client -->
  <arg name="src_yaml" default="$(find-pkg-share individual_params)/config/$(var vehicle_id)/$(var sensor_model)/sensor_kit_calibration.yaml"/>
  <arg name="dst_yaml" default="$(env HOME)/sensor_kit_calibration.yaml"/>

If so, then calibration_tools must contains individual_params package , but i cant find it in current version of calibration_tools repo. But its in autoware_universe. So should we run calibration_tools along with autoware_universe ?

Hi,
this repository has a structure that was designed to run alongside autoware-based projects (as soon as we release the pending tools, we will re design this repository so that anyone can use it easily).

autoware.universe is only required for another tool (mapping based lidar-lidar) and only in the form of a message.

Usually, your project will publish the tf tree with something like robot models, etc (this is from your side).
In our case, the individual params are read by a package like this one, and while the calibration manager reads initial params they are not used (old API soon to be removed).

In essence, you must provide a tf structure that connects the base link with the lidar, which you could to even using a static tf broadcaster if you just wanna test things, although ROS has standard/recommended ways to to this (e.g., see this link)

@knzo25 Thank you so much for very useful links, i will go through it.

@knzo25 Based on your input i have tried with following.

Input Point cloud:

Frame Id: sensor_kit_base_link
Topi Name: /points_raw

Setting up Tf structure to just test ground_plane as following:

//Static tf broadcaster

 geometry_msgs::msg::TransformStamped t;
    t.header.stamp = this->get_clock()->now();
    t.header.frame_id = "base_link";
    t.child_frame_id = "sensor_kit_base_link";
    t.transform.translation.x = atof(transformation[2]);
    t.transform.translation.y = atof(transformation[3]);
    t.transform.translation.z = atof(transformation[4]);
    tf2::Quaternion q;
    q.setRPY(
      atof(transformation[5]),
      atof(transformation[6]),
      atof(transformation[7]));
    t.transform.rotation.x = q.x();
    t.transform.rotation.y = q.y();
    t.transform.rotation.z = q.z();
    t.transform.rotation.w = q.w();
    
    geometry_msgs::msg::TransformStamped t2;
    t2.header.stamp = this->get_clock()->now();
    t2.header.frame_id = "sensor_kit_base_link";
    t2.child_frame_id = "velodyne_top_base_link";   
    t2.transform.translation.x = 0;
    t2.transform.translation.y = 0;
    t2.transform.translation.z = 0;
    t2.transform.rotation.x = 0;
    t2.transform.rotation.y = 0;
    t2.transform.rotation.z = 0;
    t2.transform.rotation.w = 1;
       
    geometry_msgs::msg::TransformStamped t3;
    t3.header.stamp = this->get_clock()->now();
    t3.header.frame_id = "velodyne_top_base_link";
    t3.child_frame_id = "velodyne_top";
    t3.transform.translation.x = 0;
    t3.transform.translation.y = 0;
    t3.transform.translation.z = 0;
    t3.transform.rotation.x = 0;
    t3.transform.rotation.y = 0;
    t3.transform.rotation.z = 0;
    t3.transform.rotation.w = 1;
    
    tf_static_broadcaster_->sendTransform(t);
    tf_static_broadcaster_->sendTransform(t2);    
    tf_static_broadcaster_->sendTransform(t3);  

And there were no Tf error, but plane segmentation breaks inside extractGroundPlane and returns ROS warn message as below.

[extrinsic_ground_plane_calibrator-4] [INFO 1677923469.573001233] [sensor_kit.sensor_kit_base_link.base_link.extrinsic_ground_plane_calibrator]: PCA-based rough plane normal. x=-nan, y=-nan, z=-nan (extractGroundPlane()

Would you please suggest fix ?

Hi, the sensor_kit to velodyne_top_base_link and velodyne_top_base_link to velodyne_top look well (I can not be sure about base_link to sensor_kit_base_link this it seems you cut that part).

The part with the nans is relatively straightforward. Based on a pointcloud it just estimates the PCA components, so the only reasons a nan may be the result (as far as I can think of) are that the pointcloud is empty, the pointcloud itself is corrupted by that point (maybe the transforms?) or that PCL has a bug (not likely).

I leave these thoughts with you for now as it is currently weekend here in Japan. When I have a breath at work I will try with the data you provided before :)

@knzo25 Thank you so much.

Here are the actual broadcasted static TF structure.

Screenshot from 2023-03-05 16-24-18

And, Input Point cloud inside extractGroundPlane is verified and it is confirmed that there is data. But normal estimation returning null, but couldn't understand reason. I will check it and get back to you.

@knzo25 I have gone through plane detection algorithm in detail and i have observed following, would you please share your opinion on this ?

  1. After testing each part separately i found that, With current data, PCA returns NAN value for single scan data. But PCA returns non-nan values if only part of the scan input to the algorithm.

PCA: returns NAN values

image

PCA: returns ( rough_normal.x()=0.00816932, rough_normal.y()=0.010659, rough_normal.z()=0.9999 )
image

  1. In the next part, Plane detection using RANSAC , unable to find Plane.

By the way, may i look at once your input data for this algorithm ? It will be very much helpful.

Hi,
I had a look at your data and can confirm that PCA is failing even though the pointcloud is not singular, does not have NANs nor any other weird value. I find this interesting since the implementation does not have any weird parts
https://github.com/PointCloudLibrary/pcl/blob/master/common/include/pcl/common/impl/pca.hpp

After that I checked ransac and it is just the parameters are to strict to your surface.
The product I designed this code has a REALLY flat surface and I was requested very low margin of error so I got very strict with the parameters.
If you take a good look at the pointcloud, it is not really flat.

To make it work for your PC you need to do as you did before cropping the PC for now (I used a 20m radius)
and adjust the following parameters in the launcher

  <param name="max_inlier_distance" value="0.05"/>
  <param name="min_plane_points_percentage" value="15.0"/>

Using the parameters I just mentioned the plane could be found no issues.

@knzo25 Thank you so much for your patience and kind response always.
Finally, i got it worked with all your inputs.

Glad we were able to help you and make it work !
Please remember to close the issue later :)