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

Revision history [back]

From the first question: "...the origin of my /map and /odom frames move relative to each other"

They will. The only way in which this would not happen would be if your odometry-frame state matched your map-frame state perfectly, which it clearly won't.

From the update:

  1. (No response)

  2. "The various EKF and navsat nodes are VERY picky about how they are launched. If you run the ekf_and_gps_localisation.launch file I always get this error:"

    That may just be because the transform isn't available for a single time step. Does it keep printing it, or does it print it once and then start functioning?

  3. Something is going wrong with navsat_transform when I try to set the datum. I've tried changing the magnetic declination, yaw offset, datum heading... nothing affects the orientation of /map

    I'll play back your bag data using your launch files and see what's going on. Also, I don't quite understand what you mean by "map always points to magnetic north." You appear to be setting a datum with a heading of zero. This is equivalent to not using any datum, and starting navsat_transform_node at the specified lat/long, and with your IMU reading 0 at that position. If your IMU reads 0 at magnetic north, then when you set the datum with a yaw of 0, you are implicitly pretending that you're starting your robot at that lat/long and facing magnetic north.

  4. I think you may be misunderstanding how rviz works. The "Fixed Frame" specifies in what frame you want to view the data, so all poses will be transformed into that frame. If the map and odom frame data are right on top of each other, that means the map->odom transform is working correctly, even if the poses themselves are not actually the same.

  5. When you use the parameters in the launch file, it just calls the service anyway:

    https://github.com/cra-ros-pkg/robot_localization/blob/kinetic-devel/src/navsat_transform.cpp#L155

    The only variable that you haven't shown here is what your robot's pose is when you first start the node. If the robot's heading is even fractionally different between those runs, then when we compute the transform from map->utm, it won't be the same. The UTM coordinates are on the order of tens of thousands of meters, so small variations will make a difference.

From the first question: "...the origin of my /map and /odom frames move relative to each other"

They will. The only way in which this would not happen would be if your odometry-frame state matched your map-frame state perfectly, which it clearly won't.

From the update:

  1. (No response)

  2. "The various EKF and navsat nodes are VERY picky about how they are launched. If you run the ekf_and_gps_localisation.launch file I always get this error:"

    That may just be because the transform isn't available for a single time step. Does it keep printing it, or does it print it once and then start functioning?

  3. Something is going wrong with navsat_transform when I try to set the datum. I've tried changing the magnetic declination, yaw offset, datum heading... nothing affects the orientation of /map

    I'll play back your bag data using your launch files and see what's going on. Also, I don't quite understand what you mean by "map always points to magnetic north." You appear to be setting a datum with a heading of zero. This is equivalent to not using any datum, and starting navsat_transform_node at the specified lat/long, and with your IMU reading 0 at that position. If your IMU reads 0 at magnetic north, then when you set the datum with a yaw of 0, you are implicitly pretending that you're starting your robot at that lat/long and facing magnetic north.

  4. I think you may be misunderstanding how rviz works. The "Fixed Frame" specifies in what frame you want to view the data, so all poses will be transformed into that frame. If the map and odom frame data are right on top of each other, that means the map->odom transform is working correctly, even if the poses themselves are not actually the same.

  5. When you use the parameters in the launch file, it just calls the service anyway:

    https://github.com/cra-ros-pkg/robot_localization/blob/kinetic-devel/src/navsat_transform.cpp#L155

    The only variable that you haven't shown here is what your robot's pose is when you first start the node. If the robot's heading is even fractionally different between those runs, then when we compute the transform from map->utm, it won't be the same. The UTM coordinates are on the order of tens of thousands of meters, so small variations will make a difference.

EDIT 1 in response to update/comments:

My understanding, based on the GPS Integration Tutorial is that I can use the datum parameter to set the origin of /map and that the heading sub-parameter dictates the heading of /map from True North (irrespective of the current or initial pose of the robot). So, according to the tutorial and REP-103, heading of 0.0 will result in the 'Y' axis of /map facing True North and the 'X' axis of /map facing True East.

If you use the datum parameter or service, the map frame should always be getting aligned such that the X axis is "true east" and the Y axis is true north. From the wiki:

When this mode is used, the robot assumes that your robot's world frame origin is at the specified latitude and longitude and with a heading of 0 (east).

I'll have to see what the effect of using yaw_offset with the datum is when I get a chance to play back your bag files.

As it turns out, the setting the datum in the launch file ends up calling rosservice anyway. So regardless of when it is set, the same method is used which means the only thing that's different between each call is the timing.

It's not just timing. It's also that your robot's pose as estimated by the EKF (which is also being fed into navsat_transform_node) may have shifted ever so slightly, particularly in yaw. navsat_transform_node also takes into account your pose coming out of the EKF before it generates the world_frame->utm transform.

Re: the issue with transforms it looks like it's missing a base_link->imu_link transform in the EKF. What is providing that transform in your case?

Let's try this: if you can, take your robot outside and drive it in a straight line towards "true" north for as long as possible (say, 100 meters). Bag the data, then turn around do go directly south for the same distance, recording a second bag. Post that bag. Also, I'm assuming the launch files you posted will be the ones you use for this experiment.

From the first question: "...the origin of my /map and /odom frames move relative to each other"

They will. The only way in which this would not happen would be if your odometry-frame state matched your map-frame state perfectly, which it clearly won't.

From the update:

  1. (No response)

  2. "The various EKF and navsat nodes are VERY picky about how they are launched. If you run the ekf_and_gps_localisation.launch file I always get this error:"

    That may just be because the transform isn't available for a single time step. Does it keep printing it, or does it print it once and then start functioning?

  3. Something is going wrong with navsat_transform when I try to set the datum. I've tried changing the magnetic declination, yaw offset, datum heading... nothing affects the orientation of /map

    I'll play back your bag data using your launch files and see what's going on. Also, I don't quite understand what you mean by "map always points to magnetic north." You appear to be setting a datum with a heading of zero. This is equivalent to not using any datum, and starting navsat_transform_node at the specified lat/long, and with your IMU reading 0 at that position. If your IMU reads 0 at magnetic north, then when you set the datum with a yaw of 0, you are implicitly pretending that you're starting your robot at that lat/long and facing magnetic north.

  4. I think you may be misunderstanding how rviz works. The "Fixed Frame" specifies in what frame you want to view the data, so all poses will be transformed into that frame. If the map and odom frame data are right on top of each other, that means the map->odom transform is working correctly, even if the poses themselves are not actually the same.

  5. When you use the parameters in the launch file, it just calls the service anyway:

    https://github.com/cra-ros-pkg/robot_localization/blob/kinetic-devel/src/navsat_transform.cpp#L155

    The only variable that you haven't shown here is what your robot's pose is when you first start the node. If the robot's heading is even fractionally different between those runs, then when we compute the transform from map->utm, it won't be the same. The UTM coordinates are on the order of tens of thousands of meters, so small variations will make a difference.

EDIT 1 in response to update/comments:

My understanding, based on the GPS Integration Tutorial is that I can use the datum parameter to set the origin of /map and that the heading sub-parameter dictates the heading of /map from True North (irrespective of the current or initial pose of the robot). So, according to the tutorial and REP-103, heading of 0.0 will result in the 'Y' axis of /map facing True North and the 'X' axis of /map facing True East.

If you In which part of the tutorial does it claim that the datum heading is an offset from true north? I'll fix that for clarity. Imagine you have a robot at a coordinate of (55.949789, -3.253136) with a heading of 0.56 radians. You then start navsat_transform_node and let it use the datum parameter or service, the map frame should IMU's current heading to dictate the transform from alwaysmap be getting aligned such that the X axis is "true east" and the Y axis is true north. From the wiki:

When this mode is used, the robot assumes that your robot's world frame origin is at the specified latitude and longitude and with a heading of 0 (east).

I'll have to see what the effect of using yaw_offset with ->utm. That is the equivalent of the datum is when I get a chance to play back your bag files.parameter.

As it turns out, the setting the datum in the launch file ends up calling rosservice anyway. So regardless of when it is set, the same method is used which means the only thing that's different between each call is the timing.

It's not just timing. It's also that your robot's pose as estimated by the EKF (which is also being fed into navsat_transform_node) may have shifted ever so slightly, particularly in yaw. navsat_transform_node also takes into account your pose coming out of the EKF before it generates the world_frame->utm transform.

Re: the issue with transforms it looks like it's missing a base_link->imu_link transform in the EKF. What is providing that transform in your case?

Let's try this: if you can, take your robot outside and drive it in a straight line towards "true" north for as long as possible (say, 100 meters). Bag the data, then turn around do go directly south for the same distance, recording a second bag. Post that bag. Also, I'm assuming the launch files you posted will be the ones you use for this experiment.

From the first question: "...the origin of my /map and /odom frames move relative to each other"

They will. The only way in which this would not happen would be if your odometry-frame state matched your map-frame state perfectly, which it clearly won't.

From the update:

  1. (No response)

  2. "The various EKF and navsat nodes are VERY picky about how they are launched. If you run the ekf_and_gps_localisation.launch file I always get this error:"

    That may just be because the transform isn't available for a single time step. Does it keep printing it, or does it print it once and then start functioning?

  3. Something is going wrong with navsat_transform when I try to set the datum. I've tried changing the magnetic declination, yaw offset, datum heading... nothing affects the orientation of /map

    I'll play back your bag data using your launch files and see what's going on. Also, I don't quite understand what you mean by "map always points to magnetic north." You appear to be setting a datum with a heading of zero. This is equivalent to not using any datum, and starting navsat_transform_node at the specified lat/long, and with your IMU reading 0 at that position. If your IMU reads 0 at magnetic north, then when you set the datum with a yaw of 0, you are implicitly pretending that you're starting your robot at that lat/long and facing magnetic north.

  4. I think you may be misunderstanding how rviz works. The "Fixed Frame" specifies in what frame you want to view the data, so all poses will be transformed into that frame. If the map and odom frame data are right on top of each other, that means the map->odom transform is working correctly, even if the poses themselves are not actually the same.

  5. When you use the parameters in the launch file, it just calls the service anyway:

    https://github.com/cra-ros-pkg/robot_localization/blob/kinetic-devel/src/navsat_transform.cpp#L155

    The only variable that you haven't shown here is what your robot's pose is when you first start the node. If the robot's heading is even fractionally different between those runs, then when we compute the transform from map->utm, it won't be the same. The UTM coordinates are on the order of tens of thousands of meters, so small variations will make a difference.

EDIT 1 in response to update/comments:

My understanding, based on the GPS Integration Tutorial is that I can use the datum parameter to set the origin of /map and that the heading sub-parameter dictates the heading of /map from True North (irrespective of the current or initial pose of the robot). So, according to the tutorial and REP-103, heading of 0.0 will result in the 'Y' axis of /map facing True North and the 'X' axis of /map facing True East.

In which part of the tutorial does it claim that the datum heading is an offset from true north? I'll fix that for clarity. Imagine you have a robot at a coordinate of (55.949789, -3.253136) with a heading of 0.56 radians. You then start navsat_transform_node and let it use the IMU's current heading to dictate the transform from map->utm. That is the equivalent of the datum parameter.

As it turns out, the setting the datum in the launch file ends up calling rosservice anyway. So regardless of when it is set, the same method is used which means the only thing that's different between each call is the timing.

It's not just timing. It's also that your robot's pose as estimated by the EKF (which is also being fed into navsat_transform_node) may have shifted ever so slightly, particularly in yaw. navsat_transform_node also takes into account your pose coming out of the EKF before it generates the world_frame->utm transform.

Re: the issue with transforms it looks like it's missing a base_link->imu_link transform in the EKF. What is providing that transform in your case?

Let's try this: if you can, take your robot outside and drive it in a straight line towards "true" north for as long as possible (say, 100 meters). Bag the data, then turn around do go directly south for the same distance, recording a second bag. Post that bag. Also, I'm assuming the launch files you posted will be the ones you use for this experiment.

EDIT 2 in response to further updates/comments:

Matt and I are going to work out the issues offline, but one quick note about the map frame: the orientation of the map frame is by no means dictated or affected by navsat_transform_node (at least, not yet). The map frame, like the odom frame, assumes that your robot starts with a position of (0, 0) and with a heading of 0. Whatever orientation data is received by the map instance of the EKF is what really dictates the orientation of that frame. If your first IMU message says you have a heading of 0.24 radians and you are fusing that yaw data into your EKF, then the orientation of your frame is dictated by whatever the zero point of your IMU is. If your IMU reads 0 at magnetic north, then your map frame will be aligned with magnetic north.

All navsat_transform_node is doing is looking at the current pose (position and orientation) in the odometry message that it is fed, and using that to determine how to transform future GPS measurements so that they are consistent with the world frame (in this case, map). That way, if you drive 10 meters forward, then no matter which way your robot was facing when it started, the output of navsat_transform_node will show that you drove 10 meters forward at that same heading. It's just letting you fuse GPS data with your local world frame.