Donkey模拟器
Donkey Gym项目是一个OpenAI Gym的包装器,用于连接Self Driving Sandbox Donkey模拟器(sdsandbox
)。
该模拟器基于Unity游戏平台构建,使用其内部的物理和图形系统,并连接到一个Donkey Python进程,以使用我们训练好的模型来控制模拟的Donkey车。
我的虚拟Donkey
根据您的目标,有许多使用模拟器的方式。您可以将模拟器视为虚拟硬件,使用它来了解和使用标准的Donkeycar驱动/训练/测试循环。您将使用与实际机器人相同的命令来收集数据、驾驶和训练。我们将首先介绍这种用法。
安装
- 从Donkey Gym Release下载并解压适用于您的主机平台的模拟器。
- 将模拟器放置在您喜欢的位置。以本示例为例,将其放置在~/projects/DonkeySimLinux目录下。根据平台的不同,您的目录名称将不同。
- 完成所有步骤以在主机PC上安装Donkey。
- 设置DonkeyGym:
cd ~/projects
git clone https://github.com/tawnkramer/gym-donkeycar
cd gym-donkeycar
conda activate donkey
pip install -e .[gym-donkeycar]
- 您可以使用现有的
~/mycar
Donkey应用程序,或者开始一个新的应用程序。在这里,我们将从头开始:
donkey createcar --path ~/mysim
cd ~/mysim
- 编辑您的
myconfig.py
文件以启用Donkey Gym模拟器包装器,请替换<user-name>
和路径的其他部分:
DONKEY_GYM = True
DONKEY_SIM_PATH = "/home/<user-name>/projects/DonkeySimLinux/donkey_sim.x86_64"
DONKEY_GYM_ENV_NAME = "donkey-generated-track-v0"
注意:根据平台和用户的不同,可执行文件的路径会有所不同。
- Windows: DonkeySimWin/donkey_sim.exe
- Mac OS: DonkeySimMac/donkey_sim.app/Contents/MacOS/donkey_sim
- Linux: DonkeySimLinux/donkey_sim.x86_64
驾驶
您可以使用所有常规的 manage.py
命令来进行操作。例如:
python manage.py drive
这将启动模拟器并自动连接到它。默认情况下,您将拥有一个用于控制Donkey的Web界面。请访问 http://localhost:8887/drive 查看控制页面。
在Ubuntu Linux上,您可以连接您选择的游戏手柄。如果它被挂载为 /dev/input/js0
,那么它很有可能可以工作。修改 myconfig.py
指示您的游戏手柄型号,并使用 --js
参数来运行。
python manage.py drive --js
在您驾驶的过程中,这将像往常一样在您的数据目录中创建一个记录的数据集。
训练
您不需要将数据进行 rsync,因为它已经被记录并保存在本地。您可以像往常一样进行训练:
donkey train --tub ./data --model models/mypilot.h5
测试
您可以像往常一样使用该模型:
python manage.py drive --model models/mypilot.h5
然后导航到Web控制页面。将“模式和驾驶员”设置为“本地驾驶员(d)”。汽车应该开始行驶。
样本驾驶数据
这是一些示例驾驶数据,可帮助您入门。下载此文件 并将其解压缩到您的数据目录中。这应该训练出一个速度较慢但稳定的驾驶程序。
API
以下是与模拟服务器通信的API信息。创建一个TCP客户端并连接到模拟器正在运行的主机上的9091端口。服务器发送和接收UTF-8编码的JSON数据包。每个消息必须有一个“msg_type”字段。模拟器会在每个JSON数据包的末尾添加换行符以作为终止符。当向服务器发送消息时,您不必在每个数据包末尾添加换行符。但是,如果发送的消息过多,可能会出现问题。如果遇到问题,请检查播放器日志文件以查找JSON解析错误。
获取协议版本
客户端=>模拟器。请求协议的版本。将帮助了解这些消息何时发生更改。
字段:无
示例:
{
"msg_type" : "get_protocol_version"
}
协议版本
模拟器=>客户端. 回复协议的版本。当前版本为2。
Fields:
- version : string integer
Example:
{
"msg_type" : "protocol_version",
"version" : "2",
}
场景选择准备就绪
模拟器=>客户端。当菜单场景加载完成时,将发送此消息。在此之后,模拟器可以响应场景加载消息。(仅菜单)
字段:无
示例:
{
"msg_type" : "scene_selection_ready"
}
获取场景名称
客户端=>模拟器。询问可以加载的场景的名称。(仅菜单)
字段:无
示例:
{
"msg_type" : "get_scene_names"
}
场景名称
模拟器=>客户端。模拟器将回复一个场景名称列表。
字段:
- scene_names:场景名称数组
示例:
{
"msg_type" : "scene_names"
"scene_names" : [ "generated_road", "warehouse", "sparkfun_avc". "generated_track" ]
}
加载场景
客户端=>模拟器。请求模拟器从菜单屏幕加载其中一个场景。(仅菜单)
字段:
scene_name:generated_road | warehouse | sparkfun_avc | generated_track(或模拟器从get_scene_names返回的列表)
示例:
{
"msg_type" : "load_scene",
"scene_name" : "generated_track"
}
场景加载完成
模拟器=>客户端。一旦场景加载完成,你将收到以下回复:
{
"msg_type" : "scene_loaded"
}
车辆加载完成
模拟器=>客户端。一旦模拟器完成加载你的车辆,它将发送此消息。在场景加载完成后,当有活动的客户端连接时,车辆将自动加载给你。或者客户端建立连接。
字段:无
示例:
{
"msg_type" : "car_loaded"
}
车辆配置
客户端=>模拟器。一旦加载完成,你可以配置车辆的可视细节(仅场景)
字段:
- body_style:donkey | bare | car01 | cybertruck | f1
- body_r:0-255之间的整数字符串值
- body_g:0-255之间的整数字符串值
- body_b:0-255之间的整数字符串值
- car_name:要在车辆上显示的字符串值车辆名称。多行可接受换行符。
- font_size:10-100之间的整数字符串值,用于设置车辆名称文本的大小
示例:
{
"msg_type" : "car_config",
"body_style" : "car01",
"body_r" : "128",
"body_g" : "0",
"body_b" : "255",
"car_name" : "Your Name",
"font_size" : "100"
}
摄像头配置
客户端=>仿真器。一旦场景加载完成,您可以配置汽车相机传感器的详细信息。
字段:
- fov:浮点数字符串,范围在10到200之间。设置相机的视野角度。
- fish_eye_x:浮点数字符串,范围在0到1之间。在x轴上引起畸变变形。
- fish_eye_y:浮点数字符串,范围在0到1之间。在y轴上引起畸变变形。
- img_w:整数字符串,范围在16到512之间。设置相机传感器图像的宽度。
- img_h:整数字符串,范围在16到512之间。设置相机传感器图像的高度。
- img_d:整数字符串,值为1或3。设置相机传感器图像的深度。在值为1的情况下,您将获得3个通道,但所有通道都是相同的,模拟器上进行了灰度转换。
- img_enc:图像数据的编码格式 JPG | PNG | TGA
- offset_x:浮点数字符串。将相机在左右轴上移动。
- offset_y:浮点数字符串。将相机上下移动。
- offset_z:浮点数字符串。将相机前后移动。
- rot_x:浮点数字符串。以度为单位。围绕X轴旋转相机。
示例:
{
"msg_type" : "cam_config",
"fov" : "150",
"fish_eye_x" : "1.0",
"fish_eye_y" : "1.0",
"img_w" : "255",
"img_h" : "255",
"img_d" : "1",
"img_enc" : "PNG",
"offset_x" : "0.0",
"offset_y" : "3.0",
"offset_z" : "0.0",
"rot_x" : "90.0"
}
注意: 您可以通过将msg_type更改为"cam_config_b"来添加另一个相机。
控制车辆
客户端=>仿真器。控制油门和转向。
字段:
- steering:浮点数字符串,范围在-1到1之间。映射到完全向左或向右,与中心相差16度。
- throttle:浮点数字符串,范围在-1到1之间。将扭矩完全施加到前进或倒车的车轮。
- brake:浮点数字符串,范围在0到1之间。
示例:
{
"msg_type" : "control",
"steering" : "0.0",
"throttle" : "0.3",
"brake" : "0.0"
}
遥测数据
仿真器=>客户端。仿真器发送此消息,包含相机图像和有关车辆状态的详细信息。这些消息以仿真器中设置的固定速率发送,通常约为20Hz。
字段:
- steering_angle:上次应用的转向角度。为什么不直接使用"steering",我不知道。
- throttle:上次应用的油门。
- speed:线速度的大小。
- image:二进制图像的BinHex编码。使用PIL.Image.open(BytesIO(base64.b64decode(imgString)))来打开图像。
- imageb:(可选)第二个相机的图像,与上述相同。
- lidar:(可选)激光雷达点的列表,格式如下:{d: 距离物体的距离, rx: 射线X轴旋转, ry: 射线Y轴旋转}
- hit:最后撞击物体的名称。如果没有撞击物体,则为None。
- accel_x:车辆的x轴加速度。
- accel_y:车辆的y轴加速度。
- accel_z:车辆的z轴加速度。
- gyro_x:x轴陀螺加速度。
- gyro_y:y轴陀螺加速度。
- gyro_z:z轴陀螺加速度。
- gyro_w:w轴陀螺加速度。
- pitch:车辆的俯仰角(以度为单位)。
- roll:车辆的横滚角(以度为单位)。
- yaw:车辆的偏航角(以度为单位)。
- activeNode:在赛道上的进度(目前与多车不正常工作)。
- totalNodes:赛道上的节点数。
- pos_x:(仅用于训练)车辆的世界坐标x。
- pos_y:(仅用于训练)车辆的世界坐标y。
- pos_z:(仅用于训练)车辆的世界坐标z。
- vel_x:(仅用于训练)车辆的x轴速度。
- vel_y:(仅用于训练)车辆的y轴速度。
- vel_z:(仅用于训练)车辆的z轴速度。
- cte:(仅用于训练)横向误差。车辆到最右车道中心线或赛道中心线的距离(取决于赛道)。
示例:
{
"msg_type" : "telemetry",
"steering_angle" : "0.0",
"throttle" : "0.0",
"speed" : "1.0",
"image" : "0x123...",
"hit" : "None",
"pos_x" : "0.0",
"pos_y" : "0.0",
"pos_z" : "0.0",
"accel_x" : "0.0",
"accel_y" : "0.0",
"accel_z" : "0.0",
"gyro_x" : "0.0",
"gyro_y" : "0.0",
"gyro_z" : "0.0",
"gyro_w" : "0.0",
"pitch" : "0.0",
"roll" : "0.0",
"yaw" : "0.0",
"activeNode" : "5",
"totalNodes" : "26",
"cte" : "0.5"
}
重置车辆
客户端=>仿真器。将车辆返回到起点。
字段:无
示例:
{
"msg_type" : "reset_car"
}
设置车辆位置
客户端=>模拟器。将车辆移动到指定位置(仅用于训练)
字段:
- pos_x:x世界坐标。
- pos_y:y世界坐标。
- pos_z:z世界坐标。
- qx:(可选)四元数x分量。
- qy:(可选)四元数y分量。
- qz:(可选)四元数z分量。
- qw:(可选)四元数w分量。
示例:
{
"msg_type" : "set_position",
"pos_x" : "0.0",
"pos_y" : "0.0",
"pos_z" : "0.0"
}
或者:
{
"msg_type" : "set_position",
"pos_x" : "0.0",
"pos_y" : "0.0",
"pos_z" : "0.0",
"qx" : "0.0",
"qy" : "0.2",
"qz" : "0.0",
"qw" : "1.0"
}
获取节点位置和旋转
客户端=>模拟器。请求一个node_position数据包
字段:
- index:节点索引
示例:
{
"msg_type": "node_position",
"index": "0"
}
节点位置和旋转
模拟器=>客户端。node_position数据包(在发送node_position数据包后收到)
字段:
- pos_x:x世界坐标。
- pos_y:y世界坐标。
- pos_z:z世界坐标。
- qx:(可选)四元数x分量。
- qy:(可选)四元数y分量。
- qz:(可选)四元数z分量。
- qw:(可选)四元数w分量。
示例:
{
"msg_type": "node_position",
"Qx": "0",
"Qy": "0",
"Qz": "0",
"Qw": "1",
"pos_x": "0",
"pos_y": "0",
"pos_z": "0"
}
退出场景
客户端=>模拟器。离开场景,返回主菜单屏幕。
字段:无
示例:
{
"msg_type" : "exit_scene"
}
退出应用
客户端=>模拟器。关闭模拟器应用程序(仅限菜单)。
字段:无
示例:
{
"msg_type" : "quit_app"
}