Carla自動駕駛仿真九:車輛變道路徑規劃

文章目錄

  • 前言
  • 一、關鍵函數
  • 二、完整代碼
  • 效果


前言

本文介紹一種在carla中比較簡單的變道路徑規劃方法,主要核心是調用carla的GlobalRoutePlanner模塊和PID控制模塊實現變道,大體的框架如下圖所示。

在這里插入圖片描述

在這里插入圖片描述


一、關鍵函數

1、get_spawn_point(),該函數根據指定road和lane獲得waypoint(這里之所以這么用是為了選擇一條比較長的直路)。具體用法可以參考上篇文章:Carla自動駕駛仿真八:兩種查找CARLA地圖坐標點的方法

def get_spawn_point(self,target_road_id,target_lane_id):#每隔5m生成1個waypointwaypoints = self.map.generate_waypoints(5.0)# 遍歷路點for waypoint in waypoints:if waypoint.road_id == target_road_id:lane_id = waypoint.lane_id# 檢查是否已經找到了特定車道ID的路點if lane_id == target_lane_id:location = waypoint.transform.locationlocation.z = 1ego_spawn_point = carla.Transform(location, waypoint.transform.rotation)breakreturn ego_spawn_point

2、should_cut_in(),用于主車和目標車的相對距離判斷,當目標車超越自車一定距離時,開始給cut_in_flag置Ture,并在下一步驟規劃變道路徑和執行變道操作。

 def should_cut_in(self,npc_vehicle, ego_vehicle, dis_to_cut=5):location1 = npc_vehicle.get_transform().locationlocation2 = ego_vehicle.get_transform().locationrel_x = location1.x - location2.xrel_y = location1.y - location2.ydistance = math.sqrt(rel_x * rel_x + rel_y * rel_y)print("relative dis",distance)#rel_x 大于等于0,說明目標車在前方if rel_x >= 0:distance = distanceelse:distance = -distanceif distance >= dis_to_cut:print("The conditions for changing lanes are met.")cut_in_flag = Trueelse:cut_in_flag = Falsereturn cut_in_flag

3、cal_target_route(),函數中調用了Carla的GlobalRoutePlanner模塊,能根據起點和終點自動生成車輛行駛的路徑(重點),我這里的變道起點是兩車相對距離達到(閾值)時目標車的當前位置,而終點就是左側車道前方target_dis米。將起點和終點代入到route = grp.trace_route(current_location, target_location)就能獲取到規劃路徑route

在這里插入圖片描述

 def cal_target_route(self,vehicle=None,lanechange="left",target_dis=20):#實例化道路規劃模塊grp = GlobalRoutePlanner(self.map, 2)#獲取npc車輛當前所在的waypointcurrent_location = vehicle.get_transform().locationcurrent_waypoint = self.map.get_waypoint(current_location)#選擇變道方向if "left" in lanechange:target_org_waypoint = current_waypoint.get_left_lane()elif "right" in lanechange:target_org_waypoint = current_waypoint.get_right_lane()#獲取終點的位置target_location = target_org_waypoint.next(target_dis)[0].transform.location#根據起點和重點生成規劃路徑route = grp.trace_route(current_location, target_location)return route

4、speed_con_by_pid(),通過PID控制車輛的達到目標速度,pid是通過實例化Carla的PIDLongitudinalController實現。由于pid.run_step()只返回油門的控制,需要增加剎車的邏輯。

 control_signal = pid.run_step(target_speed=target_speed, debug=False)throttle = max(min(control_signal, 1.0), 0.0)  # 確保油門值在0到1之間brake = 0.0  # 根據需要設置剎車值if control_signal < 0:throttle = 0.0brake = abs(control_signal)  # 假設控制器輸出的負值可以用來剎車vehilce.apply_control(carla.VehicleControl(throttle=throttle, brake=brake))

5、PID = VehiclePIDController()是carla的pid橫縱向控制模塊,通過設置目標速度和目標終點來實現軌跡控制control = PID.run_step(target_speed, target_waypoint),PID參數我隨便調了一組,有興趣的可以深入調一下。


二、完整代碼

import carla
import time
import math
import sys#修改成自己的carla路徑
sys.path.append(r'D:\CARLA_0.9.14\WindowsNoEditor\PythonAPI\carla')
from agents.navigation.global_route_planner import GlobalRoutePlanner
from agents.navigation.controller import VehiclePIDController,PIDLongitudinalController
from agents.tools.misc import draw_waypoints, distance_vehicle, vector, is_within_distance, get_speedclass CarlaWorld:def __init__(self):self.client = carla.Client('localhost', 2000)self.world = self.client.load_world('Town06')# self.world = self.client.get_world()self.map = self.world.get_map()# 開啟同步模式settings = self.world.get_settings()settings.synchronous_mode = Truesettings.fixed_delta_seconds = 0.05def spawm_ego_by_point(self,ego_spawn_point):vehicle_bp = self.world.get_blueprint_library().filter('vehicle.tesla.*')[0]ego_vehicle = self.world.try_spawn_actor(vehicle_bp,ego_spawn_point)return ego_vehicledef spawn_npc_by_offset(self,ego_spawn_point,offset):vehicle_bp = self.world.get_blueprint_library().filter('vehicle.tesla.*')[0]# 計算新的生成點rotation = ego_spawn_point.rotationlocation = ego_spawn_point.locationlocation.x += offset.xlocation.y += offset.ylocation.z += offset.znpc_transform = carla.Transform(location, rotation)npc_vehicle = self.world.spawn_actor(vehicle_bp, npc_transform)return npc_vehicledef get_spawn_point(self,target_road_id,target_lane_id):#每隔5m生成1個waypointwaypoints = self.map.generate_waypoints(5.0)# 遍歷路點for waypoint in waypoints:if waypoint.road_id == target_road_id:lane_id = waypoint.lane_id# 檢查是否已經找到了特定車道ID的路點if lane_id == target_lane_id:location = waypoint.transform.locationlocation.z = 1ego_spawn_point = carla.Transform(location, waypoint.transform.rotation)breakreturn ego_spawn_pointdef cal_target_route(self,vehicle=None,lanechange="left",target_dis=20):#實例化道路規劃模塊grp = GlobalRoutePlanner(self.map, 2)#獲取npc車輛當前所在的waypointcurrent_location = vehicle.get_transform().locationcurrent_waypoint = self.map.get_waypoint(current_location)#選擇變道方向if "left" in lanechange:target_org_waypoint = current_waypoint.get_left_lane()elif "right" in lanechange:target_org_waypoint = current_waypoint.get_right_lane()#獲取終點的位置target_location = target_org_waypoint.next(target_dis)[0].transform.location#根據起點和重點生成規劃路徑route = grp.trace_route(current_location, target_location)return routedef draw_target_line(self,waypoints):# 獲取世界和調試助手debug = self.world.debug# 設置繪制參數life_time = 60.0  # 點和線將持續顯示的時間(秒)color = carla.Color(255, 0, 0)thickness = 0.3  # 線的厚度for i in range(len(waypoints) - 1):debug.draw_line(waypoints[i][0].transform.location + carla.Location(z=0.5),waypoints[i + 1][0].transform.location + carla.Location(z=0.5),thickness=thickness,color=color,life_time=life_time)def draw_current_point(self,current_point):self.world.debug.draw_point(current_point,size=0.1, color=carla.Color(b=255), life_time=60)def speed_con_by_pid(self,vehilce=None,pid=None,target_speed=30):control_signal = pid.run_step(target_speed=target_speed, debug=False)throttle = max(min(control_signal, 1.0), 0.0)  # 確保油門值在0到1之間brake = 0.0  # 根據需要設置剎車值if control_signal < 0:throttle = 0.0brake = abs(control_signal)  # 假設控制器輸出的負值可以用來剎車vehilce.apply_control(carla.VehicleControl(throttle=throttle, brake=brake))def set_spectator(self,vehicle):self.world.get_spectator().set_transform(carla.Transform(vehicle.get_transform().location +carla.Location(z=50), carla.Rotation(pitch=-90)))def should_cut_in(self,npc_vehicle, ego_vehicle, dis_to_cut=5):location1 = npc_vehicle.get_transform().locationlocation2 = ego_vehicle.get_transform().locationrel_x = location1.x - location2.xrel_y = location1.y - location2.ydistance = math.sqrt(rel_x * rel_x + rel_y * rel_y)print("relative dis",distance)if rel_x >= 0:distance = distanceelse:distance = -distanceif distance >= dis_to_cut:print("The conditions for changing lanes are met.")cut_in_flag = Trueelse:cut_in_flag = Falsereturn cut_in_flagif __name__ == '__main__':try:CARLA = CarlaWorld()#根據road_id和lane_id選擇出生點start_point = CARLA.get_spawn_point(target_road_id=40, target_lane_id=-5)#生成自車ego_vehicle = CARLA.spawm_ego_by_point(start_point)#設置初始的觀察者視角CARLA.set_spectator(ego_vehicle)#相對ego生成目標車relative_ego = carla.Location(x=-10, y=3.75, z=0)npc_vehicle = CARLA.spawn_npc_by_offset(start_point, relative_ego)# 設置ego自動巡航ego_vehicle.set_autopilot(True)#設置目標車初始速度的縱向控制PIDinitspd_pid = PIDLongitudinalController(npc_vehicle, K_P=1.0, K_I=0.1, K_D=0.05)#設置目標車的cut_in的橫縱向控制PIDargs_lateral_dict = {'K_P': 0.8, 'K_D': 0.8, 'K_I': 0.70, 'dt': 1.0 / 10.0}args_long_dict = {'K_P': 1, 'K_D': 0.0, 'K_I': 0.75, 'dt': 1.0 / 10.0}PID = VehiclePIDController(npc_vehicle, args_lateral_dict, args_long_dict)waypoints = Nonewaypoint_index = 0need_cal_route = Truecut_in_flag = Falsearrive_target_point = Falsetarget_distance_threshold = 2.0  # 切換waypoint的距離start_sim_time = time.time()while not arrive_target_point:CARLA.world.tick()# 更新觀察者的視野CARLA.set_spectator(ego_vehicle)#計算目標車的初始速度ego_speed = (ego_vehicle.get_velocity().x  * 3.6) #km/htarget_speed = ego_speed + 8 #目標車的目標速度#是否滿足cut_in條件if cut_in_flag:if need_cal_route:#生成車側車道前方30m的waypointwaypoints = CARLA.cal_target_route(npc_vehicle,lanechange= "left",target_dis=30)CARLA.draw_target_line(waypoints)need_cal_route = False# 如果已經計算了路線if waypoints is not None and waypoint_index < len(waypoints):# 獲取當前目標路點target_waypoint = waypoints[waypoint_index][0]# 獲取車輛當前位置transform = npc_vehicle.get_transform()#繪制當前運行的點CARLA.draw_current_point(transform.location)# 計算車輛與當前目標路點的距離distance_to_waypoint = distance_vehicle(target_waypoint, transform)# 如果車輛距離當前路點的距離小于閾值,則更新到下一個路點if distance_to_waypoint < target_distance_threshold:waypoint_index += 1  # 移動到下一個路點if waypoint_index >= len(waypoints):arrive_target_point = Trueprint("npc_vehicle had arrive target point.")break  # 如果沒有更多的路點,退出循環else:# 計算控制命令control = PID.run_step(target_speed, target_waypoint)# 應用控制命令npc_vehicle.apply_control(control)else:#設置NPC的初始速度CARLA.speed_con_by_pid(npc_vehicle,initspd_pid,target_speed)#判斷是否可以cut incut_in_flag = CARLA.should_cut_in(npc_vehicle,ego_vehicle,dis_to_cut=8)# 判斷是否達到模擬時長if time.time() - start_sim_time > 60:print("Simulation ended due to time limit.")break#到達目的地停車npc_vehicle.apply_control(carla.VehicleControl(throttle=0, steer=0, brake=-0.5))print("Control the target car to brake.")time.sleep(10)except Exception as e:print(f"An error occurred: {e}")finally:# 清理資源print("Cleaning up the simulation...")if ego_vehicle is not None:ego_vehicle.destroy()if npc_vehicle is not None:npc_vehicle.destroy()settings = CARLA.world.get_settings()settings.synchronous_mode = False  # 禁用同步模式settings.fixed_delta_seconds = None

效果

下述是變道規劃簡單的實現,軌跡跟蹤效果比較一般,PID沒有仔細調,紫色是車輛運行的點跡。

在這里插入圖片描述
公眾號:自動駕駛simulation

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715185.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715185.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715185.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

c語言字符串函數之strcpy函數,strnpy函數

strcpy函數 語法格式 strcpy(字符數組1,字符串2&#xff09; 它的作用是把字符串2復制到字符數組1里面 #include<stdio.h> #include<string.h> int main() {char c[]"河南";char d[]"安徽";char d[];printf("%s\n",strcpy(c,d));…

力扣hot100題解(python版41-43題)

41、二叉樹的層序遍歷 給你二叉樹的根節點 root &#xff0c;返回其節點值的 層序遍歷 。 &#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 示例 1&#xff1a; 輸入&#xff1a;root [3,9,20,null,null,15,7] 輸出&#xff1a;[[3],[9,20],[15,7]]示例…

【C語言結構體】用戶自定義類型--結構體,結構體傳參,位段,聯合體和枚舉【圖文詳解】

歡迎來CILMY23的博客喔&#xff0c;本篇為【C語言結構體】用戶自定義類型--結構體&#xff0c;結構體傳參&#xff0c;位段&#xff0c;聯合體和枚舉【圖文詳解】&#xff0c;感謝觀看&#xff0c;支持的可以給個一鍵三連&#xff0c;點贊關注收藏。 前言 上一篇&#xff08;ht…

GO—函數

Go 語言支持普通函數、匿名函數和閉包&#xff0c;從設計上對函數進行了優化和改進&#xff0c;讓函數使用起來更加方便。 Go 語言的函數屬于“一等公民”&#xff08;first-class&#xff09;&#xff0c;也就是說&#xff1a; 函數本身可以作為值進行傳遞。支持匿名函數和閉…

Leetcode.2369 檢查數組是否存在有效劃分

題目鏈接 Leetcode.2369 檢查數組是否存在有效劃分 rating : 1780 題目描述 給你一個下標從 0 0 0 開始的整數數組 n u m s nums nums &#xff0c;你必須將數組劃分為一個或多個 連續 子數組。 如果獲得的這些子數組中每個都能滿足下述條件 之一 &#xff0c;則可以稱其為…

推薦6款SSH遠程連接工具

1、Xshell 介紹&#xff1a; xshell是一個非常強大的安全終端模擬軟件&#xff0c;它支持SSH1, SSH2, 以及Windows平臺的TELNET 協議。Xshell可以在Windows界面下用來訪問遠端不同系統下的服務器&#xff0c;從而比較好的達到遠程控制終端的目的。 業界最強大的SSH客戶機 官…

數據分析-Pandas數據的直方圖探查

數據分析-Pandas數據的直方圖探查 數據分析和處理中&#xff0c;難免會遇到各種數據&#xff0c;那么數據呈現怎樣的規律呢&#xff1f;不管金融數據&#xff0c;風控數據&#xff0c;營銷數據等等&#xff0c;莫不如此。如何通過圖示展示數據的規律&#xff1f; 數據表&…

農產品質量追溯系統—功能介紹(2)

儲藏管理 儲藏信息管理對需要儲藏的農產品,記錄儲藏的相關信息,如儲藏開始時間、存放倉庫、操作人員、儲藏原因等; 倉庫信息管理物流管理 物流公司管理對相關的物流公司信息進行登記,以便于管理和追溯; 車輛管理

我的秋招數據分析崗面經分享(京東,美團,阿里,拼多多,vivo,滴滴)

節前&#xff0c;我們社群組織了一場技術&面試討論會&#xff0c;邀請了一些互聯網大廠同學、參加社招和校招面試的同學&#xff0c;針對新手如何入門數據分析、機器學習算法、該如何備戰面試、面試常考點分享等熱門話題進行了深入的討論。 基于社群的討論&#xff0c;今天…

力扣爆刷第84天之hot100五連刷6-10

力扣爆刷第84天之hot100五連刷6-10 文章目錄 力扣爆刷第84天之hot100五連刷6-10一、15. 三數之和二、42. 接雨水三、3. 無重復字符的最長子串四、438. 找到字符串中所有字母異位詞五、560. 和為 K 的子數組 一、15. 三數之和 題目鏈接&#xff1a;https://leetcode.cn/problem…

JAVA學習筆記13(位運算)

1.位運算 1.1 原碼、反碼、補碼 ? *規則&#xff1a; ? 1.二進制的最高位是符號位&#xff1a;0表示正數&#xff0c;1表示負數 ? 2.正數的原碼&#xff0c;反碼&#xff0c;補碼都一樣&#xff08;三碼合一&#xff09; ? 3.負數的反碼 他的原碼符號位不變&#xff…

從metashape導出深度圖,從深度圖恢復密集點云

從metashape導出深度圖&#xff0c;從深度圖恢復密集點云 1.從metashape導出深度圖 參考&#xff1a;https://blog.csdn.net/WHU_StudentZhong/article/details/123107072?spm1001.2014.3001.5502 2.從深度圖建立密集點云 首先從metashape導出blockExchange格式的xml文件&…

OpenHarmony、HarmonyOS打開編輯 PDF 等操作的三方組件使用教程

項目場景: 隨著數字化時代的發展,PDF 文檔成為廣泛應用于各行業的重要文件格式。為了提高OpenHarmony/HarmonyOS生態系統的功能性和用戶體驗,我們需要一款支持打開、編輯PDF文件的應用程序。 使用戶能夠輕松打開、瀏覽和編輯PDF文件。該應用將充分利用OpenHarmony/HarmonyO…

【NTN 衛星通信】衛星和無人機配合的應用場景

1 場景概述 衛星接入網是一種有潛力的技術&#xff0c;可以為地面覆蓋差地區的用戶提供無處不在的網絡服務。然而&#xff0c;衛星覆蓋范圍對于位于考古或采礦地點內部/被茂密森林覆蓋的村莊/山谷/靠近山丘或大型建筑物的用戶可能很稀疏。因此&#xff0c;涉及衛星接入和無人駕…

HarmonyOS Full SDK的安裝

OpenHarmony的應用開發工具HUAWEI DevEco Studio現在隨著OpenHarmony版本發布而發布,只能在版本發布說明中下載,例如最新版本的OpenHarmony 4.0 Release。對應的需要下載DevEco Studio 4.0 Release,如下圖。 圖片 下載Full SDK主要有兩種方式,一種是通過DevEco Studio下載…

教你用Fiddler捕獲HTTPS請求

安裝Fiddler 這里不特別說明了&#xff0c;網上搜索一大把&#xff0c;根據安裝引導一步步安裝即可。&#xff08;這里采用的是fiddler v4.6&#xff09; 配置Fiddler 1、打開fiddler配置Tools –>Telerik Fiddler Options。 2、打開HTTPS配置項&#xff0c;勾選“Captur…

【程序員養生延壽系列-萬人關注的養生指南 4 】

1.早起一杯溫水&#xff0c;疏通腸胃&#xff0c;補充水分。 2.早十點和下午三點左右活動活動身體&#xff08;運動or健身&#xff09;&#xff0c;放松緊張疲憊的身體&#xff0c;幫助消化&#xff0c;給身體透個氣。 3.每天散步&#xff0c;好處多多&#xff08;減肥健身&a…

ctf_show筆記篇(web入門---爆破)

爆破 21&#xff1a;直接bp抓包跑字典&#xff0c;需base64加密 22&#xff1a;可用工具跑也可用瀏覽器找還可以用網上做好的域名查找去找 23&#xff1a;此題需跑腳本已經附上自寫腳本 最后跑出來六個答案一個一個嘗試得到答案為3j import hashlibm "0123456789qwert…

C++_AVL樹

目錄 1、AVL的概念 2、平衡因子的調整概念 3、AVL樹的插入 3.1 調整平衡因子代碼實現 3.2 右旋操作 3.2 左旋操作 3.3 雙旋-先右旋再左旋 3.4 雙旋-先左旋再右旋 3.5 旋轉操作的小結 4、AVL的驗證與實現 結語 前言&#xff1a; 在C中&#xff0c;AVL樹是在二叉搜索…

2024中國眼博會,山東省眼科醫學技術交流大會

以展帶會&#xff0c;以會促展&#xff0c;展與會有機結合&#xff0c;立足山東打造具全國影響力的眼康產業發展盛會&#xff1b; ——隨著時代的高速發展&#xff0c;科技的進步&#xff0c;現代生活節奏的加快&#xff0c;青少年近視問題日益嚴重&#xff0c;對兒童青少年的…