Add length, width and safety_margin to bicycle model ABC.

Add show function to display car with safety margin ellipsoid.
master
matssteinweg 2019-12-01 16:02:15 +01:00
parent 6ec93febd3
commit bbae14c519
1 changed files with 57 additions and 10 deletions

View File

@ -1,6 +1,11 @@
import numpy as np import numpy as np
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
import matplotlib.pyplot as plt
import matplotlib.patches as plt_patches
# Colors
CAR = '#F1C40F'
CAR_OUTLINE = '#B7950B'
######################### #########################
# Temporal State Vector # # Temporal State Vector #
@ -81,7 +86,7 @@ class SimpleSpatialState(SpatialState):
#################################### ####################################
class SpatialBicycleModel(ABC): class SpatialBicycleModel(ABC):
def __init__(self, reference_path): def __init__(self, reference_path, length, width):
""" """
Abstract Base Class for Spatial Reformulation of Bicycle Model. Abstract Base Class for Spatial Reformulation of Bicycle Model.
:param reference_path: reference path object to follow :param reference_path: reference path object to follow
@ -90,6 +95,11 @@ class SpatialBicycleModel(ABC):
# Precision # Precision
self.eps = 1e-12 self.eps = 1e-12
# Car Parameters
self.l = length
self.w = width
self.safety_margin = self._compute_safety_margin()
# Reference Path # Reference Path
self.reference_path = reference_path self.reference_path = reference_path
@ -192,6 +202,47 @@ class SpatialBicycleModel(ABC):
return state return state
def _compute_safety_margin(self):
"""
Compute safety margin for car if modeled by its center of gravity.
"""
# Model ellipsoid around the car
length = self.l / np.sqrt(2)
width = self.w / np.sqrt(2)
return length, width
def show(self):
"""
Display car on current axis.
"""
# Get car's center of gravity
cog = (self.temporal_state.x, self.temporal_state.y)
# Get current angle with respect to x-axis
yaw = np.rad2deg(self.temporal_state.psi)
# Draw rectangle
car = plt_patches.Rectangle(cog, width=self.l, height=self.w,
angle=yaw, facecolor=CAR, edgecolor=CAR_OUTLINE)
# Shift center rectangle to match center of the car
car.set_x(car.get_x() - (self.l/2 * np.cos(self.temporal_state.psi) -
self.w/2 * np.sin(self.temporal_state.psi)))
car.set_y(car.get_y() - (self.w/2 * np.cos(self.temporal_state.psi) +
self.l/2 * np.sin(self.temporal_state.psi)))
# Show safety margin
safety_margin = plt_patches.Ellipse(cog, width=2*self.safety_margin[0],
height=2*self.safety_margin[1],
angle=yaw,
fill=False, edgecolor=CAR)
# Add rectangle to current axis
ax = plt.gca()
ax.add_patch(safety_margin)
ax.add_patch(car)
@abstractmethod @abstractmethod
def get_spatial_derivatives(self, state, input, kappa): def get_spatial_derivatives(self, state, input, kappa):
pass pass
@ -206,21 +257,20 @@ class SpatialBicycleModel(ABC):
################# #################
class BicycleModel(SpatialBicycleModel): class BicycleModel(SpatialBicycleModel):
def __init__(self, reference_path, e_y, e_psi, t): def __init__(self, length, width, reference_path, e_y, e_psi, t):
""" """
Simplified Spatial Bicycle Model. Spatial Reformulation of Kinematic Simplified Spatial Bicycle Model. Spatial Reformulation of Kinematic
Bicycle Model. Uses Simplified Spatial State. Bicycle Model. Uses Simplified Spatial State.
:param length: length of the car in m
:param width: with of the car in m
:param reference_path: reference path model is supposed to follow :param reference_path: reference path model is supposed to follow
:param e_y: deviation from reference path | [m] :param e_y: deviation from reference path | [m]
:param e_psi: heading offset from reference path | [rad] :param e_psi: heading offset from reference path | [rad]
:param v: initial velocity | [m/s]
""" """
# Initialize base class # Initialize base class
super(BicycleModel, self).__init__(reference_path) super(BicycleModel, self).__init__(reference_path, length=length,
width=width)
# Constants
self.l = 0.06
# Initialize spatial state # Initialize spatial state
self.spatial_state = SimpleSpatialState(e_y, e_psi, t) self.spatial_state = SimpleSpatialState(e_y, e_psi, t)
@ -231,9 +281,6 @@ class BicycleModel(SpatialBicycleModel):
# Initialize temporal state # Initialize temporal state
self.temporal_state = self.s2t() self.temporal_state = self.s2t()
# Compute linear system matrices | Used for MPC
# self.A, self.B = self.linearize()
def s2t(self, reference_waypoint=None, reference_state=None): def s2t(self, reference_waypoint=None, reference_state=None):
""" """
Convert spatial state to temporal state. Either convert self.spatial_ Convert spatial state to temporal state. Either convert self.spatial_