前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在f1tenth仿真中如何实现更快速的跑圈-曲线分析篇

在f1tenth仿真中如何实现更快速的跑圈-曲线分析篇

作者头像
zhangrelay
发布2023-05-01 16:16:44
8060
发布2023-05-01 16:16:44
举报
文章被收录于专栏:机器人课程与技术

本文使用蓝桥云课,即开即用,如果配置第三方课程资源,通常也在10分钟内完成。

效果如下:

本文只给出思路,不给源码,可以“自己动手丰衣足食”。

数学基础:

1 米/秒(米每秒)=3.6 千米/时(千米每小时)

实测极限速度8米/秒。直线或弧度小于10度的赛道。此速度不稳定。

可靠性高稳定跑完全程速度峰值6.2米/秒。

前轮转向角度控制量需要依据物理机械特性进行约束设定在左右45°之内。


给定控制算法如下:

代码语言:javascript
复制
#!/usr/bin/env python
from __future__ import print_function
import sys
import math
import numpy as np
 
#ROS Imports
import rospy
from sensor_msgs.msg import Image, LaserScan
from ackermann_msgs.msg import AckermannDriveStamped, AckermannDrive
 
#PID CONTROL PARAMS
kp = 1.0
kd = 0.001
ki = 0.005
servo_offset = 0.0
prev_error = 0.0 
error = 0.0
integral = 0.0
prev_time = 0.0
 
#WALL FOLLOW PARAMS
ANGLE_RANGE = 270 # Hokuyo 10LX has 270 degrees scan
DESIRED_DISTANCE_RIGHT = 0.9 # meters
DESIRED_DISTANCE_LEFT = 0.85
VELOCITY = 1.5 # meters per second
CAR_LENGTH = 1.0 # Traxxas Rally is 20 inches or 0.5 meters
 
class WallFollow:
    """ Implement Wall Following on the car
    """
    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)

在完成实验1-4的基础上,修改f1tenth功能包,实现如下功能:

前轮转向角度控制量的曲线使用rqt中plot工具绘制。

原始:

曲线毛刺非常多

提速不改进:

曲线毛刺非常多,波动范围更大!比上一个曲线还要差 

改进1:

曲线波动范围大,但是已经有改善,并且毛刺大幅度降低 

改进2:

改善更为明显。

前轮转向角度控制量曲线的平滑度可以从上述四幅图的进行对比。

使用这些图表可以帮助改进算法。


通过控制量曲线进行算法改进和优化,提升局部规划器效果。 

f1tenth仿真转向角曲线绘制


同样的分析方法也可以用于两轮差速机器人:


AI提示(感觉基本不能用…………):

要提高F1赛车在比赛中的圈速,以下是一些可能的技巧和建议:

  1. 调整胎压:胎压是影响圈速的关键因素之一,赛车通常配备超级强大的轮胎,以提高抓地力和制动性能。要提高圈速,请确保您的轮胎压力保持在适当的水平。
  2. 调整悬挂:悬挂系统对于赛车的操控性和圈速表现有很大的影响。为了获得最佳性能,您应该根据比赛道路和天气条件,调整悬挂系统以提高赛车的稳定性和灵活性。
  3. 正确的进站策略:进站策略对于赛车的圈速也有很大的影响。在比赛中,您应该根据比赛形势和车队战术,选择合适的进站时机和方式,以获得最佳的圈速和竞争优势。
  4. 提高技术水平:熟练掌握基本驾驶技巧,例如正确的油门、刹车和换档操作,以及对赛道的熟悉程度,都是提高圈速的重要因素。
  5. 战术:战术可以在一定程度上影响圈速。在比赛中,您可以根据车队战术和对手表现,灵活运用技术和策略,以争取更多的机会和优势。

总之,要提高F1赛车在比赛中的圈速,需要综合考虑技术、战术和车队战略等多个因素。需要不断练习、尝试和调整,逐步提高自己的驾驶技能和竞争水平。

如果想要消除速度控制量曲线中的毛刺和曲线不平滑的现象,可以考虑以下几种方法:

  1. 调整进气量:如果进气量不均匀,可能会导致速度控制量曲线中出现毛刺和不平滑的现象。因此,您可以检查并调整空气滤清器和空气流量计的位置,以确保进气量的均匀性。
  2. 调整节气门:节气门的开度不均匀也可能导致速度控制量曲线中出现毛刺和不平滑的现象。您可以检查并调整节气门的位置,以确保开度的均匀性。
  3. 调整点火时间:点火时间不正确也可能会导致速度控制量曲线中出现毛刺和不平滑的现象。您可以检查并调整点火时间,以确保点火正时的准确性。
  4. 调整喷油量:喷油量不均匀也可能会导致速度控制量曲线中出现毛刺和不平滑的现象。您可以检查并调整喷油量,以确保油门响应的平稳性和曲线的平滑度。
  5. 调整进气温度:进气温度过高或过低都可能导致速度控制量曲线中出现毛刺和不平滑的现象。您可以检查并调整进气温度,以确保进气温度的适宜性和曲线的平滑度。

综上所述,调整以上因素可以消除速度控制量曲线中的毛刺和曲线不平滑的现象,提高赛车的性能和竞争力。

提高机器人巡线速度的方法有以下几种:

  1. 选择合适的无人机机型:根据不同的任务及线路环境特点,采用不同的机型进行作业,实现精准作业效果。
  2. 检查电池的数量与状态:在数量方面,电池数量与作业量要足够匹配。在电池状态方面,需要注意检查电池的外观是否有损坏、变形,电池接口的金属片是否存在破损、烧蚀等。
  3. 事先调查巡检线路的现场环境:出发前,可通过卫星图、地形图等多种资料,对所要巡视的线路的以下环境要素进行事先调查:地形条件状况、有无允许起降的场地、飞行空域有无遮挡物等,充分了解现场环境,还可对进一步的线路分段规划提供依据。
  4. 制定巡检飞行计划:在航线规划时,需要兼顾顺序安排、对于线路塔上关键部位(绝缘子、销钉或者螺母等)顺逆光的拍摄手法选择、曝光补偿的控制等。
  5. 采用多旋翼无人机倾斜摄影技术:可以从7个方面快速提升多旋翼无人机巡线效率:包括选择合适的无人机机型、检查电池的数量与状态、事先调查巡检线路的现场环境、制定巡检飞行计划、采用多旋翼无人机倾斜摄影技术、检查起降场地和飞行空域、以及对关键部位进行顺逆光拍摄等。

通过以上方法可以提高机器人巡线速度,但是需要注意,在提高速度的同时,要保证巡线的安全性和精准性。

为了降低机器人速度控制量曲线毛刺和控制不平滑的现象,可以采取以下措施:

  1. 选择合适的传感器:根据机器人所要检测的工件表面形状和尺寸,选择合适的传感器,并确保传感器的灵敏度和精度符合要求。
  2. 调整控制器参数:根据机器人所要执行的任务和环境条件,调整控制器的参数,如比例增益、积分增益和微分增益等,以提高机器人的控制精度和稳定性。
  3. 采用浮动加工技术:在机器人加工过程中,采用浮动加工技术,即将工件分为多个区域,对每个区域进行独立加工,然后将各个区域的加工结果拼接起来,以达到减少曲线毛刺的目的。
  4. 采用多轴加工技术:在机器人加工过程中,采用多轴加工技术,即将工件分为多个轴,同时对多个轴进行加工,以达到减少不平滑现象的目的。
  5. 优化加工程序:通过对加工程序进行优化,可以减少程序中的错误和不稳定因素,从而减少毛刺和不平滑现象的产生。
  6. 定期维护和保养:机器人的维护和保养工作对于其性能和稳定性至关重要,定期进行维护和保养可以有效地减少机器人故障的发生率,从而减少毛刺和不平滑现象的产生。

代码基本也是报废的:

代码语言:javascript
复制
#!/usr/bin/env python  
  
import rospy  
from control_msgs.msg import FollowJointTrajectory, FollowJointTrajectoryPoint  
from trajectory_msgs.msg import JointTrajectory, JointTrajectoryPoint  
  
rospy.init_node('laser_navigation_node')  
  
# 定义PID参数  
kp = 1.0  # 比例常数  
ki = 0.1  # 积分常数  
kd = 0.1  # 微分常数  
  
# 定义机器人末端执行器  
motor = rospy.get_param('~motor', bool)  
if not motor:  
    rospy.loginfo('No motor node provided')  
    exit()  
  
# 定义目标位姿和机器人末端执行器  
target_pose = JointTrajectory()  
target_pose.joint_names = ['joint_1', 'joint_2', 'joint_3', 'joint_4', 'joint_5', 'joint_6']  
target_pose.positions = [0.0, 0.0, 10.0, 10.0, 0.0, 0.0]  # 初始化机器人末端执行器位姿  
  
# 定义机器人初始位姿  
init_pose = JointTrajectory()  
init_pose.joint_names = ['joint_1', 'joint_2', 'joint_3', 'joint_4', 'joint_5', 'joint_6']  
init_pose.positions = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]  
  
# 定义PID控制器  
def pid_controller(traj, kp, ki, kd, target_pose):  
    error = target_pose - traj  
    integral = error * kp  
    derivative = (error - integral) * kd  
    return error + integral + derivative  
  
# 定义PID控制器的调用函数  
def run_laser_navigation():  
    rospy.loginfo('Starting laser navigation')  
    # 设置PID参数  
    kp = 1.0  
    ki = 0.1
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档