Skip to content

Conversation

@Dwilliestyle
Copy link

@Dwilliestyle Dwilliestyle commented Dec 28, 2025

Fixed TwistStamped compatibility for ROS2 Jazzy

  • Updated turtlebot3_patrol_server.py to use TwistStamped instead of Twist
  • Changed all velocity publishing to use msg.twist.twist.linear.x and msg.twist.twist.angular.z structure
  • This fixes compatibility with turtlebot3_node which expects TwistStamped messages on /cmd_vel in Jazzy

Added joystick teleoperation support

  • Created joystick_teleop.launch.py in turtlebot3_teleop package
  • Enables joystick control for TurtleBot3 robots
  • Updated setup.py to install launch files properly

These changes ensure TurtleBot3 examples work correctly with ROS2 Jazzy.

@gemini-code-assist
Copy link

Summary of Changes

Hello @Dwilliestyle, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the TurtleBot3's control mechanisms by introducing joystick teleoperation capabilities. Concurrently, it updates an existing patrol server script to align with modern ROS 2 practices, specifically by migrating from Twist to TwistStamped messages for velocity commands, ensuring robust and time-aware control within the Jazzy environment.

Highlights

  • Joystick Teleoperation Added: A new launch file, joystick_teleop.launch.py, has been introduced to enable control of the TurtleBot3 using a joystick. This integrates the joy_node for input and teleop_twist_joy_node to convert joystick commands into robot velocity commands.
  • TwistStamped Migration for Jazzy Compatibility: The turtlebot3_patrol_server.py script has been updated to utilize geometry_msgs/TwistStamped messages for publishing velocity commands instead of the simpler geometry_msgs/Twist. This change ensures compatibility with the ROS 2 Jazzy distribution and aligns with the teleop_twist_joy node's output.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces joystick teleoperation support by adding a new launch file and modifies the patrol server to use TwistStamped messages, likely for compatibility with newer ROS 2 distributions like Jazzy. The changes are a good step forward. My review focuses on improving the new launch file's configurability and correcting the usage of TwistStamped messages. Specifically, the joystick parameters are hardcoded, and I've suggested moving them to a configuration file. More critically, the TwistStamped messages are being published without populating the header timestamp, which is essential for proper operation. I've also identified a pre-existing logic bug in the patrol logic that is on a modified line and provided a fix.

Comment on lines +70 to +71
self.twist.twist.linear.x = 0.0
self.twist.twist.angular.z = 0.0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

When using TwistStamped messages, it's crucial to populate the header field, especially the timestamp, before publishing. This allows other nodes to know when the command was issued. You should update the timestamp every time you are about to publish the message.

Additionally, it would be good practice to set the frame_id in the __init__ method, for example: self.twist.header.frame_id = 'base_link'.

Suggested change
self.twist.twist.linear.x = 0.0
self.twist.twist.angular.z = 0.0
self.twist.header.stamp = self.get_clock().now().to_msg()
self.twist.twist.linear.x = 0.0
self.twist.twist.angular.z = 0.0

def go_front(self, position, length):
while True:
position += self.twist.linear.x
position += self.twist.twist.linear.x

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

There appears to be a logic error here. You are incrementing position using self.twist.twist.linear.x from the previous loop iteration (or from before this function was called). This will likely not work as intended, especially on the first iteration where the value might be zero. You probably meant to use self.linear_x, which is the speed you are setting in this loop.

A more robust implementation would use odometry to track the actual distance traveled instead of relying on time.sleep().

Suggested change
position += self.twist.twist.linear.x
position += self.linear_x

Comment on lines +88 to +89
self.twist.twist.linear.x = self.linear_x
self.twist.twist.angular.z = 0.0

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The TwistStamped message's header needs to be updated with a new timestamp before each publication. This is crucial for systems that rely on the age of the velocity command.

Suggested change
self.twist.twist.linear.x = self.linear_x
self.twist.twist.angular.z = 0.0
self.twist.header.stamp = self.get_clock().now().to_msg()
self.twist.twist.linear.x = self.linear_x
self.twist.twist.angular.z = 0.0

Comment on lines +113 to +114
self.twist.twist.linear.x = 0.0
self.twist.twist.angular.z = self.angular_z

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

As in other parts of the file, the timestamp in the TwistStamped message header should be updated with the current time before publishing.

Suggested change
self.twist.twist.linear.x = 0.0
self.twist.twist.angular.z = self.angular_z
self.twist.header.stamp = self.get_clock().now().to_msg()
self.twist.twist.linear.x = 0.0
self.twist.twist.angular.z = self.angular_z

Comment on lines 30 to 41
teleop_node = Node(
package='teleop_twist_joy',
executable='teleop_node',
name='teleop_twist_joy_node',
parameters=[{
'axis_linear.x': 1,
'axis_angular.yaw': 3,
'publish_stamped_twist': True,
'scale_linear.x': 0.5,
'scale_angular.yaw': 0.5,
}]
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better reusability and to avoid hardcoding, it's recommended to define these parameters in a separate YAML configuration file. This allows users to easily adapt the joystick configuration without modifying the launch file. You could create a joy_teleop.yaml in the param directory and load it here. This would make your launch file more flexible and align with common ROS2 practices.

    # Teleop node to convert joy to cmd_vel
    teleop_node = Node(
        package='teleop_twist_joy',
        executable='teleop_node',
        name='teleop_twist_joy_node',
        parameters=[PathJoinSubstitution([
            FindPackageShare('turtlebot3_bringup'),
            'param',
            'joy_teleop.yaml'
        ])]
    )

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with this one. I would put the .yaml file in the config folder to keep it consistent however.

@yun-goon
Copy link
Member

Hello @Dwilliestyle!
Thank you for your contribution!

Can you write a simple description??

Could you update package.xml accordingly for joystick_teleop.launch.py ??
Oh, and joystick_teleop.launch.py would be nice to have in the turtlebot3_teleop package.

@Dwilliestyle
Copy link
Author

Dwilliestyle commented Dec 28, 2025

Hello @Dwilliestyle! Thank you for your contribution!

Can you write a simple description??

Could you update package.xml accordingly for joystick_teleop.launch.py ?? Oh, and joystick_teleop.launch.py would be nice to have in the turtlebot3_teleop package.

I made the changes you requested and put the launch file in the teleop package. I put the description up top

…eleop.launch.py. Modified setup.py for YAML file installation
Signed-off-by: Don <dwilliestyle@gmail.com>
Signed-off-by: Don <dwilliestyle@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🌱 Todo

Development

Successfully merging this pull request may close these issues.

2 participants