Reputation: 1
I want to build mobile robot. I am using raspberry pi 5, YDLidar X3, ROS jazzy, slam toolbox and want to add navigation to my robot(nav2). Also I should mention that I am using motors without encoders.
Is it possible to run nav2 without encoders? Currently I am using odometry from lidar using this package: https://github.com/MAPIRlab/rf2o_laser_odometry
My transforms looks like this
<robot name="my_robot" xmlns:xacro="http://www.ros.org/wiki/xacro"> <!-- Constants/Properties --> <xacro:property name="base_width" value="0.4"/> <xacro:property name="base_length" value="0.6"/> <xacro:property name="base_height" value="0.2"/> <xacro:property name="wheel_radius" value="0.1"/> <xacro:property name="wheel_length" value="0.05"/> <xacro:property name="wheel_offset_z" value="-0.1"/> <xacro:property name="wheel_offset_y" value="0.2"/> <xacro:property name="wheel_offset_x" value="-0.1"/> <xacro:property name="caster_radius" value="0.05"/> <xacro:property name="caster_offset_x" value="0.2"/> <xacro:property name="caster_offset_z" value="-0.15"/> <xacro:property name="lidar_radius" value="0.1"/> <xacro:property name="lidar_length" value="0.06"/> <xacro:property name="lidar_offset_z" value="0.13"/> <!-- Materials --> <material name="grey"> <color rgba="0.5 0.5 0.5 1"/> </material> <material name="blue"> <color rgba="0 0 0.5 1"/> </material> <!-- Wheel macro --> <xacro:macro name="wheel" params="prefix reflect"> <joint name="base_${prefix}_wheel_joint" type="fixed"> <parent link="base_link"/> <child link="${prefix}_wheel"/> <origin xyz="${wheel_offset_x} ${reflect * wheel_offset_y} ${wheel_offset_z}" rpy="0 0 0"/> </joint> <link name="${prefix}_wheel"> <visual> <geometry> <cylinder radius="${wheel_radius}" length="${wheel_length}"/> </geometry> <origin xyz="0 0 0" rpy="1.57 0 0"/> <material name="grey"/> </visual> </link> </xacro:macro> <!-- Base Footprint --> <link name="base_footprint"/> <joint name="base_joint" type="fixed"> <parent link="base_footprint"/> <child link="base_link"/> <origin xyz="0 0 ${base_height/2}" rpy="0 0 0"/> </joint> <!-- Base Link --> <link name="base_link"> <visual> <geometry> <box size="${base_length} ${base_width} ${base_height}"/> </geometry> <origin xyz="0 0 0" rpy="0 0 0"/> <material name="blue"/> </visual> </link> <!-- LIDAR --> <joint name="lidar_joint" type="fixed"> <parent link="base_link"/> <child link="lidar_link"/> <origin xyz="0 0 ${lidar_offset_z}" rpy="0 0 0"/> </joint> <link name="lidar_link"> <visual> <geometry> <cylinder radius="${lidar_radius}" length="${lidar_length}"/> </geometry> <origin xyz="0 0 0" rpy="0 0 0"/> <material name="grey"/> </visual> </link> <!-- Wheels --> <xacro:wheel prefix="left" reflect="1"/> <xacro:wheel prefix="right" reflect="-1"/> <!-- Caster Wheel --> <joint name="base_caster_wheel_joint" type="fixed"> <parent link="base_link"/> <child link="caster_wheel"/> <origin xyz="${caster_offset_x} 0 ${caster_offset_z}" rpy="0 0 0"/> </joint> <link name="caster_wheel"> <visual> <geometry> <sphere radius="${caster_radius}"/> </geometry> <origin xyz="0 0 0" rpy="0 0 0"/> <material name="grey"/> </visual> </link> </robot>
import rclpy from rclpy.node import Node import gpiod from geometry_msgs.msg import Twist import time
class ArduinoBaseController(Node): def init(self): super().init('arduino_base_controller')
# Define GPIO pins self.motor_left_forward = 17 # Left motor forward self.motor_left_backward = 27 # Left motor backward self.motor_right_forward = 22 # Right motor forward self.motor_right_backward = 23 # Right motor backward self.chip = gpiod.Chip('gpiochip4') # Initialize GPIOs self.left_forward = self.chip.get_line(self.motor_left_forward) self.left_backward = self.chip.get_line(self.motor_left_backward) self.right_forward = self.chip.get_line(self.motor_right_forward) self.right_backward = self.chip.get_line(self.motor_right_backward) self.left_forward.request(consumer="Motor", type=gpiod.LINE_REQ_DIR_OUT) self.left_backward.request(consumer="Motor", type=gpiod.LINE_REQ_DIR_OUT) self.right_forward.request(consumer="Motor", type=gpiod.LINE_REQ_DIR_OUT) self.right_backward.request(consumer="Motor", type=gpiod.LINE_REQ_DIR_OUT) # Subscribe to /cmd_vel self.create_subscription(Twist, '/cmd_vel', self.cmd_vel_callback, 10) self.get_logger().info("Arduino Base Controller Node Initialized. Listening on /cmd_vel.") def stop_motors(self): """ Stops all motors safely """ self.left_forward.set_value(0) self.left_backward.set_value(0) self.right_forward.set_value(0) self.right_backward.set_value(0) def cmd_vel_callback(self, msg: Twist): linear = msg.linear.x angular = msg.angular.z self.get_logger().info(f"Received cmd_vel: linear.x = {linear}, angular.z = {angular}") if linear > 0.05: # Move Forward self.get_logger().info("Command: Move Forward") self.left_forward.set_value(0) self.left_backward.set_value(1) self.right_forward.set_value(1) self.right_backward.set_value(0) elif linear < -0.05: # Move Backward self.get_logger().info("Command: Move Backward") self.left_forward.set_value(1) self.left_backward.set_value(0) self.right_forward.set_value(0) self.right_backward.set_value(1) elif angular > 0.05: # Turn Left self.get_logger().info("Command: Turn Left") self.left_forward.set_value(0) self.left_backward.set_value(1) self.right_forward.set_value(0) self.right_backward.set_value(1) elif angular < -0.05: # Turn Right self.get_logger().info("Command: Turn Right") self.left_forward.set_value(1) self.left_backward.set_value(0) self.right_forward.set_value(1) self.right_backward.set_value(0) else: # Stop self.get_logger().info("Command: Stop") self.stop_motors() def destroy_node(self): """ Release GPIOs on shutdown """ self.stop_motors() self.left_forward.release() self.left_backward.release() self.right_forward.release() self.right_backward.release() super().destroy_node()
def main(args=None): rclpy.init(args=args) node = ArduinoBaseController() rclpy.spin(node) node.destroy_node() rclpy.shutdown()
if name == 'main': main()
I start it as
ros2 run tf2_ros static_transform_publisher 0 0 0.13 0 0 0 base_link lidar_link
ros2 run move_listener move_listener (topic is published and listen to data correctly)
ros2 run robot_state_publisher robot_state_publisher /home/dima/ros2_ws/src/my_robot.urdf
ros2 launch ydlidar_ros2_driver ydlidar_launch_view.py
ros2 launch rf2o_laser_odometry rf2o_laser_odometry.launch.py
ros2 launch nav2_bringup localization_launch.py map:=/home/dima/ros2_ws/src/maps/room.yaml (it works correctly and I can locate robot)
Then I run navigation:
ros2 launch nav2_bringup navigation_launch.py use_sim_time:=False
and when I setup Goal Pose in logs I receive
[bt_navigator-5] [INFO] [1740857782.106966815] [bt_navigator]: Begin navigating from current location (0.26, -0.28) to (1.32, -0.26)
[controller_server-1] [INFO] [1740857782.141517124] [controller_server]: Received a goal, begin computing control effort.
[controller_server-1] [WARN] [1740857782.141642051] [controller_server]: No goal checker was specified in parameter 'current_goal_checker'. Server will use only plugin loaded general_goal_checker . This warning will appear once.
[controller_server-1] [WARN] [1740857782.141674366] [controller_server]: No progress checker was specified in parameter 'current_progress_checker'. Server will use only plugin loaded progress_checker . This warning will appear once.
[controller_server-1] [WARN] [1740857782.196578189] [controller_server]: Control loop missed its desired rate of 20.0000 Hz. Current loop rate is 18.2448 Hz.
[bt_navigator-5] [WARN] [1740857782.197324103] [bt_navigator_navigate_to_pose_rclcpp_node]: Timed out while waiting for action server to acknowledge goal request for follow_path
[bt_navigator-5] [WARN] [1740857782.197842478] [bt_navigator]: [navigate_to_pose] [ActionServer] Aborting handle.
[bt_navigator-5] [ERROR] [1740857782.197984424] [bt_navigator]: Goal failed
[controller_server-1] [WARN] [1740857782.269227152] [controller_server]: Control loop missed its desired rate of 20.0000 Hz. Current loop rate is 13.7792 Hz.
[controller_server-1] [WARN] [1740857782.313207748] [controller_server]: Control loop missed its desired rate of 20.0000 Hz. Current loop rate is 22.8437 Hz.
[collision_monitor-8] [ERROR] [1740857782.539174449] [getTransform]: Failed to get "laser_frame"->"base_footprint" frame transform: Lookup would require extrapolation into the future. Requested time 1740857782.333532 but the latest data is at time 1740857782.161137, when looking up transform from frame [odom] to frame [base_footprint]
[collision_monitor-8] [WARN] [1740857782.539311117] [collision_monitor]: Robot to stop due to invalid source. Either due to data not published yet, or to lack of new data received within the sensor timeout, or if impossible to transform data to base frame
Could you please help me to resolve it? I would really appreciate any piece of advise, thank you
Upvotes: 0
Views: 9