ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Tom Moore's answer is correct, however for others like me who are relatively new to ROS I'll restate everything a bit more explicitly with instructions. In this instance I am referring to the frame /odom as created by the robot_localization package, so my explanation relates to that package. The problem and solution may be different if you are using some other part of the navigation stack to track odometry. I'm also assuming that this is a ground based robot with IMU and odometry data.

Problem

You want to know how the frame /odom is initialised and how you can manually re-set it or control it's initialisation.

Cause

The frame /odom is created by an instance of robot_localization when the node is launched. Depending on your launch file you will find that upon launch the /odom frame's origin and/or orientation will match that of the robot (i.e. the origin and orientation of the frame you have set to "base_link_frame" in your launch file - generally /base_link)

However...you may find that the orientation does not match when you want it to or you want to be able to re-set it yourself later. Typically this is because the orientation is matching the non-zero input from your IMU at launch.

Solution

There are three things you can do to set the origin and orientation of /odom:

  1. Initialize /odom to match the origin and orientation of /base_link at launch.
  2. Manually re-set the origin and orientation of /odom by publishing a geometry_msgs/PoseWithCovarianceStamped to the /set_pose topic.
  3. Use the SetPose service to set the origin and orientation.

(There may be more options that I don't know about yet so feel free to correct me)

Setting /odom at launch

This is as simple as setting a single parameter in the launch file for your robot_localization instance that is creating /odom. Find your launch file and add the line:

<param name="imu0_relative" value="true"/>

To override the IMU data and match the orientations. The origin of /odom should already match.

Re-setting /odom by publishing to /set_pose

At any time you can publish a geometry_msgs/PoseWithCovarianceStamped message to the /set_pose topic. The topic likely won't appear using rostopic list until you publish to it. Type this into a terminal:

rostopic pub /set_pose geometry_msgs/PoseWithCovarianceStamped header: {stamp: now, frame_id: "odom"}, pose: {pose: {position: {x: 1.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} }, covariance: [1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}'

And replace the x,y,z,w values with whatever you want to want to set /odom to. Note that the code above will set the new pose relative to the old pose.

Use the SetPose service

I'm pretty unfamiliar with using services so I'll update this when I know more. In the meantime be mindful that this is an option but you'll have to set it up yourself.

Tom Moore's answer is correct, however for others like me who are relatively new to ROS I'll restate everything a bit more explicitly with instructions. In this instance I am referring to the frame /odom as created by the robot_localization package, so my explanation relates to that package. The problem and solution may be different if you are using some other part of the navigation stack to track odometry. I'm also assuming that this is a ground based robot with IMU and odometry data.

Problem

You want to know how the frame /odom is initialised and how you can manually re-set it or control it's initialisation.

Cause

The frame /odom is created by an instance of robot_localization when the node is launched. Depending on your launch file you will find that upon launch the /odom frame's origin and/or orientation will match that of the robot (i.e. the origin and orientation of the frame you have set to "base_link_frame" in your launch file - generally /base_link)

However...you may find that the orientation does not match when you want it to or you want to be able to re-set it yourself later. Typically this is because the orientation is matching the non-zero input from your IMU at launch.

Solution

There are three things you can do to set the origin and orientation of /odom:

  1. Initialize /odom to match the origin and orientation of /base_link at launch.
  2. Manually re-set the origin and orientation of /odom by publishing a geometry_msgs/PoseWithCovarianceStamped to the /set_pose topic.
  3. Use the SetPose service to set the origin and orientation.

(There may be more options that I don't know about yet so feel free to correct me)

Setting /odom at launch

This is as simple as setting a single parameter in the launch file for your robot_localization instance that is creating /odom. Find your launch file and add the line:

<param name="imu0_relative" value="true"/>

To override the IMU data and match the orientations. The origin of /odom should already match.

Re-setting /odom by publishing to /set_pose

At any time you can publish a geometry_msgs/PoseWithCovarianceStamped message to the /set_pose topic. The topic likely won't appear using rostopic list until you publish to it. Type this into a terminal:

rostopic pub /set_pose geometry_msgs/PoseWithCovarianceStamped header: {stamp: now, frame_id: "odom"}, pose: {pose: {position: {x: 1.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} }, covariance: [1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}'

And replace the x,y,z,w values with whatever you want to want to set /odom to. Note that the code above will set the new pose relative to the old pose.

Use the SetPose service

I'm pretty unfamiliar with using services so I'll update this when I know more. In the meantime be mindful that this is an option but you'll have to set it up yourself.

Tom Moore's answer is correct, however for others like me who are relatively new to ROS I'll restate everything a bit more explicitly with instructions. In this instance I am referring to the frame /odom as created by the robot_localization package, so my explanation relates to that package. The problem and solution may be different if you are using some other part of the navigation stack to track odometry. I'm also assuming that this is a ground based robot with IMU and odometry data.

Problem

You want to know how the frame /odom is initialised and how you can manually re-set it or control it's initialisation.

Cause

The frame /odom is created by an instance of robot_localization when the node is launched. Depending on your launch file you will find that upon launch the /odom frame's origin and/or orientation will match that of the robot (i.e. the origin and orientation of the frame you have set to "base_link_frame" in your launch file - generally /base_link)

However...you may find that the orientation does not match when you want it to or you want to be able to re-set it yourself later. Typically this is because the orientation is matching the non-zero input from your IMU at launch.

Solution

There are three things you can do to set the origin and orientation of /odom:

  1. Initialize /odom to match the origin and orientation of /base_link at launch.
  2. Manually re-set the origin and orientation of /odom by publishing a geometry_msgs/PoseWithCovarianceStamped to the /set_pose topic.
  3. Use the SetPose service to set the origin and orientation.

(There may be more options that I don't know about yet so feel free to correct me)

Setting /odom at launch

This is as simple as setting a single parameter in the launch file for your robot_localization instance that is creating /odom. Find your launch file and add the line:

<param name="imu0_relative" value="true"/>

To override the IMU data and match the orientations. The origin of /odom should already match.

Re-setting /odom by publishing to /set_pose

At any time you can publish a geometry_msgs/PoseWithCovarianceStamped message to the /set_pose topic. The topic likely won't appear using rostopic list until you publish to it. Type this into a terminal:

rostopic pub /set_pose geometry_msgs/PoseWithCovarianceStamped header: {stamp: now, frame_id: "odom"}, pose: {pose: {position: {x: 1.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} }, covariance: [1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}'

And replace the x,y,z,w values with whatever you want to want to set /odom to. Note that the code above will set the new pose relative to the old pose.

Use the SetPose service

I'm pretty unfamiliar with using services so I'll update this when I know more. In the meantime be mindful that this is an option but you'll have to set it up yourself.

Type the following into terminal:

rosservice call /set_pose <tab>

And fill out the pose and orientation information the same as you would if you were publishing to the /set_pose topic (as described above).

Tom Moore's answer is correct, however for others like me who are relatively new to ROS I'll restate everything a bit more explicitly with instructions. In this instance I am referring to the frame /odom as created by an instance of ekf_localization from the robot_localization package, so my explanation relates to that package. The problem and solution may be different if you are using some other part of the navigation stack to track odometry. I'm also assuming that this is a ground based robot with IMU and odometry data.

Problem

You want to know how the frame /odom is initialised initialized and how you can manually re-set it or control it's initialisation.initialization.

Cause

In short: The origin of /odom initializes to the current position of the robot. The orientation of /odom initializes to whatever your IMU thinks is magnetic North (the heading at which your IMU reads 0.0).

In full: The frame /odom is created by an instance of robot_localizationekf_localization when the node is launched. Depending on By default, the origin of /odom is set equal to the origin of /base_link - i.e. the current position of your launch file you robot. The ekf_localization node requires an IMU data stream as an input (default source is /imu/data). This data stream dictates the orientation of /odom. When ekf_localization is launched it will find that upon launch the /odom frame's origin and/or read the IMU data and set the orientation will match that of the robot (i.e. the origin and orientation of the frame you have set to "base_link_frame" in your launch file - generally /base_link)

However...you may find that the orientation does not match when you want it to or you want to be able to re-set it yourself later. Typically this is because the orientation is matching the non-zero input from of /odom to whatever heading your IMU at launch.will read 0.0 at. If your IMU data is earth-referenced, it will (typically) read 0.0 when pointing to magnetic North. So, your /odom frame will initialize with its orientation pointing to magnetic North.

However, you may want to re-set /odom or otherwise control its pose...

Solution

There are three things you can do to set the origin and orientation of /odom:

  1. Initialize /odom to match the origin and orientation of /base_link at launch.
  2. Manually re-set the origin and orientation of /odom by publishing a geometry_msgs/PoseWithCovarianceStamped to the /set_pose topic.
  3. Use the SetPose service to set the origin and orientation.

(There may be more options that I don't know about yet so feel free to correct me)

Setting /odom at launch

This is as simple as setting a single parameter in the launch file for your robot_localization instance that is creating /odom. Find your launch file and add the line:

<param name="imu0_relative" value="true"/>

To override the IMU data and match the orientations. The origin of /odom should already match.

Re-setting /odom by publishing to /set_pose

At any time you can publish a geometry_msgs/PoseWithCovarianceStamped message to the /set_pose topic. The topic likely won't appear using rostopic list until you publish to it. Type this into a terminal:

rostopic pub /set_pose geometry_msgs/PoseWithCovarianceStamped header: {stamp: now, frame_id: "odom"}, pose: {pose: {position: {x: 1.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} }, covariance: [1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}'

And replace the x,y,z,w values with whatever you want to want to set /odom to. Note that the code above will set the new pose relative to the old pose.

Use the SetPose service

Type the following into terminal:

rosservice call /set_pose <tab>

And fill out the pose and orientation information the same as you would if you were publishing to the /set_pose topic (as described above).

Tom Moore's answer is correct, however for others like me who are relatively new to ROS I'll restate everything a bit more explicitly with instructions. In this instance I am referring to the frame /odom as created by an instance of ekf_localization from the robot_localization package, so my explanation relates to that package. The problem and solution may be different if you are using some other part of the navigation stack to track odometry. I'm also assuming that this is a ground based robot with IMU and odometry data.

Problem

You want to know how the frame /odom is initialized and how you can manually re-set it or control it's initialization.

Cause

In short: The origin of /odom initializes to the current position of the robot. The orientation of /odom initializes to whatever your IMU thinks is magnetic North (the heading at which your IMU reads 0.0).

In full: The frame /odom is created by an instance of ekf_localization when the node is launched. By default, the origin of /odom is set equal to the origin of /base_link - i.e. the current position of your robot. The ekf_localization node requires an IMU data stream as an input (default source is /imu/data). This data stream dictates the orientation of /odom. When ekf_localization is launched it will read the IMU data and set the orientation of /odom to whatever heading your IMU will read 0.0 at. If your IMU data is earth-referenced, it will (typically) read 0.0 when pointing to magnetic North. So, your /odom frame will initialize with its orientation pointing to magnetic North.

However, you may want to re-set /odom or otherwise control its pose...

Solution

There are three things you can do to set the origin and orientation of /odom:

  1. Initialize /odom to match the origin and orientation of /base_link at launch.
  2. Manually re-set the origin and orientation of /odom by publishing a geometry_msgs/PoseWithCovarianceStamped to the /set_pose topic.
  3. Use the SetPose service to set the origin and orientation.

(There may be more options that I don't know about yet so feel free to correct me)

Setting /odom at launch

This is as simple as setting a single parameter in the launch file for your robot_localization instance that is creating /odom. Find your launch file and add the line:

<param name="imu0_relative" value="true"/>

To override the IMU data and match the orientations. The origin of /odom should already match.

Re-setting /odom by publishing to /set_pose

At any time you can publish a geometry_msgs/PoseWithCovarianceStamped message to the /set_pose topic. The topic likely won't appear using rostopic list until you publish to it. Type this into a terminal:

rostopic pub /set_pose geometry_msgs/PoseWithCovarianceStamped header: {stamp: now, frame_id: "odom"}, pose: {pose: {position: {x: 1.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} }, covariance: [1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}'
[1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}

And replace the x,y,z,w values with whatever you want to want to set /odom to. Note that the code above will set the new pose relative to the old pose.

Use the SetPose service

Type the following into terminal:

rosservice call /set_pose <tab>

And fill out the pose and orientation information the same as you would if you were publishing to the /set_pose topic (as described above).

Tom Moore's answer is correct, however for others like me who are relatively new to ROS I'll restate everything a bit more explicitly with instructions. In this instance I am referring to the frame /odom as created by an instance of ekf_localization from the robot_localization package, so my explanation relates to that package. The problem and solution may be different if you are using some other part of the navigation stack to track odometry. I'm also assuming that this is a ground based robot with IMU and odometry data.

Problem

You want to know how the frame /odom is initialized and how you can manually re-set it or control it's initialization.

Cause

In short: The origin of /odom initializes to the current position of the robot. The orientation of /odom initializes to whatever your IMU thinks is magnetic North (the heading at which your IMU reads 0.0).

In full: The frame /odom is created by an instance of ekf_localization when the node is launched. By default, the origin of /odom is set equal to the origin of /base_link - i.e. the current position of your robot. The ekf_localization node requires an IMU data stream as an input (default source is /imu/data). This data stream dictates the orientation of /odom. When ekf_localization is launched it will read the IMU data and set the orientation of /odom to whatever heading your IMU will read 0.0 at. If your IMU data is earth-referenced, it will (typically) read 0.0 when pointing to magnetic North. So, your /odom frame will initialize with its orientation pointing to magnetic North.

However, you may want to re-set /odom or otherwise control its pose...

Solution

There are three things you can do to set the origin and orientation of /odom:

  1. Initialize /odom to match the origin and orientation of /base_link at launch.
  2. Manually re-set the origin and orientation of /odom by publishing a geometry_msgs/PoseWithCovarianceStamped to the /set_pose topic.
  3. Use the SetPose service to set the origin and orientation.

(There may be more options that I don't know about yet so feel free to correct me)

Setting /odom at launch

This is as simple as setting a single parameter in the launch file for your robot_localization instance that is creating /odom. Find your launch file and add the line:

<param name="imu0_relative" value="true"/>

To override the IMU data and match the orientations. The origin of /odom should already match.

Re-setting /odom by publishing to /set_pose

At any time you can publish a geometry_msgs/PoseWithCovarianceStamped message to the /set_pose topic. The topic likely won't appear using rostopic list until you publish to it. Type this into a terminal:

rostopic pub /set_pose geometry_msgs/PoseWithCovarianceStamped header: '{header: {stamp: now, frame_id: "odom"}, pose: {pose: {position: {x: 1.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} }, covariance: [1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}
[1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}'

And replace the x,y,z,w values with whatever you want to want to set /odom to. Note that the code above will set the new pose relative to the old pose.

Use the SetPose service

Type the following into terminal:

rosservice call /set_pose <tab>

And fill out the pose and orientation information the same as you would if you were publishing to the /set_pose topic (as described above).

Tom Moore's answer is correct, however for others like me who are relatively new to ROS I'll restate everything a bit more explicitly with instructions. In this instance I am referring to the frame /odom as created by an instance of ekf_localization from the robot_localization package, so my explanation relates to that package. The problem and solution may be different if you are using some other part of the navigation stack to track odometry. I'm also assuming that this is a ground based robot with IMU and odometry data.

Problem

You want to know how the frame /odom is initialized and how you can manually re-set it or control it's initialization.

Cause

In short: The origin of /odom initializes to the current position of the robot. The orientation of /odom initializes to whatever your IMU thinks is magnetic North (the heading at which your IMU reads 0.0).

In full: The frame /odom is created by an instance of ekf_localization when the node is launched. By default, the origin of /odom is set equal to the origin of /base_link - i.e. the current position of your robot. The ekf_localization node requires an IMU data stream as an input (default source is /imu/data). This data stream dictates the orientation of /odom. When ekf_localization is launched it will read the IMU data and set the orientation of /odom to whatever heading your IMU will read 0.0 at. If your IMU data is earth-referenced, it will (typically) read 0.0 when pointing to magnetic North. So, your /odom frame will initialize with its orientation pointing to magnetic North.

However, you may want to re-set /odom or otherwise control its pose...

Solution

There are three things you can do to set the origin and orientation of /odom:

  1. Initialize /odom to match the origin and orientation of /base_link at launch.
  2. Manually re-set the origin and orientation of /odom by publishing a geometry_msgs/PoseWithCovarianceStamped to the /set_pose topic.
  3. Use the SetPose service to set the origin and orientation.

(There may be more options that I don't know about yet so feel free to correct me)

Setting /odom at launch

This is as simple as setting a single parameter in the launch file for your robot_localization instance that is creating /odom. Find your launch file and add the line:

<param name="imu0_relative" value="true"/>

To override the IMU data and match the orientations. The origin of /odom should already match.

Re-setting /odom by publishing to /set_pose

At any time you can publish a geometry_msgs/PoseWithCovarianceStamped message to the /set_pose topic. The topic likely won't appear using rostopic list until you publish to it. Type this into a terminal:

rostopic pub /set_pose geometry_msgs/PoseWithCovarianceStamped '{header: {stamp: now, frame_id: "odom"}, pose: {pose: {position: {x: 1.0, y: 1.0, z: 0.0}, orientation: {w: 1.0} }, covariance: [1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,1]}}'

And replace the x,y,z,w values with whatever you want to want to set the origin and orientation of /odom to. Note that the code above what you are technically doing is re-setting the odometry of your robot in the /odom frame, rather than the origin of the frame itself. So for example if you re-set the frame to X,Y = 2,3 the origin of /base_link (i.e. the body of your robot) will set the new pose relative to the old pose.move to X,Y = 2,3 in the /odom frame. This is more intuitive to think about if your robot has already moved around in the real world, and you want to re-set to /odom frame to wherever your robot currently is. Setting /odom X,Y,Z = 0,0,0 will make the /odom frame move back to your robot and zero the odometry.

Use the SetPose service

Type the following into terminal:

rosservice call /set_pose <tab>

And fill out the pose and orientation information the same as you would if you were publishing to the /set_pose topic (as described above).