F1TENTH Gym
Writing notes on how this gym works. Main thing is for how to formalize Head-to-Head Autonomous Racing.
Inspiration from F1TENTH Gym
Many of the things I have thought about is directly implemented in the F1TENTH Gym.
With the example code that they provide, the policy returns a speed
and steer
angle pair, which is then fed into the environment.
- This is slightly different from the acceleration formulation I’ve gone with.
Observation Space
obs
is a dictionary, with keys:
- For a single agent, poses_x will just be
[2.0]
for example - For multiple agents, poses_x will be
[2.0, 4.0]
for example
Action Space
control_inputs (np.ndarray (num_agents, 2)): control inputs of all agents,
- 1st column is desired steering angle
- 2nd column is desired velocity
Reward
reward is also of shape (num_agents)
- Their reward out of the box is just however the timestep is configured.
So with the configuration above, the step_reward would be 0.01
.
Abstractions that they do
- Steering speed instead of raw pedal acceleration
- However, compensated by setting controller params inside
config_example_map.yaml
throughvgain_min
andvgain_max
- However, compensated by setting controller params inside
- Discretized waypoints instead of continuous waypoints
- Vehicle dynamics using the Single Track Model
What happens when you add a second agent
- This can easily be configured!
But what you immediately notice is that there is no concept of DRS to encourage overtaking. When we test this out in real life, it also might become an issue.
- Solution: One way to overcome this is that when the vehicle behind is within a certain radius, then we increase its max speed, allowing it to go a little faster.
Observation Space
- You can have access to odometry from both vehicles, and lidar scans from both vehicles
- Although probably when you formulate the problem, you can likely see it work better.
Crashes
The gym will crash automatically if you spawn the vehicles on top of each other. Actually, whenever there is any collision, the environment just exits.
Basics
They choose the acceleration and steering angle for you based on a PID Tuning
Map Loading
You just specify a map, and they can give you a distance matrix using Scipy’s distance_transform_edt
- Head-to-Head-Autonomous-Racing/gym/f110_gym/envs/laser_models.py This is different from how the TUMFTM raceline repo does it, in which case it requires a centerline,
Then, the map can be used for scan matching, they do some sort of Raytracing, see the get_scan
function in the file.
Question: How do they check for collision into a wall?
In f110_env.py, I see the following termination logic
If I backtrace this code, it’s in base_classes.py
oh but this is collision between two vehicles, search for the check_collision
function.
So they don’t check for wall collision?? Actually they do, because it does terminate properly.
Control-f for self.collisions
self.in_collision seems to check for that? YES
so the check_ttc_jit
is a function defined in laser_models.py which does this.
Map
The map is loaded from a single black and white image. Similar to how this map is generated when you run slam_toolbox in ROS2. The unit of the resolution is m/pixel.
For example:
Waypoints
The set of waypoints is formalized as a 2D array of points.
The planner they have first loads the waypoints calling load_waypoints()
, which calls a np.loadtxt
function
We have our first insight: the trajectory is simply discretized over a set of xy coordinates.
The main loop that the car is running to plan + control is the following:
The planner makes a plan based on the xy-theta, and tlad and vgain?
- These are constant parameters:
There are also other params specified in config_example_map.yaml
.
So what does the planner.plan
function do?
- This is the naive default implementation. It is pretty much exactly what I do with Pure Pursuit
Vehicle Dynamics
You can specify the vehicle dynamics through this dictionary. They use the Single Track Model.