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

Revision history [back]

A few things:

  1. No output at all only occurs when it's not receiving sensor data or it can't transform the data into the target frame. Do rostopic info on all your topics to make sure that they are being published and subscribed to.
  2. Velocities should ideally be reported in the frame of the vehicle (base_link), but if they're not, the package will transform them into base_link anyway before fusing them with the state estimate. In this case, I'm guessing that it's attempting to transform your velocity message from odom->base_link, but can't, as it the node that produces that transform is ekf_localization_node itself. It's a chicken-or-egg problem.
  3. However, the odom->base_link transform should be getting generated if any one of the sensors is being successfully fused, so check (1) again, and perhaps post examples of your other sensor messages?

A few things:

  1. No output at all only occurs when it's not receiving sensor data or it can't transform the data into the target frame. Do rostopic info on all your topics to make sure that they are being published and subscribed to.
  2. Velocities should ideally be reported in the frame of the vehicle (base_link), but if they're not, the package will transform them into base_link anyway before fusing them with the state estimate. In this case, I'm guessing that it's attempting to transform your velocity message from odom->base_link, but can't, as it the node that produces that transform is ekf_localization_node itself. It's a chicken-or-egg problem.
  3. However, the odom->base_link transform should be getting generated if any one of the sensors is being successfully fused, so check (1) again, and perhaps post examples of your other sensor messages?

A few things:

  1. No output at all only occurs when it's not receiving sensor data or it can't transform the data into the target frame. Do rostopic info on all your topics to make sure that they are being published and subscribed to.
  2. Velocities should ideally be reported in the frame of the vehicle (base_link), but if they're not, the package will transform them into base_link anyway before fusing them with the state estimate. In this case, I'm guessing that it's attempting to transform your velocity message from odom->base_link, but can't, as the node that produces that transform is ekf_localization_node itself. It's a chicken-or-egg problem.
  3. However, the odom->base_link transform should be getting generated if any one of the sensors is being successfully fused, so check (1) again, and perhaps post examples of your other sensor messages?

EDIT: Also, turn debug mode off unless you want to eat up disk space in a hurry. If you want to run your node for a few seconds with all of the sensor data coming in and then send me that log, that will help, but in general, don't run with that on.

A few things:

  1. No output at all only occurs when it's not receiving sensor data or it can't transform the data into the target frame. Do rostopic info on all your topics to make sure that they are being published and subscribed to.
  2. Velocities should ideally be reported in the frame of the vehicle (base_link), but if they're not, the package will transform them into base_link anyway before fusing them with the state estimate. In this case, I'm guessing that it's attempting to transform your velocity message from odom->base_link, but can't, as the node that produces that transform is ekf_localization_node itself. It's a chicken-or-egg problem.
  3. However, the odom->base_link transform should be getting generated if any one of the sensors is being successfully fused, so check (1) again, and perhaps post examples of your other sensor messages?

EDIT: Also, turn debug mode off unless you want to eat up disk space in a hurry. If you want to run your node for a few seconds with all of the sensor data coming in and then send me that log, that will help, but in general, don't run with that on.

EDIT in response to update. Forgive me if I go over anything you already know. I just want to make sure we're on the same page.

Q1: Let me back up a bit. First, in your system, we actually have three separate coordinate frames (at least with regard to this question, you probably have more):

  1. odom
  2. base_link
  3. imu (which is equivalent to the ENU frame)

Just so we're clear, both your IMU's velocity message frame_id (as reported in xsens/velocity) and its orientation frame_id (as reported in imu/data) are now reported in the imu (i.e., ENU) frame, correct?

Assuming this is true, let's consider the velocity first. If your robot heads directly east, your IMU velocity sensor reads only +X velocity, and if it drives straight north, you get only +Y, correct?

Assuming I'm still correct, then what you need is a transform from base_link->imu, which you said you have. Question: how did you generate this transform? It can't be static, as it will constantly change depending on the heading of the robot. For example, if you drive northeast, in the imu (ENU) frame, you'd get equal values for X and Y velocity. However, in base_link, you'd only have +X velocity. Now if you turned around and drove southwest, you'd have -X and -Y velocity in the imu frame, but would still have +X velocity in the base_link frame. Essentially, your base_link->imu transform would always have to contain the vehicle's current heading. It may be easier to edit your velocity node so that it automatically applies this transform internally before publishing, and then you can just publish the velocity with the base_link frame_id.

Before I respond to your issue regarding the differential setting, let me make sure we're on the same page with the odom frame. When you first start your robot, the odom frame is automatically aligned with your starting position and orientation. If you're facing northeast, then your robot still believes it's at (0, 0) with a heading of 0 (simplifying to 2D for illustration). This obviously is not the same as the ENU frame, which always has the same orientation. So at the starting point, your odom frame heading is 0, but your imu (ENU) frame heading is, say, pi/4. Again, you have a couple options here. First, if you didn't create a base_link->imu transform, you could now create an odom->imu transform (SEE NOTE AT THE END OF THIS UPDATE). In our example, you would transform a new IMU heading by -pi/4 to get the odom frame heading. That transform would be static, but you'd have to set it programmatically when you first start running. A second (and much easier) option is to simply turn the differential setting on. This will effectively treat the initial orientation as a "zero point" for all future measurements, so your first measurement has a heading of pi/4, but that becomes 0, and future measurements would be relative to it. The differential behavior is a bit more complicated than that, but for this question, that's all that's relevant.

To summarize: I would edit the IMU velocity generation node to output velocities in the base_link frame. I would then turn on the differential setting for your IMU so that the orientation starts out at zero. Feel free to upload a bag and I'll check it out at some point.

Q2: That seems reasonable, sure. That's really a tf question. I'm using message filters to ensure that transforms are available for any message I receive.

END OF UPDATE NOTE The statements I made above regarding transforming the IMU data are only partially true. I still need to fix this. Right now, ekf_localization_node always tries to transform IMU data - both angular velocity and orientation - into base_link. I either need to let users specify a target frame for IMU orientation and velocity data, or simply make it so all orientation data gets transformed into odom, and all angular velocity and acceleration data get transformed into base_link.

A few things:

  1. No output at all only occurs when it's not receiving sensor data or it can't transform the data into the target frame. Do rostopic info on all your topics to make sure that they are being published and subscribed to.
  2. Velocities should ideally be reported in the frame of the vehicle (base_link), but if they're not, the package will transform them into base_link anyway before fusing them with the state estimate. In this case, I'm guessing that it's attempting to transform your velocity message from odom->base_link, but can't, as the node that produces that transform is ekf_localization_node itself. It's a chicken-or-egg problem.
  3. However, the odom->base_link transform should be getting generated if any one of the sensors is being successfully fused, so check (1) again, and perhaps post examples of your other sensor messages?

EDIT: Also, turn debug mode off unless you want to eat up disk space in a hurry. If you want to run your node for a few seconds with all of the sensor data coming in and then send me that log, that will help, but in general, don't run with that on.

EDIT in response to update. Forgive me if I go over anything you already know. I just want to make sure we're on the same page.

Q1: Let me back up a bit. First, in your system, we actually have three separate coordinate frames (at least with regard to this question, you probably have more):

  1. odom
  2. base_link
  3. imu (which is equivalent to the ENU frame)

Just so we're clear, both your IMU's velocity message frame_id (as reported in xsens/velocity) and its orientation frame_id (as reported in imu/data) are now reported in the imu (i.e., ENU) frame, correct?

Assuming this is true, let's consider the velocity first. If your robot heads directly east, your IMU velocity sensor reads only +X velocity, and if it drives straight north, you get only +Y, correct?

(Incidentally, this would surprise me. If you're using accelerations, the velocities you generate, unless you transform them, are going to be in the body frame of the IMU, but not in the ENU frame).

Assuming I'm still correct, then what you need is a transform from base_link->imu, which you said you have. Question: how did you generate this transform? It can't be static, as it will constantly change depending on the heading of the robot. For example, if you drive northeast, in the imu (ENU) frame, you'd get equal values for X and Y velocity. However, in base_link, you'd only have +X velocity. Now if you turned around and drove southwest, you'd have -X and -Y velocity in the imu frame, but would still have +X velocity in the base_link frame. Essentially, your base_link->imu transform would always have to contain the vehicle's current heading. It may be easier to edit your velocity node so that it automatically applies this transform internally before publishing, and then you can just publish the velocity with the base_link frame_id.

Before I respond to your issue regarding the differential setting, let me make sure we're on the same page with the odom frame. When you first start your robot, the odom frame is automatically aligned with your starting position and orientation. If you're facing northeast, then your robot still believes it's at (0, 0) with a heading of 0 (simplifying to 2D for illustration). This obviously is not the same as the ENU frame, which always has the same orientation. So at the starting point, your odom frame heading is 0, but your imu (ENU) frame heading is, say, pi/4. Again, you have a couple options here. First, if you didn't create a base_link->imu transform, you could now create an odom->imu transform (SEE NOTE AT THE END OF THIS UPDATE). In our example, you would transform a new IMU heading by -pi/4 to get the odom frame heading. That transform would be static, but you'd have to set it programmatically when you first start running. A second (and much easier) option is to simply turn the differential setting on. This will effectively treat the initial orientation as a "zero point" for all future measurements, so your first measurement has a heading of pi/4, but that becomes 0, and future measurements would be relative to it. The differential behavior is a bit more complicated than that, but for this question, that's all that's relevant.

To summarize: I would edit the IMU velocity generation node to output velocities in the base_link frame. I would then turn on the differential setting for your IMU so that the orientation starts out at zero. Feel free to upload a bag and I'll check it out at some point.

Q2: That seems reasonable, sure. That's really a tf question. I'm using message filters to ensure that transforms are available for any message I receive.

END OF UPDATE NOTE The statements I made above regarding transforming the IMU data are only partially true. I still need to fix this. Right now, ekf_localization_node always tries to transform IMU data - both angular velocity and orientation - into base_link. I either need to let users specify a target frame for IMU orientation and velocity data, or simply make it so all orientation data gets transformed into odom, and all angular velocity and acceleration data get transformed into base_link.

A few things:

  1. No output at all only occurs when it's not receiving sensor data or it can't transform the data into the target frame. Do rostopic info on all your topics to make sure that they are being published and subscribed to.
  2. Velocities should ideally be reported in the frame of the vehicle (base_link), but if they're not, the package will transform them into base_link anyway before fusing them with the state estimate. In this case, I'm guessing that it's attempting to transform your velocity message from odom->base_link, but can't, as the node that produces that transform is ekf_localization_node itself. It's a chicken-or-egg problem.
  3. However, the odom->base_link transform should be getting generated if any one of the sensors is being successfully fused, so check (1) again, and perhaps post examples of your other sensor messages?

EDIT: Also, turn debug mode off unless you want to eat up disk space in a hurry. If you want to run your node for a few seconds with all of the sensor data coming in and then send me that log, that will help, but in general, don't run with that on.

EDIT in response to update. Forgive me if I go over anything you already know. I just want to make sure we're on the same page.

Q1: Let me back up a bit. First, in your system, we actually have three separate coordinate frames (at least with regard to this question, you probably have more):

  1. odom
  2. base_link
  3. imu (which is equivalent to the ENU frame)

Just so we're clear, both your IMU's velocity message frame_id (as reported in xsens/velocity) and its orientation frame_id (as reported in imu/data) are now reported in the imu (i.e., ENU) frame, correct?

Assuming this is true, let's consider the velocity first. If your robot heads directly east, your IMU velocity sensor reads only +X velocity, and if it drives straight north, you get only +Y, correct?

(Incidentally, this would surprise me. If you're using accelerations, the velocities you generate, unless you transform them, are going to be in the body frame of the IMU, but not in the ENU frame).frame. However, the rest of my answer assumes you did mean that the velocities are reported in the ENU frame. Apologies if I misunderstood.)

Assuming I'm still correct, then what you need is a transform from base_link->imu, which you said you have. Question: how did you generate this transform? It can't be static, as it will constantly change depending on the heading of the robot. For example, if you drive northeast, in the imu (ENU) frame, you'd get equal values for X and Y velocity. However, in base_link, you'd only have +X velocity. Now if you turned around and drove southwest, you'd have -X and -Y velocity in the imu frame, but would still have +X velocity in the base_link frame. Essentially, your base_link->imu transform would always have to contain the vehicle's current heading. It may be easier to edit your velocity node so that it automatically applies this transform internally before publishing, and then you can just publish the velocity with the base_link frame_id.

Before I respond to your issue regarding the differential setting, let me make sure we're on the same page with the odom frame. When you first start your robot, the odom frame is automatically aligned with your starting position and orientation. If you're facing northeast, then your robot still believes it's at (0, 0) with a heading of 0 (simplifying to 2D for illustration). This obviously is not the same as the ENU frame, which always has the same orientation. So at the starting point, your odom frame heading is 0, but your imu (ENU) frame heading is, say, pi/4. Again, you have a couple options here. First, if you didn't create a base_link->imu transform, you could now create an odom->imu transform (SEE NOTE AT THE END OF THIS UPDATE). In our example, you would transform a new IMU heading by -pi/4 to get the odom frame heading. That transform would be static, but you'd have to set it programmatically when you first start running. A second (and much easier) option is to simply turn the differential setting on. This will effectively treat the initial orientation as a "zero point" for all future measurements, so your first measurement has a heading of pi/4, but that becomes 0, and future measurements would be relative to it. The differential behavior is a bit more complicated than that, but for this question, that's all that's relevant.

To summarize: I would edit the IMU velocity generation node to output velocities in the base_link frame. I would then turn on the differential setting for your IMU so that the orientation starts out at zero. Feel free to upload a bag and I'll check it out at some point.

Q2: That seems reasonable, sure. That's really a tf question. I'm using message filters to ensure that transforms are available for any message I receive.

END OF UPDATE NOTE The statements I made above regarding transforming the IMU data are only partially true. I still need to fix this. Right now, ekf_localization_node always tries to transform IMU data - both angular velocity and orientation - into base_link. I either need to let users specify a target frame for IMU orientation and velocity data, or simply make it so all orientation data gets transformed into odom, and all angular velocity and acceleration data get transformed into base_link.

A few things:

  1. No output at all only occurs when it's not receiving sensor data or it can't transform the data into the target frame. Do rostopic info on all your topics to make sure that they are being published and subscribed to.
  2. Velocities should ideally be reported in the frame of the vehicle (base_link), but if they're not, the package will transform them into base_link anyway before fusing them with the state estimate. In this case, I'm guessing that it's attempting to transform your velocity message from odom->base_link, but can't, as the node that produces that transform is ekf_localization_node itself. It's a chicken-or-egg problem.
  3. However, the odom->base_link transform should be getting generated if any one of the sensors is being successfully fused, so check (1) again, and perhaps post examples of your other sensor messages?

EDIT: Also, turn debug mode off unless you want to eat up disk space in a hurry. If you want to run your node for a few seconds with all of the sensor data coming in and then send me that log, that will help, but in general, don't run with that on.

EDIT in response to update. Forgive me if I go over anything you already know. I just want to make sure we're on the same page.

Q1: Let me back up a bit. First, in your system, we actually have three separate coordinate frames (at least with regard to this question, you probably have more):

  1. odom
  2. base_link
  3. imu (which is equivalent to the ENU frame)

Just so we're clear, both your IMU's velocity message frame_id (as reported in xsens/velocity) and its orientation frame_id (as reported in imu/data) are now reported in the imu (i.e., ENU) frame, correct?

Assuming this is true, let's consider the velocity first. If your robot heads directly east, your IMU velocity sensor reads only +X velocity, and if it drives straight north, you get only +Y, correct?

(Incidentally, this would surprise me. If you're using accelerations, the velocities you generate, unless you transform them, are going to be in the body frame of the IMU, but not in the ENU frame. However, the rest of my answer assumes you did mean that the velocities are reported in the ENU frame. Apologies if I misunderstood.)

Assuming I'm still correct, then what you need is a transform from base_link->imu, which you said you have. Question: how did you generate this transform? It can't be static, as it will constantly change depending on the heading of the robot. For example, if you drive northeast, in the imu (ENU) frame, you'd get equal values for X and Y velocity. However, in base_link, you'd only have +X velocity. Now if you turned around and drove southwest, you'd have -X and -Y velocity in the imu frame, but would still have +X velocity in the base_link frame. Essentially, your base_link->imu transform would always have to contain the vehicle's current heading. It may be easier to edit your velocity node so that it automatically applies this transform internally before publishing, and then you can just publish the velocity with the base_link frame_id.

Before I respond to your issue regarding the differential setting, let me make sure we're on the same page with the odom frame. When you first start your robot, the odom frame is automatically aligned with your starting position and orientation. If you're facing northeast, then your robot still believes it's at (0, 0) with a heading of 0 (simplifying to 2D for illustration). This obviously is not the same as the ENU frame, which always has the same orientation. So at the starting point, your odom frame heading is 0, but your imu (ENU) frame heading is, say, pi/4. Again, you have a couple options here. First, if you didn't create a base_link->imu transform, you could now create an odom->imu transform (SEE NOTE AT THE END OF THIS UPDATE). In our example, you would transform a new IMU heading by -pi/4 to get the odom frame heading. That transform would be static, but you'd have to set it programmatically when you first start running. A second (and much easier) option is to simply turn the differential setting on. This will effectively treat the initial orientation as a "zero point" for all future measurements, so your first measurement has a heading of pi/4, but that becomes 0, and future measurements would be relative to it. The differential behavior is a bit more complicated than that, but for this question, that's all that's relevant.

To summarize: I would edit the IMU velocity generation node to output velocities in the base_link frame. I would then turn on the differential setting for your IMU so that the orientation starts out at zero. Feel free to upload a bag and I'll check it out at some point.

Q2: That seems reasonable, sure. That's really a tf question. I'm using message filters to ensure that transforms are available for any message I receive.

END OF UPDATE NOTE The statements I made above regarding transforming the IMU data are only partially true. I still need to fix this. Right now, ekf_localization_node always tries to transform IMU data - both angular velocity and orientation - into base_link. I either need to let users specify a target frame for IMU orientation and velocity data, or simply make it so all orientation data gets transformed into odom, and all angular velocity and acceleration data get transformed into base_link.


EDIT: Responding to update that contains Q3:

OK, so your velocities are being reported in the body frame. In this case, what I would do is:

  1. Generate a base_link->imu transform that contains the IMU's orientation and position w.r.t the body frame.
  2. Change your IMU data's frame to be imu.
  3. Enable the differential setting for your IMU.

What you want to avoid (at least in this case; this is not generally true) is to require ekf_localization_node to use the very transform it's meant to be generating (e.g., odom->base_link). Re: the coordinate frame of the IMU orientation data, part of the issue is the IMU message itself. It has only one frame_id specified in the message, but the orientation data is usually reported in a world-fixed frame, and the angular velocity and linear acceleration is usually reported in another (e.g., the base_link frame). ekf_localization_node will try to transform the data into the frames it requires using the frame_id of the IMU message. While it treats orientation and velocity/acceleration data separately, it's still going to use the frame_id in that message as the source frame when it attempts to carry out the transform. So what is the target frame? For orientation data, it ought to be your world_frame (e.g., map or odom), but it can't be if your IMU transform is relative to your base_link frame, as you're back to square one with your issue (the chicken-or-egg problem). For angular velocity and acceleration data, it's the body frame (e.g., base_link). The problem is that we cannot define an odom->imu transform and a base_link->imu transform, as that would be dual-parenting in the tf tree, which would break the tree.

In any case, for you, the differential setting for your IMU ought to fix the orientation issue anyway.