安装turtlebot3
首先需要安装Gazebo turtlebot3
sudo apt-get install ros-foxy-gazebo-*
sudo apt install ros-foxy-turtlebot3
sudo apt install ros-foxy-turtlebot3-simulations
添加环境变量
vim ~/.bashrc
export TURTLEBOT3_MODEL=burger
启动仿真环境
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py
绘图
打开rviz准备绘图
ros2 launch turtlebot3_cartographer cartographer.launch.py use_sim_time:=True
打开键盘绘制节点控制机器人移动绘制地图
ros2 run turtlebot3_teleop teleop_keyboard
保存建好的地图
ros2 run nav2_map_server map_saver_cli -f ~/ROS2/map/tutorial
关闭所有窗口后执行下面命令
导航
打开下面launch文件
ros2 launch turtlebot3_gazebo turtlebot3_world.launch.py
ros2 launch turtlebot3_navigation2 navigation2.launch.py use_sim_time:=true
在rviz 在其上方工具栏中有2D Pose estimate,用来设置大概的初始点
通过RViz中的navigation2 goal按钮,发送一个目标位置。然后自动规划路线到达目的的
简单的自动避障
通过订阅/scan话题获取正前方的距离与发布/cmd_vel话题的速度控制可以实现一个简单的避障功能,距离前方距离小于1m停止前进并转动,就这样一直循环下去就可以避障了,但是
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import LaserScan
from geometry_msgs.msg import Twist
import time
class AvoidOb(Node):
def __init__(self):
self.disp = 0
super().__init__("avoid_node")
self.subLidar = self.create_subscription(
LaserScan,
'scan',
self.listener_callback,
10
)
self.pubVel = self.create_publisher(
Twist,
'cmd_vel',
10
)
self.time = self.create_timer(1,self.time_callback)
def time_callback(self):
vel = Twist()
if self.disp < 1:
vel.angular.z = 0.3
else:
vel.linear.x = 0.3
self.pubVel.publish(vel)
self.get_logger().info(f'disp:{self.disp},send vel: {vel.linear.x},{vel.angular.z}')
def listener_callback(self,msg):
self.disp = msg.ranges[0]
def main(args=None):
rclpy.init(args=args)
fun = AvoidOb()
rclpy.spin(fun)
fun.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
航向锁定
通过订阅/imu话题可以获取机器人的角度信息,再通过发布cmd_vel话题控制机器人的航向
安装四元数转换工具
sudo apt install ros-foxy-tf-transformations
sudo pip3 install transforms3d
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Imu
from geometry_msgs.msg import Twist
from tf_transformations import euler_from_quaternion
import math
class AvoidOb(Node):
def __init__(self):
self.target_yaw = 45
super().__init__("imu_node")
self.subLidar = self.create_subscription(
Imu,
'imu',
self.listener_callback,
10
)
self.pubVel = self.create_publisher(
Twist,
'cmd_vel',
10
)
def listener_callback(self,msg):
if msg.orientation_covariance[0] < 0:
return
quaternion = [
msg.orientation.x,
msg.orientation.y,
msg.orientation.z,
msg.orientation.w,
]
[pitch,row,yaw] = euler_from_quaternion(quaternion)
pitch = pitch*180/math.pi
row = row*180/math.pi
yaw = yaw*180/math.pi
diff = self.target_yaw - yaw
vel_cmd = Twist()
vel_cmd.angular.z = diff * 0.01
self.pubVel.publish(vel_cmd)
self.get_logger().info(f'pitch:{pitch},row:{row},yaw:{yaw}. angularZ:{vel_cmd.angular.z}')
def main(args=None):
rclpy.init(args=args)
fun = AvoidOb()
rclpy.spin(fun)
fun.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
运行代码机器人将转动45度并固定角度