This tutorial demonstrates how are the motion primitives used in solving motion planning problems generated.
Before you proceed with this tutorial, make sure that
The configuration parameters related to our motion primitive generator are stored in generator_config.yaml. The configuration file contains the following parameters:
Note: Generating too sparse primitives (low branching factor) may restrict the search space such that no feasible solution can be found. On the other hand, generating too dense primitives (high branching factor) may dramatically inscrease the time of search. Thus striking a balance between diversity and efficiency is important here.
%load_ext autoreload
%autoreload 2
import matplotlib.pyplot as plt
import numpy as np
from MotionPrimitiveGenerator import MotionPrimitiveGenerator as MPG
# specify path to configuration file
path_file_config = "./generator_config.yaml"
# load configuration file
MPG.load_configuration(path_file_config)
The attributes of the states in a motion primitive are:
Here we only generate motion primitives with positive steering angles, as the other half can be easily obtained by mirroring them.
list_motion_primitives = MPG.generate_motion_primitives()
We plot the generated motion primitives:
fig = plt.figure(figsize=(12, 3))
ax = fig.gca()
rear_ax_dist = 1.42
for traj in list_motion_primitives:
list_x = [state.position[0] for state in traj.state_list]
list_y = [state.position[1] for state in traj.state_list]
plt.plot(list_x, list_y)
ax.set_xticks(np.arange(-5, 20, 0.5))
ax.set_yticks(np.arange(-5, 5., 0.5))
plt.axis('equal')
plt.grid(alpha=0.5)
plt.xlim((-1,11))
plt.ylim((-1,2))
plt.show()
As we only computed primitives that have a positive steering angle, we now mirror them to get the other half of the feasible primitives.
list_motion_primitives_mirrored = MPG.create_mirrored_primitives(list_motion_primitives)
print("Total number of primitives (mirrored included): ", len(list_motion_primitives_mirrored))
We now plot the final generated motion primitives.
fig = plt.figure(figsize=(12, 5))
ax = fig.gca()
for traj in list_motion_primitives_mirrored:
list_x = [state.position[0] for state in traj.state_list]
list_y = [state.position[1] for state in traj.state_list]
plt.plot(list_x, list_y)
ax.set_xticks(np.arange(-5, 20, 0.5))
ax.set_yticks(np.arange(-5, 5., 0.5))
plt.axis('equal')
plt.grid(alpha=0.5)
plt.xlim((-1,11))
plt.ylim((-2,2))
plt.show()
We can inspect the average branching factor of the generated primitives to have a rough idea how many successors a given motion primitive can have.
branching_factor_average = MPG.compute_branching_factor(list_motion_primitives_mirrored)
print("Average branching factor of primitives: ", branching_factor_average)
We create some sample trajectories with the motion primitives that we have just generated.
MPG.generate_sample_trajectories(list_motion_primitives_mirrored)
We save the generated motion primitves to XML files, which are output tothe directory specified in the configuration file.
file_name = MPG.save_motion_primitives(list_motion_primitives_mirrored)
from SMP.maneuver_automaton.maneuver_automaton import ManeuverAutomaton
ManeuverAutomaton.create_pickle(file_motion_primitive=file_name, dir_save=MPG.parameter.dir_output)