-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generalized Lidar Simulator PR #78
Conversation
Thanks for the effort! Unfortunately, the changes made the code more complex instead of more simple. I think there is a much leaner solution :) Please have a look at the following:
|
Hi Hermann :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the contribution. I would try to make it a bit more generic by just providing a pose / transformation message topic (whichever source it is, e.g., marker, ground truth message etc) and then publish the simulated lidar from there. For the static offset you would then simply add this to this transformation (or to zero, if this published topic does not exist). Ideally you would then use much less parameters.and special cases.
<param name="SimMarker" value="true" /> | ||
<param name="FixLidarScans" value="true" /> | ||
<param name="SimMarkerPoseTopic" value="/mesh_id_marker/feedback" /> | ||
<param name="cadTopic" value="/mesh_publisher/mesh_out" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be enough to just give a pose or transformation topic this node subscribes to this can then for instance come from an interactive marker. Then you don't need a specific marker flag.
@@ -23,6 +24,9 @@ PointCloud lidar_scan; | |||
bool got_CAD = false; | |||
std::string tf_map_frame; | |||
|
|||
bool use_marker_for_sim; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As mentioned above, ideally not work with an extra flag for the marker, only with a subscribed topic.
@@ -38,6 +42,7 @@ float noise_variance; | |||
ros::Publisher scan_pub; | |||
|
|||
void getCAD(const cgal_msgs::TriangleMeshStamped &cad_mesh_in); | |||
void sim_lidar_at_marker(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would integrate this function with the regular simulate_lidar()
function.
use_marker_for_sim = nh_private.param<bool>("SimMarker", false); | ||
fix_lidar_scan = nh_private.param<bool>("FixLidarScans", false); | ||
ros::Subscriber marker_pos_sub; | ||
if (use_marker_for_sim) { | ||
std::cout << "Move marker to get lidar scans" << std::endl; | ||
std::string marker_pos_topic = nh_private.param<std::string>("SimMarkerPoseTopic", "fail"); | ||
marker_pos_sub = nh.subscribe(marker_pos_topic, 20, &sim_lidar_at_marker); | ||
// Push back no rotation | ||
quat.push_back(1); | ||
quat.push_back(0); | ||
quat.push_back(0); | ||
quat.push_back(0); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THis should be more generic: e.g., checking if a pose / transformation topic is given as a parameter and if so listening to. Otherwise revert to a standard behaviour (e.g., publishing from the origin).
x = nh_private.param<float>("groundtruthx", 0); | ||
y = nh_private.param<float>("groundtruthy", 0); | ||
z = nh_private.param<float>("groundtruthz", 0); | ||
quat = nh_private.param<std::vector<float>>("groundtruth_orientation", {}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this would then be the standard behaviour.
void sim_lidar_at_marker(const visualization_msgs::InteractiveMarkerFeedbackConstPtr &feedback) { | ||
// Change position of lidar to the one of the marker (different coordinate system) | ||
x = -(feedback->pose.position.y) - 1; | ||
y = feedback->pose.position.x + 1; | ||
z = feedback->pose.position.z; | ||
|
||
std::cout << std::endl; | ||
std::cout << "Position of marker/lidar: " << x << " " << y << " " << z << std::endl; | ||
std::cout << std::endl; | ||
|
||
if (got_CAD) { | ||
simulate_lidar(); | ||
lidar_scan.clear(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
THis could be fully integrated with simulate_lidar()
reference_mesh->transform(ctransformation); | ||
|
||
std::cout << "Lidar frame transformed according to ground truth data" << std::endl; | ||
if (!fix_lidar_scan) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use this parameter as mentioned above and derive it from the input topic (or not).
Oh, I see that Hermann has basically commented the same. I guess I hadn't reloaded the github page. |
Hi :), thanks for the feedback. I have uploaded a new version yesterday, the commit is on the generalized_lidar-feature branch but oddly enough does not seem to appear here in the PR. I have now reverted the changes and will try it again, otherwise I will open a new PR. |
@@ -30,7 +30,7 @@ Panels: | |||
Experimental: false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the revised version, sorry for the inconvenience. SimLidar now uses the tf transformation between map (due to visualization reasons, switching to "marker" should be possible with a constant transformation in SimLidar) and marker_pose (frame from the interactive marker). I tried to simplify the code of SimLidar and to regulate certain things already in the launch file (constant pose, etc.) to become more modular.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, you were quick with applying all these changes :)
Looks very good, just have some minor comments about naming etc.
@@ -6,6 +6,6 @@ mapSamplingDensity: 20 | |||
usetoyproblem: true | |||
|
|||
#Select Matcher (only one) | |||
use_template: false | |||
use_go_icp: true | |||
usetemplate: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file should not change in this PR.
<param name="lidarFrame" value="$(arg lidar_frame)" /> | ||
</node> | ||
|
||
<group if ="$(arg SimMarkerLidar)"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess this is copied from some of my launch files. In the meantime, I found out that you can add the if="$(arg SimMarkerLidar)"
simply to the node itself, you don't really need the group tag around it.
<arg name="cad_file" default="$(find cpt_selective_icp)/resources/cla.json" /> | ||
<arg name="lidar_settings" default="$(find cpt_matching_algorithms)/config/sim_lidar_config.yaml" /> | ||
<arg name="SimMarkerLidar" value="true" /> | ||
<arg name="lidar_frame" value="marker_pose" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe a better name for the frame would be simulated_lidar_pose
<node pkg="tf" type="static_transform_publisher" name="SimFixLidar" args="-2 2 1 0 0 0.724872 0.6894984 map $(arg lidar_frame) 100"/> | ||
</group> | ||
|
||
<node name="mesh_positioning" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this node even necessary? I guess a static transform would be sufficient, together with publish_on_start
in the mesh_publisher.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not really sure about that. Is there a reason why two different fixed frames (map & marker) with different axes are used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, this is a bit confusing. We needed "map" and "marker" so far because we did not have global localization. The workflow is as follows:
"map" is the frame for the map of the icp localisation. Ie cpt_selective_icp will load a mesh into the map frame and localize the lidar in it. This is very dependent on where the map frame is initialized with respect to the robot.
For this, we use the marker to move the mesh around (this is the mesh published in marker frame). Once we get a good alignment, we call a service and cpt_selective_icp will set map := marker to initialize.
So basically the map frame is only necessary when using cpt_selective_icp. You don't need it here.
@@ -11,6 +11,7 @@ | |||
#include <ros/ros.h> | |||
#include <tf/transform_listener.h> | |||
#include <tf_conversions/tf_eigen.h> | |||
#include <visualization_msgs/InteractiveMarkerFeedback.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not be necessary.
bin_elevation = nh_private.param<std::vector<float>>("bin_elevation", {0}); | ||
dtheta = nh_private.param<float>("lidar_angular_resolution", 1); | ||
lidar_offset = nh_private.param<float>("lidar_offset", 1.5); | ||
noise_variance = nh_private.param<float>("accuracy_of_lidar", 0.02); | ||
|
||
scan_pub = nh.advertise<sensor_msgs::PointCloud2>("sim_rslidar_points", 1, true); | ||
fix_lidar_scan = nh_private.param<bool>("FixLidarScans", true); | ||
tf_lidar_frame = nh_private.param<std::string>("lidarFrame", "fail"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is no sensible default available, please rather check whether the parameter is available and otherwise raise an Error with a good message of what is failing.
@@ -79,7 +79,7 @@ int main(int argc, char **argv) { | |||
void getCAD(const cgal_msgs::TriangleMeshStamped &cad_mesh_in) { | |||
if (!got_CAD) { | |||
std::cout << "Processing CAD mesh" << std::endl; | |||
std::string frame_id = cad_mesh_in.header.frame_id; | |||
frame_id = cad_mesh_in.header.frame_id; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To avoid confusion with the lidar frame, please rename frame_id
into something more explicit, like mesh_frame_id
.
rospy.init_node("find_id_in_mesh") | ||
transform_pub = rospy.Publisher('/T_map_marker', Transform, queue_size=10) | ||
tf_broadcaster = TransformBroadcaster() | ||
marker = RosMarker('Marker Pose', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe you can make these strings parameters, such that e.g. for your usecase, the label would be "Simulated LiDAR", but others could apply useful labels for their applications.
<node name="lidar_simulator" pkg="cpt_matching_algorithms" type="sim_lidar_node" output="screen" launch-prefix="tmux split-window"> | ||
<rosparam command="load" file="$(arg lidar_settings)" /> | ||
|
||
<param name="FixLidarScans" value="false" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment here that explains this parameter better. Usually, the launch-file is what people who just want to use your code will look into first, because it gives a high-level interface to your nodes. So it is important to add explanations to parameters that are not straightforward to understand.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, this looks good! :)
Generalized Lidar Simulator PR
Hi :)
You can find the commit of the discussed generalized lidar simulator in this PR. The parameter SimMarker in the movable_lidar_sim.launch allows for moving the lidar scan around with the interactive marker if set on true, if set on false it will use the ground truth data in the config file of the simulator. Additionally, I have implemented the option to fix the lidar scan on the cad model. This can be switched on by setting the parameter FixLidarScan on true (also in the movable_lidar_sim.launch file). If set on false, it will create a point cloud of the lidar scan, where the lidar sensor is centered in the origin. Both variables are set per default on false in sim_lidar_node.cpp such that there is no change in the behavior for the already existing files.
Best,
Marc