Python API入门:连接Carla客户端、获取世界对象、加载地图、设置天气
好,咱们正式开始动手了。上一章我们把Carla环境搭好,现在该写代码了。说实话,我第一次接触Carla的Python API时,觉得这东西挺绕的——又是客户端又是世界,还有一堆回调。但用顺手了你会发现,它的设计其实很清晰。
这一章,我们只做四件事:连上Carla、拿到世界、换个地图、调个天气。别小看这四步,它们是所有仿真脚本的基石。
2.1 连接Carla客户端
先说说客户端这个概念。Carla采用C/S架构,服务端就是那个CarlaUE4.exe(或者Linux下的sh脚本),客户端就是我们写的Python脚本。两者通过网络通信。
连接代码很简单:
import carla
# 创建客户端,默认地址是localhost:2000
client = carla.Client('localhost', 2000)
# 设置超时时间,单位秒
client.set_timeout(10.0)
print('客户端已连接')
这里有个坑,我一开始就踩过——超时时间。如果你不设timeout,默认是无穷大,脚本会卡死在那里。我建议至少设5秒以上,因为Carla启动后加载地图需要时间,尤其是大场景。
2.2 获取世界对象
连上客户端后,下一步就是获取世界(World)。世界是Carla里最核心的对象,它管理着地图、车辆、行人、传感器、天气……几乎所有东西。
# 获取当前世界
world = client.get_world()
print(f'当前地图: {world.get_map().name}')
拿到world对象后,你可以做很多事情。比如获取所有参与者(actors)、设置天气、获取地图信息等等。我个人习惯把world保存成一个全局变量,后面所有操作都基于它。
为什么会这样设计?因为Carla把整个仿真环境抽象成了一个“世界”,你想想看,现实世界中你要改变天气、移动物体,不也是通过某种“世界规则”来操作的吗?
2.3 加载地图
Carla自带了好几个地图,比如Town01到Town07,还有最新的Town10。每个地图的布局、道路复杂度都不一样。
加载地图有两种方式:
- 通过地图名称加载:直接指定地图名
- 通过地图文件路径加载:加载自定义地图
先看第一种:
# 加载Town03地图
world = client.load_world('Town03')
# 等待地图加载完成
world.wait_for_tick()
print('地图已切换为Town03')
这里有个细节——wait_for_tick()。Carla的仿真世界是按“tick”推进的,每个tick相当于一帧。加载地图后,需要等一个tick让世界完成初始化。我曾经没加这行,结果后续操作报了一堆空指针错误。
第二种方式用于加载你自己用RoadRunner导出的地图:
# 加载自定义地图(假设文件在Carla的Content目录下)
client.load_world('/Game/Carla/Maps/MyCustomMap')
client.get_available_maps() 列出所有地图。我经常用这个命令来检查新导入的地图是否被识别。
2.4 设置天气
天气系统是Carla的一大亮点。你可以控制阳光、雨、雾、云层、风速……甚至能模拟沙尘暴(虽然我没试过)。
设置天气有两种方式:
方式一:使用预设天气
Carla提供了一些预设的天气参数,比如晴天、雨天、夜晚等:
# 获取世界对象
world = client.get_world()
# 设置天气为晴天
weather = carla.WeatherParameters.ClearNoon
world.set_weather(weather)
print('天气已设置为晴天')
预设天气有这些:
| 预设名称 | 说明 |
|---|---|
| ClearNoon | 晴天正午 |
| CloudyNoon | 多云正午 |
| WetNoon | 雨后正午 |
| WetCloudyNoon | 雨后多云正午 |
| MidRainyNoon | 中雨正午 |
| HardRainNoon | 大雨正午 |
| SoftRainNoon | 小雨正午 |
| ClearSunset | 晴天黄昏 |
| CloudySunset | 多云黄昏 |
| WetSunset | 雨后黄昏 |
| WetCloudySunset | 雨后多云黄昏 |
| MidRainySunset | 中雨黄昏 |
| HardRainSunset | 大雨黄昏 |
| SoftRainSunset | 小雨黄昏 |
方式二:自定义天气参数
预设天气不够用?那就自己调参数。每个参数都有取值范围:
# 自定义天气:大雾+小雨
weather = carla.WeatherParameters(
cloudiness=80.0, # 云量 0-100
precipitation=30.0, # 降雨量 0-100
precipitation_deposits=50.0, # 路面积水 0-100
wind_intensity=20.0, # 风速 0-100
sun_azimuth_angle=180.0, # 太阳方位角
sun_altitude_angle=45.0, # 太阳高度角
fog_density=70.0, # 雾浓度 0-100
fog_distance=10.0, # 雾的可见距离
fog_falloff=1.0, # 雾衰减
wetness=60.0 # 路面湿润度 0-100
)
world.set_weather(weather)
print('自定义天气已应用')
嗯,这里要注意——参数不是随便填的。比如fog_distance设得太小,你会什么都看不见。我刚开始调的时候,把雾浓度设到100,结果整个场景白茫茫一片,连车在哪都找不到。
2.5 完整示例:一条龙搞定
把上面所有步骤串起来,就是一个完整的入门脚本:
import carla
import time
def main():
# 1. 连接客户端
client = carla.Client('localhost', 2000)
client.set_timeout(10.0)
# 2. 加载地图
world = client.load_world('Town03')
world.wait_for_tick()
# 3. 设置天气(自定义:多云+微风)
weather = carla.WeatherParameters(
cloudiness=60.0,
precipitation=0.0,
wind_intensity=10.0
)
world.set_weather(weather)
# 4. 打印当前状态
print(f'地图: {world.get_map().name}')
print(f'天气: 云量{weather.cloudiness}%, 风速{weather.wind_intensity}')
# 保持仿真运行一会儿
for i in range(10):
world.tick()
time.sleep(0.1)
print('仿真运行结束')
if __name__ == '__main__':
main()
这个脚本你直接复制就能跑。它会加载Town03,设置多云天气,然后跑10个tick(大约1秒)。
2.6 本章小结
这一章我们做了四件事:
- 连接客户端:
carla.Client()+set_timeout() - 获取世界:
client.get_world()或client.load_world() - 加载地图:指定地图名,别忘了
wait_for_tick() - 设置天气:预设或自定义参数
说白了,这就是Carla仿真的“开机四步”。后面所有章节,都会基于这四步展开。你想想看,不管是加车、加传感器、还是做交通流,都得先有世界和地图对吧?
下一章,我们开始往世界里放车——生成车辆、控制车辆、获取车辆状态。那才是真正好玩的部分。