蘭橋クラウドクラスROSロボット旧バージョン実験レポート-05 ナビゲーション機能

プロジェクト名

実験5 ナビゲーション機能 

スコア

内容: 変換の作成、センサー メッセージの公開、走行距離データ情報、基本コントローラーの作成、マップの作成、ロボット構成、グローバルおよびローカルのコスト マップ、rviz の詳細構成、適応型モンテカルロ測位、障害物回避、ターゲットの送信

実験記録(70点)

実験 1 ~ 4 の完了に基づいて、f1tenth 関数パッケージを変更して次の関数を実現します。

 

シンプルで実行可能なレーザー ローカル プランニング PID アルゴリズムは次のとおりです。

#!/usr/bin/env Python

__future__ から print_function をインポート

インポートシステム

数学をインポート

numpyをnpとしてインポート

#ROS インポート

ロスピをインポートする

sensor_msgs.msg からインポート画像、LaserScan

ackermann_msgs.msg から import AckermannDriveStamped、AckermannDrive

#PID 制御パラメータ

kp = 1.0

kd = 0.001

〜 = 0.005

サーボオフセット = 0.0

前のエラー = 0.0

誤差 = 0.0

積分 = 0.0

前の時間 = 0.0

#ウォールフォローパラメータ

ANGLE_RANGE = 270 # 北洋 10LX は 270 度スキャン

DESIRED_DISTANCE_RIGHT = 0.9 # メートル

希望の距離_左 = 0.85

速度 = 1.5 # メートル/秒

CAR_LENGTH = 1.0 # Traxxas Rally は 20 インチまたは 0.5 メートルです

クラス WallFollow:

    「」「壁フォローを車に実装する」

    """

    def __init__(self):

        global prev_time

        #Topics & Subs, Pubs

        lidarscan_topic = '/scan'

        drive_topic = '/nav'

        prev_time = rospy.get_time()

        self.lidar_sub = rospy.Subscriber(lidarscan_topic, LaserScan, self.lidar_callback)

        self.drive_pub = rospy.Publisher(drive_topic, AckermannDriveStamped, queue_size = 10)

    def getRange(self, data, angle):

        # data: single message from topic /scan

        # angle: between -45 to 225 degrees, where 0 degrees is directly to the right

        # Outputs length in meters to object with angle in lidar scan field of view

        #make sure to take care of nans etc.

        #TODO: implement

        if angle >= -45 and angle <= 225:

            iterator = len(data) * (angle + 90) / 360

            if not np.isnan(data[int(iterator)]) and not np.isinf(data[int(iterator)]):

                return data[int(iterator)]

    def pid_control(self, error, velocity):

        global integral

        global prev_error

        global kp

        global ki

        global kd

        global prev_time

        angle = 0.0

        current_time = rospy.get_time()

        del_time = current_time - prev_time

        #TODO: Use kp, ki & kd to implement a PID controller for

        integral += prev_error * del_time

        angle = kp * error + ki * integral + kd * (error - prev_error) / del_time

        prev_error = error

        prev_time = current_time

        drive_msg = AckermannDriveStamped()

        drive_msg.header.stamp = rospy.Time.now()

        drive_msg.header.frame_id = "laser"

        drive_msg.drive.steering_angle = -angle

        if abs(angle) > math.radians(0) and abs(angle) <= math.radians(10):

            drive_msg.drive.speed = velocity

        elif abs(angle) > math.radians(10) and abs (angle) <= math.radians(20):

            drive_msg.drive.speed = 1.0

        else:

            drive_msg.drive.speed = 0.5

        self.drive_pub.publish(drive_msg)

    def followLeft(self, data, leftDist):

        #Follow left wall as per the algorithm

        #TODO:implement

        front_scan_angle = 125

        back_scan_angle = 180

        teta = math.radians(abs(front_scan_angle - back_scan_angle))

        front_scan_dist = self.getRange(data, front_scan_angle)

        back_scan_dist = self.getRange(data, back_scan_angle)

        alpha = math.atan2(front_scan_dist * math.cos(teta) - back_scan_dist, front_scan_dist * math.sin(teta))

        wall_dist = back_scan_dist * math.cos(alpha)

        ahead_wall_dist = wall_dist + CAR_LENGTH * math.sin(alpha)

        return leftDist - ahead_wall_dist

    def lidar_callback(self, data):

        """

        """

        error = self.followLeft(data.ranges, DESIRED_DISTANCE_LEFT) #TODO: replace with error returned by followLeft

        #send error to pid_control

        self.pid_control(error, VELOCITY)

def main(args):

    rospy.init_node("WallFollow_node", anonymous=True)

    wf = WallFollow()

    rospy.sleep(0.1)

    rospy.spin()

if __name__=='__main__':

main(sys.argv)

复现一个案例:

解压缩提供的f1_ws.zip功能包,unzip f1_ws.zip。

(/home/shiyanlou/f1tenth/src/)

 

回到功能包路径下,重新编译,catkin_make。

补全确少功能包!

sudo apt install ros-kinetic-teb-local-planner ros-kinetic-navigation ros-kinetic-move-base ros-kinetic-nav-core -y

修改:

/opt/ros/kinetic/share/catkin/cmake/toplevel.cmake

执行如下:roslaunch xiaomu_nav simulator_wall_following.launch

 

第一个错误是没有外界游戏手柄;

第二个错误是没有识别对应功能程序。

对应第一个解决方法,USB插入游戏手柄,如果没有游戏手柄可以忽略。

对应第二个有两种方式:

  1. 不严谨

找到对应程序,手工执行!

 

  1. 官方推荐

修改CMakelist.txt

参考如下:

catkin_install_python(PROGRAMS scripts/talker.py

  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}

)

对应本案例如下:

catkin_install_python(PROGRAMS

  scripts/wall_following.py

  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}

)

此部分完成后,转入导航测试:

roslaunch xiaomu_nav xiaomu_teb_nav.launch

报错如下:

 

参考上面问题二,方法二解决。

catkin_install_python(PROGRAMS

  scripts/wall_following.py scripts/cmd_vel_to_ackermann_drive.py

  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}

)

注意需要执行文件的权限。

 


蓝桥云课ROS机器人实验报告-05导航功能的大纲可能包括以下内容:

  1. 导航系统介绍:介绍导航系统的概念、组成、功能和实现方式。
  2. 地图构建:介绍如何使用ROS的地图构建工具,如SLAM、Map再将等,构建机器人的地图。
  3. 导航策略:介绍常见的导航策略,如A*、D*、Potential Field等,并介绍如何在ROS中实现这些策略。
  4. 机器人定位:介绍常见的机器人定位方法,如GPS、IMU、Visual Odometry等,并介绍如何在ROS中实现这些定位方法。
  5. 实验练习:学生需要根据给定的机器人硬件设备和控制需求,设计机器人的导航策略和定位方法,并在ROS环境中进行实验和调试。

以上是蓝桥云课ROS机器人实验报告-05导航功能大纲的一个大致框架,具体内容可能会根据实验的目的和实际情况进行调整。

蓝桥云课ROS机器人旧版实验报告-05导航功能进阶实验流程可能包括以下步骤:

  1. 导入机器人硬件设备的CAD模型:使用CAD软件(如SolidWorks、AutoCAD等)导入机器人的硬件设备的CAD模型,并导出为stl文件格式。
  2. 创建机器人仿真环境:在Gazebo中创建一个新的仿真环境,并设置仿真器的物理引擎、时间步长、传感器等参数。
  3. 导入机器人模型:将机器人的CAD模型导入到Gazebo中,并设置机器人的几何结构、运动学模型、动力学模型等。
  4. 编写机器人控制程序:使用ROS编写机器人的控制程序,包括机器人的运动控制、传感器数据采集等。
  5. 模拟传感器数据:在Gazebo中模拟机器人的传感器数据,如激光雷达、摄像头、GPS等,并将传感器数据输出到ROS中。
  6. 可视化机器状态和传感器数据:使用ROS的可视化工具,如rqt_plot、rqt_image等,将机器人的状态和传感器数据可视化。
  7. 调试和优化:根据实验结果进行调试和优化,包括机器人的控制策略、传感器数据的处理等。
  8. 实验评估:对实验结果进行评估,包括机器人的运动精度、传感器数据的准确性等。

以上是蓝桥云课ROS机器人旧版实验报告-05导航功能进阶实验流程的一个大致框架,具体步骤和流程可能会根据实验的目的和实际情况进行调整。

蓝桥云课ROS机器人旧版实验报告-05导航功能核心要点总结如下:

  1. 导航系统介绍:介绍导航系统的概念、组成、功能和实现方式。
  2. 地图构建:介绍如何使用ROS的地图构建工具,如SLAM、Map再将等,构建机器人的地图。
  3. 导航策略:介绍常见的导航策略,如A*、D*、Potential Field等,并介绍如何在ROS中实现这些策略。
  4. 机器人定位:介绍常见的机器人定位方法,如GPS、IMU、Visual Odometry等,并介绍如何在ROS中实现这些定位方法。

以上是蓝桥云课ROS机器人旧版实验报告-05导航功能核心要点的总结,掌握这些内容可以帮助学生在ROS中实现机器人的导航功能,包括地图构建、导航策略和机器人定位等。

在使用阿克曼模型进行移动机器人导航时,需要注意以下细节:

  1. 机器人模型的选择和参数设置:阿克曼模型是一种非完整约束的机器人模型,需要考虑机器人的几何参数(如轮距、轮速等)和动力学参数(如摩擦系数、电机响应时间等),并进行合理的设置。
  2. 运动控制策略:阿克曼模型是一种基于反馈的控制模型,需要设计合适的控制策略,如基于PID控制器、滑模控制器等,来保证机器人的稳定性和跟踪性能。
  3. 路径规划:在使用阿克曼模型进行导航时,需要为机器人规划一条合理的路径,使其能够从起点到达终点。这可以通过使用全局路径规划算法(如A算法、D算法等)或局部路径规划算法(如动态规划、滑模控制等)来实现。
  4. 传感器数据采集和处理:机器人需要使用传感器来获取环境信息,如激光雷达、摄像头、GPS等。需要对传感器数据进行预处理和滤波,以减少噪声和误差。
  5. 导航精度和稳定性:在使用阿克曼模型进行导航时,需要考虑模型的精度和稳定性。可以通过实验和调试来评估模型的性能,并进行优化和调整。
  6. 实时性能:导航系统需要实时响应机器人的运动状态和环境变化。在实现导航系统时,需要考虑算法的时间复杂度和实时性能,以确保系统的响应速度和稳定性。

综上所述,使用阿克曼模型进行移动机器人导航需要综合考虑机器人的模型、控制策略、路径规划、传感器数据采集和处理、导航精度和稳定性以及实时性能等因素,以确保机器人的导航效果和性能。

在ROS中仿真使用阿克曼模型的移动机器人导航时,需要注意以下细节:

  1. 机器人模型的建立和参数设置:在ROS中仿真使用阿克曼模型,需要建立机器人的模型,并设置好机器人的几何参数和动力学参数。可以使用ROS中的机器人描述文件(URDF或XML文件)来描述机器人模型,并使用ROS中的参数服务器来设置机器人的参数。
  2. 仿真环境的搭建和模拟器选择:在ROS中仿真使用阿克曼模型的移动机器人导航,需要搭建仿真环境,并选择合适的模拟器。常见的模拟器包括Gazebo、V-REP、ROS Robot Simulation等。
  3. 传感器数据的模拟和采集:在仿真环境中,需要模拟机器人的传感器数据,如激光雷达、摄像头、GPS等。可以使用ROS中的传感器模拟器来模拟传感器数据,并使用ROS中的消息传递机制来采集传感器数据。
  4. 控制算法的实现和调试:在ROS中实现控制算法通常使用ROS中的节点(Node)来实现。需要编写控制算法的节点,并使用ROS中的消息传递机制来与仿真环境和传感器数据进行交互。在进行调试时,可以使用ROS的调试工具,如rqt_console和rqt_graph等。
  5. 路径规划和导航算法的选择:在ROS中实现路径规划和导航算法,可以使用ROS中的导航包(Navigation Stack)。导航包提供了常用的路径规划和导航算法,如A算法、D算法等。可以根据实际需求选择合适的算法,并进行适当的配置和参数设置。
  6. 可视化和数据记录:在ROS中可以使用ROS中的可视化工具(Visualization Tools)来可视化机器人的运动和环境变化。还可以使用ROS中的日志记录工具(Logging Tools)来记录仿真过程中的的数据,以便后续分析和处理。

综上所述,在ROS中仿真使用阿克曼模型的进行移动机器人导航需要注意机器人的模型的建立和参数设置、仿真环境的搭建和模拟器选择、传感器数据的模拟和采集、控制算法的实现和调试、路径规划和导航算法的选择,以及可视化和数据记录等方面的。同时,需要熟悉ROS的架构和编程规范,以便更好地实现和调试导航系统。

这类问题AI解决不是特别擅长的

以下是在ROS中仿真使用阿克曼模型的移动机器人导航的示例代码:

# 导入必要的ROS包  
import rospy  
from std_msgs.msg import String  
from geometry_msgs.msg import Pose  
from nav_msgs.msg import OccupancyGrid  
from sensor_msgs.msg import LaserScan  
  
# 定义机器人的初始位置和方向  
start_pose = Pose(x=0.0, y=0.0, z=0.0, roll=0.0, pitch=0.0, yaw=0.0)  
  
# 定义机器人的激光传感器数据  
laser_scan_data = []  
for i in range(360):  
    laser_scan_data.append(100)  
  
# 定义机器人的地图  
map_data = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],  
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],  
            [1, 0, 1, 1, 1, 1, 1, 1, 0, 1],  
            [1, 0, 1, 0, 0, 0, 0, 0, 0, 1],  
            [1, 0, 1, 0, 0, 0, 0, 0, 0, 1],  
            [1, 0, 1, 0, 0, 0, 0, 0, 0, 1],  
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],  
            [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],  
            [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]  
  
# 发布机器人的位置和地图数据  
pub_pose = rospy.Publisher('/robot_pose', Pose, queue_size=10)  
pub_map = rospy.Publisher('/map', OccupancyGrid, queue_size=10)  
  
# 设置ROS节点的循环时间  
rospy.init_node('nav_test', anonymous=True)  
rate = rospy.Rate(10) # 10hz  
  
# 在ROS中循环发布机器人的位置和地图数据  
while not rospy.is_shutdown():  
    # 设置机器人的位置和方向  
    current_pose = Pose(x=start_pose.x+0.5, y=start_pose.y+0.5, z=start_pose.z+0.5,\  
                       roll=start_pose.roll+rospy.Time.now().to_sec(),\  
                       pitch=start_pose.pitch+rospy.Time.now().to_sec(),\  
                       yaw=start_pose.yaw+rospy.Time.now().to_sec())  
    # 将机器人的位置数据发布到ROS中  
    pub_pose.publish(current_pose)  
    # 设置机器人的激光传感器数据  
    laser_scan = LaserScan()  
    laser_scan.header.frame_id = "base_link"  
    laser_scan.angle_min = -180.0  
    laser_scan.angle_max = 180.0  
    laser_scan.angle_increment = -360/(len(laser_scan_data))  
    laser_scan.time_stamp = rospy.Time.now()  
    laser_scan.range_min = -3.5  
    laser_scan.range_max = 3.5
laser_scan.data = laser_scan_data  
    # 将机器人的激光传感器数据发布到ROS中  
    pub_laser_scan.publish(laser_scan)  
    # 设置机器人的地图数据  
    map_msg = OccupancyGrid()  
    map_msg.header.frame_id = "map"  
    map_msg.info.resolution = 1  
    map_msg.info.width = len(map_data[0])  
    map_msg.info.height = len(map_data)  
    map_msg.info.origin.position.x = 0  
    map_msg.info.origin.position.y = 0  
    map_msg.info.origin.position.z = 0  
    map_msg.info.origin.orientation.x = 0  
    map_msg.info.origin.orientation.y = 0  
    map_msg.info.origin.orientation.z = 0  
    map_msg.info.origin.orientation.w = 1  
    map_msg.data = map_data  
    # 将机器人的地图数据发布到ROS中  
    pub_map.publish(map_msg)  
      
    # 按照设定的循环率进行ROS节点的循环  
    rate.sleep()

以上是在ROS中仿真使用阿克曼模型的移动机器人导航的示例代码。这个代码示例假设机器人有一个激光传感器和一个全局地图,并将它们发布到ROS中。同时,它还发布了机器人的位置和方向数据。在此基础上,你可以根据实际需求添加更多的功能和组件,如局部地图、SLAM算法、路径规划等。 


 

おすすめ

転載: blog.csdn.net/ZhangRelay/article/details/132046559