How to use tf2 in ros1 to calculate dead reackoning

asked 2023-02-17 11:41:22 -0500

Darkproduct gravatar image

updated 2023-02-19 07:24:09 -0500

PS: The twist of the robot has 3 degrees of freedom. lin.x, lin.y and ang.z

// given
// - from sensor data calculated "twist" [geometry_msgs::Twist] 
// - time step "dt" [ros::Duration]
// - time of new sensor data used "t" [ros::Time]
// - heading "yaw" [double]
// - last odom value "last_odom_msg" [nav_msgs::Odometry]

// create odom
nav_msgs::Odometry odom = last_odom_msg;
odom.header.stamp = t;

odom.twist.twist = twist;

// calculate and set new pose
// oldpose += dt * transform_to_odom(yaw, twist) ???

How do I calculate the last line using tf2 with the given values? The API is a bit confusing, because nothing works with the "native" geometry_msgs types. This is as far as i got:

// not sure if this is the right type
tf2::Transform twist;
tf2::fromMsg(odom.twist.twist, twist);

// get orientation as quaternion
tf2::Quaternion orientation(yaw, 0, 0);

// get last position
tf2::Vector3 position;
tf2::fromMsg(last_odom_msg.pose.pose.position, position);

// TODO: transform twist into odom frame
// TODO: add dt * twist to the current position and orientation

Without tf2 it should look something like this, I think:

auto syaw = sin(yaw);
auto cyaw = cos(yaw);
odom.pose.pose = last_odom_msg.pose.pose;
odom.pose.pose.position.x += dt.toSec() * (cyaw * odom.twist.twist.linear.x +
                                            syaw * odom.twist.twist.linear.y);
odom.pose.pose.position.y += dt.toSec() * (syaw * odom.twist.twist.linear.x +
                                            cyaw * odom.twist.twist.linear.y);

odom.pose.pose.orientation = tf2::toMsg(tf2::Quaternion(yaw, 0, 0));
edit retag flag offensive close merge delete