tradr-project / static_transform_mux

A helper node that makes sure everybody knows about all static transforms, even if they are published by multiple publishers.
BSD 3-Clause "New" or "Revised" License
12 stars 4 forks source link

Not quite solved #1

Open nslay opened 5 years ago

nslay commented 5 years ago

I think this is a very clever solution. In fact, when I read your response in some github PR, I almost immediately knew this should be the solution to the problem!

However, when playing with, say, 20+ static transforms, somehow static_transform_mux is not necessarily the last /tf_static message recorded/played back by rosbag record/play. I don't know why or how the messages get fumbled or received, stored or played out of order, just that they do and that this clever solution is not 100%. In fact, it doesn't work most of the time with one or two stray static transforms somehow arriving or playing back after the aggregate /tf_static message is sent by static_transform_mux (no matter what I do, whether I start it first or last or 10 seconds after... it doesn't matter).

peci1 commented 5 years ago

Hi, thanks for the feedback. Would you think some periodic publishing (e.g. once in 1 or 10 seconds) would help? I could add that as an option.

nslay commented 5 years ago

Yeah. As long as static_transform_mux eventually has the last say, this solution will work! I find it completely confusing that static_transform_mux's message does not already arrive last. But I suppose there is no guarantee that rosbag record necessarily process or receive in order the 20+ messages from multiple nodes publishing to /tf_static. If it was on a single TCP connection, it should be in order. But I think ROS is probably more point-to-point and that there are actually 20+ connections. Throw in callback queues and maybe some parallel processing aspects happening in rosbag record, it's probably only more confusing to think about!

Alternatively, static_transform_publisher could be taught to do what static_transform_mux already does, except from the start and with 1 single TFMessage. My solution was to make a multiple_static_transform_publisher that reads a file line-by-line with each line having static_transform_publisher-like arguments. Then I simply publish one single combined TFMessage like static_transform_mux and all my rosbag headaches go away. I think this is a bit more elegant than having a launch file... ~20 lines vs hundreds saturated by XML formatting.

This, of course, doesn't mean static_transform_mux isn't still useful. If someone wanted to publish static transforms from multiple nodes (for whatever reason), then my solution doesn't apply anymore.

peci1 commented 5 years ago

That's exactly what we do - we have zillions of launch files for various sensors, and some of them need to publish some static transforms - and the easiest way to do that is to put a line in the launch file... So we also have like 10 static TF publishers...

So no, editing static_transform_publisher is also not a general solution... I think a really working general solution would need a big rework of the already exising API, which is IMO not happening any more in ROS 1.

nslay commented 5 years ago

Yeah... latched topics are a real mess! It works out from rosbag play if you slowly step through the initial /tf_static messages one at a time so that every node receives each message. But when these messages are sent too quickly, a node does not necessarily see all of them.

Before playing with aggregated TFMessage, I was originally just pressing the step key 20 times until rviz or rostopic echo would see each one. Very annoying...

I think if static_transform_mux sends the transforms periodically, this would be a good and general workaround.

ihadzic commented 1 year ago

Might be a bit belated comment relative to when this was open, but the only way I was able to fully solve the problem is to separate the mux input and mux output topics. That requires always running the mux and remapping all sources of tf_static topic to use a different topic name (e.g. tf_static_in). That guarantees that /tf_static has one and only one publisher which resolves the race discussed above.