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

How to convert x and y velocities to linear.x and angular.z?

asked 2020-10-06 03:20:51 -0500

kjn gravatar image

Hi, I'm trying to control the turtlesim using computed accelerations in the x and y direction.

However, since we are publishing to geometry_msgs/Twist, I can't figure out how to make this work. My initial thought was that I could ignore the angular velocity, and just change and publish the linear.x and linear.y components of the twist message. However, although the x component works how I expect it to, the turtlesim does not move up and down.

This makes me think I need to somehow convert the x and y accelerations into linear.x and angular.z components.

Having set rate = rospy.Rate(30) and using rate.sleep() within my while loop, I know that each time step will be approximately delta_t = (1/30) seconds.

There I calculated the change in x and y components of velocity at each time step by multiplying the components of acceleration, and adding it to the x and y components of the original velocity (obtained by subscribing to the pose of the /turtle1/, taking the angle theta and multiplying linear.x with either sin(theta) or cos(theta))

However, from here, I am completely stuck. I'm thinking I'd need to find a change in angle after the timestep derived from the direction of the new velocity vector, and dividing that change in angle by delta_t to get the rate of change, and set angular.z to that value, but my first attempt at that failed.

This was a convoluted way to say that I'm not really sure how to control the turtlesim using geometry_msgs/Twist. Thank you for the help.

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
0

answered 2023-04-19 06:07:38 -0500

Al53 gravatar image

I understand your confusion. The turtlesim node simulates a simple, non-holonomic 2D robot, which means that it can only move forward and rotate, but not move up and down (in the Y direction). The geometry_msgs/Twist message is used to control the robot's linear and angular velocities. However, since turtlesim cannot move in the Y direction, it ignores the linear.y component of the Twist message.

To control the turtlesim based on computed accelerations in the X and Y direction, you will need to first compute the desired linear velocity and angular velocity from the accelerations. Given that you have already calculated the change in the X and Y components of velocity at each time step, you can now find the magnitude and direction of the new velocity vector.

Here's a general outline of what you can do:

Subscribe to the turtlesim's pose from the /turtle1/pose topic. Calculate the X and Y components of the current velocity based on the current linear.x and the heading angle (theta) from the pose. Update the X and Y components of the velocity based on the computed accelerations and time step (delta_t). Compute the magnitude of the new velocity vector and set linear.x to that value. Compute the direction of the new velocity vector (using atan2) and find the difference between the new direction and the current heading angle (theta). This will give you the change in angle. Divide the change in angle by delta_t to get the angular velocity and set angular.z to that value. Publish the updated Twist message to the /turtle1/cmd_vel topic. Here's some example code to help you get started:

#!/usr/bin/env python3
import rospy
from geometry_msgs.msg import Twist
from turtlesim.msg import Pose
import math

def pose_callback(pose):
    global current_pose
    current_pose = pose

rospy.init_node('turtlesim_control', anonymous=True)
velocity_publisher = rospy.Publisher('/turtle1/cmd_vel', Twist, queue_size=10)
pose_subscriber = rospy.Subscriber('/turtle1/pose', Pose, pose_callback)

current_pose = Pose()
rate = rospy.Rate(30)
delta_t = 1.0 / 30

while not rospy.is_shutdown():
    # Compute the X and Y components of the current velocity
    current_velocity_x = current_pose.linear_velocity * math.cos(current_pose.theta)
    current_velocity_y = current_pose.linear_velocity * math.sin(current_pose.theta)

    # Update the X and Y components of the velocity based on the computed accelerations and delta_t
    acceleration_x = # Calculate the x acceleration based on your logic
    acceleration_y = # Calculate the y acceleration based on your logic
    new_velocity_x = current_velocity_x + acceleration_x * delta_t
    new_velocity_y = current_velocity_y + acceleration_y * delta_t

    # Compute the magnitude of the new velocity vector
    new_linear_x = math.sqrt(new_velocity_x**2 + new_velocity_y**2)

    # Compute the direction of the new velocity vector and find the change in angle
    new_direction = math.atan2(new_velocity_y, new_velocity_x)
    delta_angle = new_direction - current_pose.theta

    # Calculate the angular velocity
    new_angular_z = delta_angle / delta_t

    # Publish the updated Twist message
    twist = Twist()
    twist.linear.x = new_linear_x
    twist.angular.z = new_angular_z
    velocity_publisher.publish(twist)

    rate.sleep()

Remember to replace the # Calculate the x acceleration based on your logic and # Calculate the y acceleration based on your logic lines with your specific acceleration calculations.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2020-10-06 03:19:13 -0500

Seen: 848 times

Last updated: Apr 19 '23