Points 1 and 3:
You need to declare the tf_prefix parameter before you load anything that publishes TFs that should be in the namespace.
Move the line <param name="tf_prefix" value="qbot0" />
in your launch file before:
<!-- run kobuki base -->
<include file="$(find kobuki_node)/launch/minimal.launch"/>
Also the static_transform_publisher
does not use the parameter I think, so you should either move those links to the URDF or use an argument for those transforms.
With the argument your launch file would look something like this:
<launch>
<arg name="tf_prefix" default="qbot0"/>
<group ns="$(arg tf_prefix)">
<param name="tf_prefix" value="$(arg tf_prefix)" />
<!-- run kobuki base -->
<include file="$(find kobuki_node)/launch/minimal.launch"/>
<!-- tf config -->
<node pkg="tf" type="static_transform_publisher" name="camera_to_base" args="0 0 0.1 0 0.0 0 $(arg tf_prefix)/base_footprint $(arg tf_prefix)/camera_link 100"/>
<node pkg="tf" type="static_transform_publisher" name="robot_state_publisher" args="0 0 0 0 0.0 0 $(arg tf_prefix)/base_footprint $(arg tf_prefix)/base_link 100"/>
<!-- run kinect -->
<include file="$(find freenect_launch)/launch/freenect.launch" />
</group>
</launch>
As for point 2. There are a range of tools that would help with debuging. The rosrun tf view_frames
and rosrun rqt_tf_tree rqt_tf_tree
both provide sources for the transform, there are other tools to work with tf like
$ rosrun tf
bullet_migration_sed.py tf_change_notifier tf_empty_listener tf_remap
static_transform_publisher tf_echo tf_monitor view_frames
And there are more, but it's too much for me to go into right now.
updated answer
I changed the arg tf_prefix I previously used in the launch file to robot_name to be less confusing.
As @jaindu mentions it is possible to pass the tf_prefix to kinect_frames.launch
from looking at the launch files you should include the freenect_tf_prefix.launch
instead of freenect.launch
for that, the relevant lines would look something like this:
<include file="$(find freenect_launch)/launch/freenect_tf_prefix.launch">
<arg name="tf_prefix" default="$(arg robot_name)"/>
</include>
as for the kobuki_node
stuff it is a bit harder to test without setting up quite a bit of stuff. As far as I can tell, setting the parameters in the kobuki_node minimal.launch should fix the problem. As I said it's not very easy to test without actual feedback but adding the params odom_frame
and base_frame
to minimal.launch
, passing the robot_name arg and using it in the params might work. Here is my guess as to what might work:
kobuki_node minimal.launch
<!--
Standalone launcher for running a default Kobuki
-->
<launch>
<arg name="kobuki_publish_tf" default="true"/> <!-- Publish base_footprint - odom transforms (usually good thing to have for localisation) -->
<arg name="tf_prefix" default=""/>
<node pkg="nodelet" type="nodelet" name="mobile_base_nodelet_manager" args="manager"/>
<node pkg="nodelet" type="nodelet" name="mobile_base" args="load kobuki_node/KobukiNodelet mobile_base_nodelet_manager">
<rosparam file="$(find kobuki_node)/param/base.yaml" command="load"/>
<param name="odom_frame" value="$(arg tf_prefix)/odom"/>
<param name="base_frame" value="$(arg tf_prefix)/base_frame"/>
<param name="publish_tf" value="$(arg kobuki_publish_tf)"/>
<remap from="mobile_base/odom" to="odom"/>
<remap from="mobile_base/joint_states" to="joint_states"/>
</node>
<node pkg="diagnostic_aggregator" type="aggregator_node" name="diagnostic_aggregator" >
<rosparam command="load" file="$(find kobuki_node)/param/diagnostics.yaml" />
</node>
</launch>
your launch file
as the tf_prefix param does not have an effect in this file, I removed it.
<launch>
<arg name="robot_name" default="qbot0"/>
<group ns="$(arg robot_name)">
<!-- run kobuki base -->
<!-- <include file="$(find kobuki_node)/launch/minimal.launch"/> -->
<include file="$(find kobuki_node)/launch/minimal.launch">
<arg name="tf_prefix" default="$(arg robot_name)"/>
</include>
<!-- tf config -->
<node pkg="tf" type="static_transform_publisher" name="camera_to_base" args="0 0 0.1 0 0.0 0 $(arg robot_name)/base_footprint $(arg robot_name)/camera_link 100"/>
<node pkg="tf" type="static_transform_publisher" name="robot_state_publisher" args="0 0 0 0 0.0 0 $(arg robot_name)/base_footprint $(arg robot_name)/base_link 100"/>
<!-- run kinect -->
<!-- <include file="$(find freenect_launch)/launch/freenect.launch" /> -->
<include file="$(find freenect_launch)/launch/freenect_tf_prefix.launch">
<arg name="tf_prefix" default="$(arg robot_name)"/>
</include>
</group>
</launch>
I guess I should add that neither of the packages use the tf_prefix
as I think it was intended to be used. Kobuki does not use it based on the launch files I have seen so far (not many) and I have not looked at the code. And I guess not using it is OK. You can read more about it here tf_prefix deprecated
Originally posted by Reamees with karma: 591 on 2019-04-01
This answer was ACCEPTED on the original site
Post score: 4
Original comments
Comment by TharushiDeSilva on 2019-04-01:
@Reamees, I tried doing this, but still no luck. Now I can see that the TF tree is broken into parts with some frames with namespace, and some frames without namespace. This is the TF tree.
I tried adding the tf_prefix argument into kobuki udrf files. But it did not make any difference.
Comment by janindu on 2019-04-01:\
- To fix the
odom->base_footprint
transformation : The kobuki_node sets the frame names from the parameters ~odom_frame
and ~base_frame
. So you need to set them inside the launch file.
Comment by janindu on 2019-04-02:
And if you take a look at the freenect.launch
file you can see that it uses rgbd_camera kinect_frames.launch
to launch tf. Going through that launch file, you can see that you can pass tf_prefix
as an argument. You can use that to join the camera_link
tree to qbot0/camera_link
.
Comment by TharushiDeSilva on 2019-04-02:
@Reamees, @janindu, Thank you both for the answers to solve my issue. I was able to set the odom
frame and the base_footprint
frame by considering the frame names as private parameters. (~odom_frame
, ~base_frame
as @janindu mentioned) Then I added the tf_prefix default parameter to rgbd_launch/launch/kinect_frames.launch
file.
I was able to publish all the frames as I expected
But now I cannot visualize my camera output, which means the expected topics are not published and hence cannot be visualized by RViz. Looks like I'm going to enjoy solving that one. :D
Comment by Reamees on 2019-04-03:
if you launched the nodes in a namespace the topics will also most likely be in the same namespace.
Comment by TharushiDeSilva on 2019-04-03:
Yes. I think my program is loading data via the sources in the /opt/ros/kinetic/share
directory. They have all the old and default names. I have all the required sources within my workspace, and sourcing the workspace doesn't seem to work. I tried removing packages from /opt/ros/kinetic/share
but it led to more errors. So I'm currently working on how to load drivers and other sources from my workspace.
Comment by janindu on 2019-04-03:
In your sourced workspace, try rospack find package_name
. It would tell you from where the packages are loaded.
Comment by TharushiDeSilva on 2019-04-04:
The reason for this issue was; apart from installing the packages from the source, I had also installed them using command line. I did this when I was getting familiar with the devices and equipment because I wanted to play around. So as an example, I had freenect package installed in my /opt/ros/..
as well as in my workspace(cloned from git). I uninstalled the packages from the /opt/ros/.. directory and after that my parameter changes became effective.
One lesson I learned was; it's troublesome to locate sources/drivers under common ROS installation space where I don't have control over it. I'm not sure whether it's a good practice, because there can be several workspaces in a machine.
Comment by janindu on 2019-04-05:
The best practice is to install common ROS packages using apt
. You should be able to configure the nodes using arguments / parameters specified in a launch file without having to worry about any code changes. The only reason to build from source IMO is when you do need a code change to configure a badly implemented node.
I saw in a different problem you posted that octomap_server
subscribes to a topic in global namespace (where you do need a code change if you want namespaces). However, a quick look at the kinetic devel and melodic devel branches show that it's fixed there.
Comment by janindu on 2019-04-05:
Careful use of source catkin_workspace_n/devel/setup.bash
allows multiple ROS workspaces / ROS distributions to co-exist in a Linux environment.
Comment by Reamees on 2019-04-05:
What @janindu said. Also whether the package in your WS or the package installed with apt is used depends on which ever package appears first in your ROS_PACKAGE_PATH env variable. You can manipulate the variable manually, to test stuff out. What has been working for me so far is having the lines source /opt/ros/kinetic/setup.bash
and source ~/catkin_ws/devel/setup.bash
in .bashrc
in that order. That way it has always used the package in my WS if there are two packages with the same name. You might not be using kinetic or your WS might not be called catkin_ws, so change that according to your setup.
Comment by TharushiDeSilva on 2019-04-05:
@janindu, @Reamees, Thank you both for the tips. I should try those things in the future.