對(duì)于CARLA模擬器來(lái)說(shuō),這是一段漫長(zhǎng)的旅程长赞。該團(tuán)隊(duì)于2016年底開始了這一冒險(xiǎn)活動(dòng)晦攒,旨在將最先進(jìn)的自動(dòng)駕駛模擬器帶入開源社區(qū)。我們的目標(biāo)很明確:通過(guò)可訪問(wèn)的模擬使自動(dòng)駕駛民主化得哆,并創(chuàng)建一個(gè)平臺(tái)脯颜,使學(xué)者和行業(yè)成員可以共享知識(shí)和結(jié)果公開。2017年11月贩据,我們首次公開發(fā)行了CARLA栋操。當(dāng)時(shí),該平臺(tái)是一個(gè)謙虛的模擬器饱亮,圍繞基于攝像機(jī)的策略學(xué)習(xí)和數(shù)據(jù)獲取任務(wù)的用例構(gòu)建矾芙。一個(gè)很好的起點(diǎn),但還不夠近上。因此剔宪,我們決定完全重新設(shè)計(jì)平臺(tái),以生產(chǎn)出更先進(jìn)壹无,更靈活的自動(dòng)駕駛模擬器葱绒,并牢記以下目標(biāo):
- 用戶必須能夠以簡(jiǎn)單的方式創(chuàng)建新的內(nèi)容(即地圖,關(guān)卡)
- 用戶必須能夠創(chuàng)建復(fù)雜的交通場(chǎng)景(又名交通狀況)
- 用戶必須能夠利用自動(dòng)駕駛中使用的任何現(xiàn)有傳感器
- 用戶必須能夠自動(dòng)培訓(xùn)和評(píng)估他們的駕駛?cè)藛T(駕駛?cè)藛T)
- 該平臺(tái)必須是可擴(kuò)展的斗锭,即計(jì)算在不同節(jié)點(diǎn)之間分布
我們?cè)谶^(guò)去的10個(gè)月中致力于重新設(shè)計(jì)平臺(tái)以實(shí)現(xiàn)這些目標(biāo)地淀。0.9.0版本是此工作的初步展示,其中引入了新的CARLA API拒迅,多客戶端體系結(jié)構(gòu)以及可以隨意控制所有仿真車輛的功能骚秦。
在此0.9.1版本中,我們添加了關(guān)鍵功能璧微,以啟用使用外部工具制作的新內(nèi)容(地圖)的攝取作箍,以及使用基于航點(diǎn)和地圖查詢的新API輕松導(dǎo)航這些地圖。為此前硫,我們采用了OpenDrive作為CARLA道路網(wǎng)絡(luò)格式的核心胞得。我們的地圖表示基于OpenDrive構(gòu)建,從而提供了易于使用的通用導(dǎo)航API屹电。我們還介紹了Town03阶剑,這是一個(gè)復(fù)雜的城市場(chǎng)景跃巡,具有多車道的道路,隧道牧愁,環(huán)形交叉路口和許多其他有趣的功能素邪,以外部工具半自動(dòng)生成的地圖為例。
現(xiàn)在猪半,讓我們深入了解此版本的新功能兔朦,請(qǐng)注意,這仍然是開發(fā)版本磨确!
駕駛模擬消息
服務(wù)器在0.8.X分支中生成的所有駕駛消息都已作為CARLA 0.9.1的傳感器合并回去沽甥。這使客戶能夠檢測(cè)到碰撞并確定車道變化。新的可以檢測(cè)到與場(chǎng)景的靜態(tài)布局和動(dòng)態(tài)對(duì)象(如車輛)的碰撞sensor.other.collision
乏奥。
class CollisionSensor(object):
"""
Encapsulate sensor.other.collision messages
"""
def __init__(self, parent_actor):
self._parent = parent_actor
self._history = collections.defaultdict(int)
bp = world.get_blueprint_library().find('sensor.other.collision')
self._sensor = world.spawn_actor(bp, carla.Transform(), attach_to=self._parent)
# We need to pass the lambda a weak reference to self to avoid circular
# reference.
weak_self = weakref.ref(self)
self.sensor.listen(lambda event: CollisionSensor._on_collision(weak_self, event))
@staticmethod
def _on_collision(weak_self, event):
self = weak_self()
if not self:
return
actor_type = ' '.join(event.other_actor.type_id.replace('_', '.').title().split('.')[1:])
self._hud.notification('Collision with %r' % actor_type)
impulse = event.normal_impulse
intensity = math.sqrt(impulse.x**2 + impulse.y**2 + impulse.z**2)
self._history.append((event.frame_number, intensity))
...
在這個(gè)例子中摆舟,我們將接收的消息的每個(gè)所述時(shí)間parent_actor
(車輛)崩潰針對(duì)場(chǎng)景的其它演員,說(shuō)明其類型和大小的影響邓了。該傳感器還報(bào)告與地圖的靜態(tài)元素(例如交通標(biāo)志恨诱,墻壁,交通信號(hào)燈骗炉,人行道等)的碰撞胡野。
sensor.other.lane_detector
現(xiàn)在可以使用新的傳感器來(lái)檢測(cè)車道變化。新的CARLA地圖更加復(fù)雜痕鳍,包含多車道的道路硫豆。在這種情況下,重要的是要檢測(cè)車輛何時(shí)改變車道笼呆,確定車輛已越過(guò)哪種類型的車道標(biāo)記以及目標(biāo)車道的方向是什么熊响。請(qǐng)參見(jiàn)下面的代碼示例:
class LaneInvasionSensor(object):
def __init__(self, parent_actor, hud):
self.sensor = None
self._parent = parent_actor
self._hud = hud
world = self._parent.get_world()
bp = world.get_blueprint_library().find('sensor.other.lane_detector')
self.sensor = world.spawn_actor(bp, carla.Transform(), attach_to=self._parent)
# We need to pass the lambda a weak reference to self to avoid circular
# reference.
weak_self = weakref.ref(self)
self.sensor.listen(lambda event: LaneInvasionSensor._on_invasion(weak_self, event))
@staticmethod
def _on_invasion(weak_self, event):
self = weak_self()
if not self:
return
text = ['%r' % str(x).split()[-1] for x in set(event.crossed_lane_markings)]
self._hud.notification('Crossed line %s' % ' and '.join(text))
地圖和航點(diǎn)表示
現(xiàn)在可以通過(guò)Map類訪問(wèn)公路網(wǎng)的高級(jí)表示。借助地圖對(duì)象诗赌,我們可以獲取建議的車輛生成點(diǎn)(可以安全地實(shí)例化新對(duì)象的地方):
map.get_spawn_points()
通過(guò)新的航點(diǎn)查詢API汗茄,這也使從客戶端驅(qū)動(dòng)變得非常容易。在下面的代碼中铭若,我們獲得與角色的當(dāng)前位置關(guān)聯(lián)的航路點(diǎn)洪碳。
w = map.get_waypoint(location)
用戶還可以生成指定距離內(nèi)的航路點(diǎn):
map.generate_waypoints(distance)
總體而言,用戶可以利用這些新功能來(lái)創(chuàng)建自己的導(dǎo)航算法:
client = carla.Client(args.host, args.port)
client.set_timeout(2.0)
hud = HUD(args.width, args.height)
world = World(client.get_world(), hud)
world.vehicle.set_simulate_physics(False)
m = world.world.get_map()
w = m.get_waypoint(world.vehicle.get_location())
clock = pygame.time.Clock()
count = 0
while True:
clock.tick_busy_loop(60)
world.tick(clock)
world.render(display)
pygame.display.flip()
if count % 10 == 0:
nexts = list(w.next(1.0))
print('Next(1.0) --> %d waypoints' % len(nexts))
if not nexts:
raise RuntimeError("No more waypoints!")
w = random.choice(nexts)
text = "road id = %d, lane id = %d, transform = %s"
print(text % (w.road_id, w.lane_id, w.transform))
if count % 40 == 0:
draw_waypoints(world.world, w)
count = 0
t = w.transform
world.vehicle.set_transform(t)
count += 1
圖1.使用新的Waypoint類即時(shí)生成的航點(diǎn)
用于半自動(dòng)地圖生成的管道
此版本最令人興奮的功能之一就是與使用外部工具創(chuàng)建的新地圖的兼容性叼屠。我們希望用戶在CARLA中輕松創(chuàng)建自己的地圖瞳腌。為此,我們采用了OpenDrive作為我們的地圖定義標(biāo)準(zhǔn)镜雨。使用眾所周知的標(biāo)準(zhǔn)可減少創(chuàng)建與CARLA模擬器兼容的新內(nèi)容所需的工作嫂侍。
我們一直與VectorZero緊密合作,以確保RoadRunner和CARLA之間的完全兼容性。憑借強(qiáng)大的程序生成引擎挑宠,RoadRunner是一種只需單擊幾下即可生成復(fù)雜駕駛地圖的工具菲盾。最好的是,它還會(huì)生成與3D地圖關(guān)聯(lián)的OpenDrive文件各淀,因此RoadRunner生成的地圖可以直接在CARLA中使用懒鉴,并具有當(dāng)前城鎮(zhèn)可用的所有功能。
VectorZero已承諾向要求它的學(xué)者免費(fèi)授予將RoadRunner用于學(xué)術(shù)和研究目的的許可碎浇。因此疗我,請(qǐng)?jiān)L問(wèn)他們的網(wǎng)站以獲得許可證并開始構(gòu)建自己的地圖!
圖2. RoadRunner場(chǎng)景示例
缺少的東西
- 全同步模式
- 模擬行人
- 功能齊全的ROS橋
這些功能將很快添加南捂。我們將在以后的版本中繼續(xù)改進(jìn)此API。如果您發(fā)現(xiàn)任何問(wèn)題或可以添加的建議旧找,請(qǐng)隨時(shí)在我們的GitHub或 Discord chat上與社區(qū)共享溺健。有關(guān)可用方法的完整列表,請(qǐng)參閱《Python API參考》钮蛛。
非常感謝我們所有的支持者和贊助者使這個(gè)項(xiàng)目成為現(xiàn)實(shí)鞭缭。祝1年快樂(lè)CARLA!
完整變更清單
- 使用VectorZero的RoadRunner生成的New Town03
- Python API增強(qiáng)功能
- 支持Python 3
- 支持檢索和更改照明和天氣狀況
- 激光雷達(dá)傳感器支持
- 圖像轉(zhuǎn)換器方法支持:Depth魏颓,LogarithmicDepth和CityScapesPalette
- IO方法支持傳感器數(shù)據(jù)岭辣,“ save_to_disk”可用于PNG,JPEG甸饱,TIFF和PLY
- 添加了碰撞事件傳感器“ sensor.other.collision”沦童,該碰撞事件在每次碰撞時(shí)觸發(fā)一個(gè)回調(diào),該碰撞會(huì)附加到該actor
- 添加了車道檢測(cè)器傳感器“ sensor.other.lane_detector”叹话,用于檢測(cè)車道入侵事件
- 添加了
carla.Map
和carla.Waypoint
類用于查詢有關(guān)道路布局的信息- 添加了將地圖轉(zhuǎn)換和保存為OpenDrive格式的方法
- 已添加
map.get_spawn_points()
以檢索建議的車輛生成點(diǎn) - 添加
map.get_waypoint(location)
查詢最近的航路點(diǎn) - 已添加
map.generate_waypoints(distance)
以在整個(gè)地圖上以近似距離生成航點(diǎn) - 添加
map.get_topology()
用于獲取包含定義路線圖邊緣的航點(diǎn)元組的列表 - 已添加
waypoint.next(distance)
以檢索從給定航路點(diǎn)可以到達(dá)的特定距離處的航路點(diǎn)列表
- 為車輛添加了邊界框?qū)傩裕?
vehicle.bounding_box
-
parent
為角色添加了屬性偷遗,如果角色附加到另一個(gè)角色,則沒(méi)有屬性 - 添加了啟用/禁用演員物理模擬的功能驼壶,
actor.set_simulate_physics(enabled=True)
- 增加了對(duì)請(qǐng)求當(dāng)前世界上所有活著的演員名單的支持氏豌,
world.get_actors()
-
world.get_actors()
返回ActorList
具有filter
功能和參與者的延遲初始化的對(duì)象 - 已添加
semantic_tags
到包含其所有組件標(biāo)簽列表的actor(這些標(biāo)簽與語(yǔ)義分割傳感器檢索到的標(biāo)簽匹配) - 暴露于車輛的最后控制權(quán),
vehicle.get_vehicle_control()
- 添加了一個(gè)“滴答”消息热凹,其中包含場(chǎng)景中所有演員的信息
- 在后臺(tái)執(zhí)行并緩存
- 添加
world.wait_for_tick()
用于阻止當(dāng)前線程泵喘,直到收到“滴答”消息 -
world.on_tick(callback)
每次接收“滴答”消息時(shí)添加的異步執(zhí)行回調(diào)函數(shù)。這些方法返回/傳遞一個(gè)carla.Timestamp
包含以下內(nèi)容的對(duì)象:幀計(jì)數(shù)般妙,上次滴答的增量時(shí)間纪铺,全局模擬時(shí)間和OS時(shí)間戳 - 檢索參與者信息的方法,例如
actor.get_transform()
碟渺,不需要與模擬器連接霹陡,這使得這些調(diào)用相當(dāng)便宜
- 允許從Python繪制調(diào)試形狀:點(diǎn),線,箭頭烹棉,框和字符串(
world.debug.draw_*
) - 已將ID(當(dāng)前劇集的ID)和地圖名稱添加到
carla.World
- 暴露的交通信號(hào)燈和交通標(biāo)志作為參與者攒霹。紅綠燈具有專門的actor類,可將紅綠燈狀態(tài)(紅色浆洗,綠色催束,黃色)作為屬性公開
- 添加了訪問(wèn)和修改
carla.Image
(像素)和carla.LidarMeasurement
(位置)中單個(gè)項(xiàng)目的方法 - 新增
carla.Vector3D
的(X,Y伏社,Z)的對(duì)象是不是carla.Location
- 刪除
client.ping()
并添加client.get_server_version()
抠刺,實(shí)現(xiàn)相同的目的 - 將
contains_X()
方法重命名為has_X()
- 將超時(shí)更改為使用秒(浮動(dòng))
- 允許迭代Actor藍(lán)圖的屬性
- 修復(fù)了通配符過(guò)濾問(wèn)題,現(xiàn)在稱為“車輛”摘昌。”或“ bmw *”模式也可以使用速妖!
- 修復(fù)
actor.set_transform()
了附屬演員的損壞
- 更多Python示例腳本并改進(jìn)了當(dāng)前示例
- 現(xiàn)在,所有腳本都使用每個(gè)地圖的建議生成點(diǎn)列表
- 將“ example.py”重命名為“ tutorial.py”聪黎,并使用API??中的最新更改進(jìn)行了更新
- 在示例中添加了超時(shí)
- “ manual_control.py”性能得到了改進(jìn)罕容,同時(shí)具有更多的度量
- “ manual_control.py”現(xiàn)在具有更改相機(jī)類型和位置的選項(xiàng)
- “ manual_control.py”現(xiàn)在具有迭代天氣預(yù)設(shè)的選項(xiàng)
- “ manual_control.py”現(xiàn)在具有更精美的HUD,其中包含大量信息稿饰,并通過(guò)F1鍵綁定將其刪除
- 添加了“ dynamic_weather.py”以實(shí)時(shí)更改天氣(視頻中使用的天氣)
- 添加了“ spawn_npc.py”以將大量NPC車輛快速添加到模擬器中
- 添加了“ spawn_npc.py –safe”以僅添加非問(wèn)題車輛
- “ vehicle_gallery.py”也有一些小問(wèn)題
- 資產(chǎn)和內(nèi)容改進(jìn)
- 改善了對(duì)自行車和摩托車的控制锦秒,雖然還不完善,但事故較少
- 調(diào)整了樹葉的最大距離剔除
- 調(diào)整了行人動(dòng)畫和縮放問(wèn)題(盡管新API尚不提供)
- 調(diào)整后的車輛物理和質(zhì)心
- 在Windows上打包項(xiàng)目時(shí)修復(fù)文件名過(guò)長(zhǎng)
- 修復(fù)了“ SplineMeshRepeater”有時(shí)會(huì)丟失其對(duì)撞機(jī)網(wǎng)格的問(wèn)題
- 基于OpenDrive格式的道路信息新系統(tǒng)
- 添加了新的地圖類喉镰,用于查詢有關(guān)道路布局和拓?fù)涞男畔?/li>
- 添加了在道路上查找最接近點(diǎn)的方法
- 添加了根據(jù)道路布局生成和迭代航點(diǎn)的方法
- 添加了OpenDrive解析器旅择,可將OpenDrive文件轉(zhuǎn)換為我們的地圖數(shù)據(jù)結(jié)構(gòu)
- 其他雜項(xiàng)改進(jìn)和修復(fù)
- 修復(fù)了單通道激光雷達(dá)崩潰(通過(guò)@cwecht)
- 固定的命令行參數(shù)
-carla-settings
無(wú)法加載絕對(duì)路徑(通過(guò)@harlowja) - 在啟動(dòng)模擬器時(shí),在命令行中添加了更改質(zhì)量級(jí)別的選項(xiàng)侣姆,
-quality-level=Low
- 添加了ROS橋測(cè)距消息(通過(guò)@ShepelIlya)
- 新的Docker教程
- 禁用紋理流生真,以避免在場(chǎng)景捕獲中未加載紋理的問(wèn)題
- 將場(chǎng)景捕獲相機(jī)的灰度系數(shù)調(diào)整為2.4
- 修復(fù)了生成車輛時(shí)模擬中的泄漏對(duì)象的問(wèn)題。現(xiàn)在當(dāng)銷毀一個(gè)Actor時(shí)捺宗,如果有必要汇歹,Pawn的控制器也會(huì)被銷毀
- 修復(fù)了平臺(tái)時(shí)間戳上的溢出。現(xiàn)在使用
double
- 升級(jí)@rpclib以修復(fù)客戶端退出速度過(guò)快時(shí)發(fā)生的崩潰(rpclib / PR#167)
- 將“ PythonClient”移至不推薦使用的文件夾中偿凭,以避免造成混淆
- 重構(gòu)傳感器相關(guān)代碼
- 用于傳感器的新插件系統(tǒng)产弹,可簡(jiǎn)化傳感器的添加,在#830上的微型教程
- 傳感器和串行器的編譯時(shí)調(diào)度程序
- 流媒體庫(kù)的改進(jìn)
- 添加了多流以同時(shí)流式傳輸?shù)蕉鄠€(gè)客戶端(由“ tick”消息使用)
- 消息盡可能重用分配的內(nèi)存
- 允許退訂流
- 固定客戶端接收交錯(cuò)的傳感器消息弯囊,但是如果連接速度太慢痰哨,則某些消息可以被丟棄
- 固定流客戶端無(wú)法在Windows中連接
- 修復(fù)了流客戶端在銷毀傳感器后不斷嘗試重新連接的問(wèn)題
- 重構(gòu)的客戶端C ++ API
- 盡可能釋放Python GIL,以避免阻塞
- 修復(fù)了在連接客戶端時(shí)關(guān)閉模擬器時(shí)的死鎖
- 修復(fù)了如果客戶端在某個(gè)時(shí)間點(diǎn)已連接匾嘱,則會(huì)在模擬器關(guān)閉時(shí)崩潰的問(wèn)題
- 現(xiàn)在斤斧,異步發(fā)送Set方法,這大大提高了客戶端的性能
- 車輛控制已緩存霎烙,如果未更改撬讽,則不會(huì)發(fā)送
- 析構(gòu)函數(shù)中的異常抑制
- 其他發(fā)展改進(jìn)
- 改進(jìn)的Linux Makefile蕊连,細(xì)粒度目標(biāo)可減少開發(fā)中的編譯時(shí)間
- “ setup.py”再次鏈接到“ libcarla_client.a”的解決方法(僅Linux)
- 添加了對(duì)“ .gtest”文件的支持,該文件的每一行在運(yùn)行
make check
目標(biāo)時(shí)作為參數(shù)傳遞給GTest可執(zhí)行文件 - Python雞蛋也被存檔在Jenkins上游昼,無(wú)需下載完整軟件包即可輕松獲取它們
- 添加了用于格式化UE4 C ++代碼的uncrustify配置文件