Examples.RaceCarModel ​
Race car of the dymos race car example (P. de Buck's lap simulation, https://openmdao.github.io/dymos/examples/racecar/racecar.html), in the track frame and in the time domain: a single-track vehicle with four tyres, driven by the steering angle
Coordinates ​
The position is given relative to the centerline of the track: s is the arc length along the centerline, n the lateral offset from it (positive to the left) and alpha the heading of the car relative to the tangent of the centerline. V is the speed, lambda the body slip angle (the angle from the velocity to the body axis), omega the yaw rate, and ax, ay the filtered longitudinal and lateral accelerations through which the load transfer between the tyres acts (time constants tau_x, tau_y). With
dymos integrates the same equations over s (dividing every rate by s.
Tyres and loads ​
The normal loads follow from the static weight distribution, the longitudinal and lateral load transfer (h, chi) and the downforce CoP. The longitudinal tyre forces are set directly by the controls: the throttle puts beta between the front and the rear. The lateral tyre forces are linear in the slip angle of each tyre with the stiffness k_lambda times the normal load. dymos has one signed thrust control split into a throttle and a brake by its sign; here the two are separate nonnegative controls, which gives the same forces without the kink at zero, and thrust is their difference. The tyre adherence c_fl, ..., c_rr is the friction ellipse power the tractive power. The controller constrains the power and, in place of the ellipse of each tyre, the facets adh_fl, ..., adh_rr of a regular octagon inscribed in it, with two vertices on the axes so that pure braking and pure cornering keep the whole adherence and combined braking and cornering lose at most 8 % of it. The lateral coordinate of the polygon is linear in the slip angle of the tyre, and that is the point: the ellipse spans a slip angle of only RaceCarSpatialModel). The ellipse written as a smoothed norm, whose gradient has unit length away from the origin, fails from the first ticks for the same reason: the car starts with zero slip, where that gradient vanishes too. The facets have constant gradients and the iterations converge on them. The ellipse itself is enforced by ACADOSMPCRaceCarSpatialExample through the convex-over-nonlinear constraint module of acados (nl_convex_inner/nl_convex_outer), which adds the curvature of the ellipse to the QP: the iterations then keep the tyres within a few percent of it.
Track ​
The centerline is the sequence of straight segments and circular arcs of the track, given by the curvature and the length of each segment (seg_curvature, seg_length; see racetrack_curvatures). The curvature at the arc length s is the sum over the segments of what each contributes, one for a segment the arc length has entered and zero for one it has left, blended with the cubic blend metres at either end so that s_lap, which wraps at their total length, so that any number of laps is driven on the tables of one; the first and the last segment must be straights longer than the blend, as they are on the oval, for the curvature to be zero on both sides of the wrap. The two tables are online parameters of the controller, as the path is in OmniRobotPathModel.
The parameter values are the ones of the dymos example.
This partial component holds the parameters, the variables, the output connectors and every algebraic relation, so that RaceCarPlant (the car in the time domain) and RaceCarSpatialModel (the car with the arc length as the independent variable) share them and differ in the derivatives alone.
Usage ​
MPCComponents.Examples.RaceCarModel(M=800.0, a=1.8, b=1.6, tw=0.73, Iz=450.0, h=0.3, chi=0.5, CoP=1.6, beta=0.62, k_lambda=44.0, mu0_x=1.68, mu0_y=1.68, k_mu=0.0, tau_x=0.2, tau_y=0.2, rho=1.2, CdA=2.0, ClA=4.0, g=9.8, P_max=960000.0, s0=0.0, n0=0.0, alpha0=0.0, V0=20.0, delta0=0.0, throttle0=0.0, brake0=0.0, blend=racetrack_blend(), seg_curvature=racetrack_curvatures(), seg_length=racetrack_lengths(), N0_f=M * g / 2 * b / (a + b), N0_r=M * g / 2 * a / (a + b), facet_cos=friction_polygon_cos(), facet_sin=friction_polygon_sin(), adh_max=friction_polygon_bound())
Parameters: ​
| Name | Description | Units | Default value |
|---|---|---|---|
nseg | Number of segments of the track (derived) | – | racetrack_segment_count() |
nbound | Number of segment boundaries of the track (derived) | – | nseg + 1 |
nfacet | Number of facets of the polygon inscribed in the friction ellipse (derived) | – | friction_polygon_facets() |
M | Mass | – | 800.0 |
a | Distance from the centre of gravity to the front axle | – | 1.8 |
b | Distance from the centre of gravity to the rear axle | – | 1.6 |
tw | Half track width | – | 0.73 |
Iz | Yaw inertia | – | 450.0 |
h | Height of the centre of gravity | – | 0.3 |
chi | Roll stiffness distribution (share of the lateral load transfer taken by the front axle) | – | 0.5 |
CoP | Distance from the centre of pressure to the front axle | – | 1.6 |
beta | Brake bias (share of the braking force on the front axle) | – | 0.62 |
k_lambda | Lateral tyre stiffness per unit normal load | – | 44.0 |
mu0_x | Longitudinal friction coefficient at the static load | – | 1.68 |
mu0_y | Lateral friction coefficient at the static load | – | 1.68 |
k_mu | Load sensitivity of the friction coefficient | – | 0.0 |
tau_x | Time constant of the longitudinal load transfer | – | 0.2 |
tau_y | Time constant of the lateral load transfer | – | 0.2 |
rho | Air density | – | 1.2 |
CdA | Drag coefficient times frontal area | – | 2.0 |
ClA | Downforce coefficient times wing area | – | 4.0 |
g | Gravitational acceleration | – | 9.8 |
P_max | Engine power limit, the scale of the normalized tractive power power_norm | – | 960000.0 |
s0 | Arc length at the start | – | 0.0 |
n0 | Lateral offset at the start | – | 0.0 |
alpha0 | Relative heading at the start | – | 0.0 |
V0 | Speed at the start (positive: the speed divides the slip angle dynamics) | – | 20.0 |
delta0 | Steering angle at the start | – | 0.0 |
throttle0 | Throttle at the start | – | 0.0 |
brake0 | Brake at the start | – | 0.0 |
blend | Arc length over which the curvature blends from one segment to the next | – | racetrack_blend() |
seg_curvature | Curvature of each segment of the track; an online parameter of the controller | – | racetrack_curvatures() |
seg_length | Length of each segment of the track; an online parameter of the controller | – | racetrack_lengths() |
Connectors ​
delta_rate- This connector represents a real signal as an input to a component (RealInput)throttle_rate- This connector represents a real signal as an input to a component (RealInput)brake_rate- This connector represents a real signal as an input to a component (RealInput)s_out- This connector represents a real signal as an output from a component (RealOutput)n_out- This connector represents a real signal as an output from a component (RealOutput)alpha_out- This connector represents a real signal as an output from a component (RealOutput)V_out- This connector represents a real signal as an output from a component (RealOutput)lambda_out- This connector represents a real signal as an output from a component (RealOutput)omega_out- This connector represents a real signal as an output from a component (RealOutput)ax_out- This connector represents a real signal as an output from a component (RealOutput)ay_out- This connector represents a real signal as an output from a component (RealOutput)delta_out- This connector represents a real signal as an output from a component (RealOutput)throttle_out- This connector represents a real signal as an output from a component (RealOutput)brake_out- This connector represents a real signal as an output from a component (RealOutput)seg_curvature_out- This connector represents a real signal as an output from a component (RealOutput)seg_length_out- This connector represents a real signal as an output from a component (RealOutput)
Variables ​
| Name | Description | Units |
|---|---|---|
s | Arc length along the centerline | – |
s_lap | Arc length within the lap, at which the track tables are evaluated | – |
n | Lateral offset from the centerline | – |
alpha | Heading relative to the centerline | – |
V | Speed | – |
lambda | Body slip angle | – |
omega | Yaw rate | – |
ax | Longitudinal acceleration (filtered) | – |
ay | Lateral acceleration (filtered) | – |
delta | Steering angle | – |
throttle | Throttle: the rear longitudinal tyre force as a fraction of the weight (nonnegative) | – |
brake | Brake: the braking force as a fraction of the weight (nonnegative) | – |
seg_start | Arc length at which each segment starts (derived from the lengths) | – |
t_in | Fraction of the blend into each segment covered, clipped to [0, 1] | – |
t_out | Fraction of the blend out of each segment covered, clipped to [0, 1] | – |
kappa_k | Curvature contributed by the first k segments | – |
kappa | Curvature of the centerline at the arc length s | – |
sdot | Rate of progress along the centerline | – |
downforce | Downforce | – |
drag | Aerodynamic drag | – |
N_fl | Normal load of the front-left tyre | – |
N_fr | Normal load of the front-right tyre | – |
N_rl | Normal load of the rear-left tyre | – |
N_rr | Normal load of the rear-right tyre | – |
S_f | Longitudinal force of one front tyre | – |
S_r | Longitudinal force of one rear tyre | – |
F_fl | Lateral force of the front-left tyre | – |
F_fr | Lateral force of the front-right tyre | – |
F_rl | Lateral force of the rear-left tyre | – |
F_rr | Lateral force of the rear-right tyre | – |
ndot | Rate of the lateral offset | – |
alphadot | Rate of the relative heading | – |
Vdot | Acceleration along the body axis | – |
lambdadot | Rate of the body slip angle | – |
omegadot | Yaw acceleration | – |
axdot | Rate of the filtered longitudinal acceleration | – |
aydot | Rate of the filtered lateral acceleration | – |
power | Tractive power | – |
power_norm | Tractive power relative to the engine power limit (one at the limit) | – |
thrust | Throttle minus brake, the signed thrust of dymos | – |
c_fl | Friction ellipse of the front-left tyre (one at the limit of adherence) | – |
c_fr | Friction ellipse of the front-right tyre | – |
c_rl | Friction ellipse of the rear-left tyre | – |
c_rr | Friction ellipse of the rear-right tyre | – |
sx_fl | Longitudinal tyre force of the front-left tyre relative to its limit of adherence | – |
sx_fr | Longitudinal tyre force of the front-right tyre relative to its limit of adherence | – |
sx_rl | Longitudinal tyre force of the rear-left tyre relative to its limit of adherence | – |
sx_rr | Longitudinal tyre force of the rear-right tyre relative to its limit of adherence | – |
sy_fl | Lateral tyre force of the front-left tyre relative to its limit of adherence, linear in the slip angle | – |
sy_fr | Lateral tyre force of the front-right tyre relative to its limit of adherence | – |
sy_rl | Lateral tyre force of the rear-left tyre relative to its limit of adherence | – |
sy_rr | Lateral tyre force of the rear-right tyre relative to its limit of adherence | – |
adh_fl | Facets of the octagon inscribed in the friction ellipse of the front-left tyre, each at most adh_max: the form the controller constrains | – |
adh_fr | Facets of the octagon inscribed in the friction ellipse of the front-right tyre | – |
adh_rl | Facets of the octagon inscribed in the friction ellipse of the rear-left tyre | – |
adh_rr | Facets of the octagon inscribed in the friction ellipse of the rear-right tyre | – |
Source ​
"""
Race car of the dymos race car example (P. de Buck's lap simulation,
https://openmdao.github.io/dymos/examples/racecar/racecar.html), in the track frame and in the time
domain: a single-track vehicle with four tyres, driven by the steering angle ``\\delta``, the throttle
and the brake.
# Coordinates
The position is given relative to the centerline of the track: `s` is the arc length along the
centerline, `n` the lateral offset from it (positive to the left) and `alpha` the heading of the car
relative to the tangent of the centerline. `V` is the speed, `lambda` the body slip angle (the angle
from the velocity to the body axis), `omega` the yaw rate, and `ax`, `ay` the filtered longitudinal and
lateral accelerations through which the load transfer between the tyres acts (time constants `tau_x`,
`tau_y`). With ``\\kappa(s)`` the curvature of the centerline,
```math
\\dot s = \\frac{V \\cos(\\alpha - \\lambda)}{1 - n \\kappa(s)}, \\qquad
\\dot n = V \\sin(\\alpha - \\lambda), \\qquad
\\dot\\alpha = \\omega - \\kappa(s) \\dot s.
```
dymos integrates the same equations over `s` (dividing every rate by ``\\dot s``) because its
collocation nodes are then fixed in space; a receding-horizon controller runs on a clock and integrates
over time, so the model is kept in the time domain and the curvature is evaluated at the state `s`.
# Tyres and loads
The normal loads follow from the static weight distribution, the longitudinal and lateral load
transfer (`h`, `chi`) and the downforce ``\\tfrac{1}{2} \\rho C_l A V^2`` split at the centre of
pressure `CoP`. The longitudinal tyre forces are set directly by the controls: the throttle puts
``\\tfrac{1}{2} M g \\, \\mathrm{throttle}`` on each rear tyre, the brake puts ``M g \\, \\mathrm{brake}``
on the car split by the brake bias `beta` between the front and the rear. The lateral tyre forces are
linear in the slip angle of each tyre with the stiffness `k_lambda` times the normal load. dymos has
one signed `thrust` control split into a throttle and a brake by its sign; here the two are separate
nonnegative controls, which gives the same forces without the kink at zero, and `thrust` is their
difference. The tyre adherence `c_fl`, ..., `c_rr` is the friction ellipse
``(S / \\mu_x N)^2 + (F / \\mu_y N)^2`` of each tyre and `power` the tractive power. The controller
constrains the power and, in place of the ellipse of each tyre, the facets `adh_fl`, ..., `adh_rr` of a
regular octagon inscribed in it, with two vertices on the axes so that pure braking and pure cornering
keep the whole adherence and combined braking and cornering lose at most 8 % of it. The lateral
coordinate of the polygon is linear in the slip angle of the tyre, and that is the point: the ellipse
spans a slip angle of only ``\\mu_y / k_\\lambda \\approx 0.04`` rad, and it is quadratic in it, so its
linearization at a small slip angle carries no information about the lateral force: run to convergence
the iterations stall on it, and capped at a few iterations per tick they let the tyres exceed it by a
factor of 3 to 4 in the corners, with either prediction model (the time-domain one and
`RaceCarSpatialModel`). The ellipse written as a smoothed norm, whose gradient has unit length away
from the origin, fails from the first ticks for the same reason: the car starts with zero slip, where
that gradient vanishes too. The facets have constant gradients and the iterations converge on them.
The ellipse itself is enforced by `ACADOSMPCRaceCarSpatialExample` through the convex-over-nonlinear
constraint module of acados (`nl_convex_inner`/`nl_convex_outer`), which adds the curvature of the
ellipse to the QP: the iterations then keep the tyres within a few percent of it.
# Track
The centerline is the sequence of straight segments and circular arcs of the track, given by the
curvature and the length of each segment (`seg_curvature`, `seg_length`; see `racetrack_curvatures`).
The curvature at the arc length `s` is the sum over the segments of what each contributes, one for a
segment the arc length has entered and zero for one it has left, blended with the cubic
``3t^2 - 2t^3`` over `blend` metres at either end so that ``\\kappa(s)`` and its derivative are
continuous (the sequential quadratic programming of the controller relies on a continuous Jacobian);
the blend is symmetric, so the heading turned through a segment stays exactly its curvature times its
length. The tables describe one lap and are evaluated at the arc length within the lap, `s_lap`, which
wraps at their total length, so that any number of laps is driven on the tables of one; the first and
the last segment must be straights longer than the blend, as they are on the oval, for the curvature to
be zero on both sides of the wrap. The two tables are online parameters of the controller, as the path
is in `OmniRobotPathModel`.
The parameter values are the ones of the dymos example.
This partial component holds the parameters, the variables, the output connectors and every algebraic
relation, so that `RaceCarPlant` (the car in the time domain) and `RaceCarSpatialModel` (the car with
the arc length as the independent variable) share them and differ in the derivatives alone.
"""
partial component RaceCarModel
"Rate of the steering angle"
delta_rate = RealInput() {}
"Rate of the throttle"
throttle_rate = RealInput() {}
"Rate of the brake"
brake_rate = RealInput() {}
"Arc length along the centerline"
s_out = RealOutput() {}
"Lateral offset from the centerline, positive to the left"
n_out = RealOutput() {}
"Heading relative to the centerline"
alpha_out = RealOutput() {}
"Speed"
V_out = RealOutput() {}
"Body slip angle"
lambda_out = RealOutput() {}
"Yaw rate"
omega_out = RealOutput() {}
"Longitudinal acceleration (filtered)"
ax_out = RealOutput() {}
"Lateral acceleration (filtered)"
ay_out = RealOutput() {}
"Steering angle"
delta_out = RealOutput() {}
"Throttle"
throttle_out = RealOutput() {}
"Brake"
brake_out = RealOutput() {}
"Curvature of each track segment, the table `seg_curvature` as a signal (for a controller that takes the track as online parameters)"
seg_curvature_out = [RealOutput() for k in 1:nseg] {}
"Length of each track segment, the table `seg_length` as a signal"
seg_length_out = [RealOutput() for k in 1:nseg] {}
"Mass"
parameter M::Real = 800.0
"Distance from the centre of gravity to the front axle"
parameter a::Real = 1.8
"Distance from the centre of gravity to the rear axle"
parameter b::Real = 1.6
"Half track width"
parameter tw::Real = 0.73
"Yaw inertia"
parameter Iz::Real = 450.0
"Height of the centre of gravity"
parameter h::Real = 0.3
"Roll stiffness distribution (share of the lateral load transfer taken by the front axle)"
parameter chi::Real = 0.5
"Distance from the centre of pressure to the front axle"
parameter CoP::Real = 1.6
"Brake bias (share of the braking force on the front axle)"
parameter beta::Real = 0.62
"Lateral tyre stiffness per unit normal load"
parameter k_lambda::Real = 44.0
"Longitudinal friction coefficient at the static load"
parameter mu0_x::Real = 1.68
"Lateral friction coefficient at the static load"
parameter mu0_y::Real = 1.68
"Load sensitivity of the friction coefficient"
parameter k_mu::Real = 0.0
"Time constant of the longitudinal load transfer"
parameter tau_x::Real = 0.2
"Time constant of the lateral load transfer"
parameter tau_y::Real = 0.2
"Air density"
parameter rho::Real = 1.2
"Drag coefficient times frontal area"
parameter CdA::Real = 2.0
"Downforce coefficient times wing area"
parameter ClA::Real = 4.0
"Gravitational acceleration"
parameter g::Real = 9.8
"Engine power limit, the scale of the normalized tractive power `power_norm`"
parameter P_max::Real = 960000.0
"Arc length at the start"
parameter s0::Real = 0.0
"Lateral offset at the start"
parameter n0::Real = 0.0
"Relative heading at the start"
parameter alpha0::Real = 0.0
"Speed at the start (positive: the speed divides the slip angle dynamics)"
parameter V0::Real = 20.0
"Steering angle at the start"
parameter delta0::Real = 0.0
"Throttle at the start"
parameter throttle0::Real = 0.0
"Brake at the start"
parameter brake0::Real = 0.0
"Arc length over which the curvature blends from one segment to the next"
parameter blend::Real = racetrack_blend()
"Number of segments of the track (derived)"
final structural parameter nseg::Integer = racetrack_segment_count()
"Number of segment boundaries of the track (derived)"
final structural parameter nbound::Integer = nseg + 1
"Curvature of each segment of the track; an online parameter of the controller"
parameter seg_curvature::Real[nseg] = racetrack_curvatures()
"Length of each segment of the track; an online parameter of the controller"
parameter seg_length::Real[nseg] = racetrack_lengths()
"Static normal load of one front tyre (derived)"
final parameter N0_f::Real = M * g / 2 * b / (a + b)
"Static normal load of one rear tyre (derived)"
final parameter N0_r::Real = M * g / 2 * a / (a + b)
"Number of facets of the polygon inscribed in the friction ellipse (derived)"
final structural parameter nfacet::Integer = friction_polygon_facets()
"Cosine of the direction of each facet normal in the (longitudinal, lateral) plane of the tyre forces (derived)"
final parameter facet_cos::Real[nfacet] = friction_polygon_cos()
"Sine of the direction of each facet normal (derived)"
final parameter facet_sin::Real[nfacet] = friction_polygon_sin()
"Distance of the facets from the origin, the bound of `adh_fl` and its siblings (derived)"
final parameter adh_max::Real = friction_polygon_bound()
"Arc length along the centerline"
variable s::Real
"Arc length within the lap, at which the track tables are evaluated"
variable s_lap::Real
"Lateral offset from the centerline"
variable n::Real
"Heading relative to the centerline"
variable alpha::Real
"Speed"
variable V::Real
"Body slip angle"
variable lambda::Real
"Yaw rate"
variable omega::Real
"Longitudinal acceleration (filtered)"
variable ax::Real
"Lateral acceleration (filtered)"
variable ay::Real
"Steering angle"
variable delta::Real
"Throttle: the rear longitudinal tyre force as a fraction of the weight (nonnegative)"
variable throttle::Real
"Brake: the braking force as a fraction of the weight (nonnegative)"
variable brake::Real
"Arc length at which each segment starts (derived from the lengths)"
variable seg_start::Real[nbound]
"Fraction of the blend into each segment covered, clipped to [0, 1]"
variable t_in::Real[nseg]
"Fraction of the blend out of each segment covered, clipped to [0, 1]"
variable t_out::Real[nseg]
"Curvature contributed by the first k segments"
variable kappa_k::Real[nbound]
"Curvature of the centerline at the arc length s"
variable kappa::Real
"Rate of progress along the centerline"
variable sdot::Real
"Downforce"
variable downforce::Real
"Aerodynamic drag"
variable drag::Real
"Normal load of the front-left tyre"
variable N_fl::Real
"Normal load of the front-right tyre"
variable N_fr::Real
"Normal load of the rear-left tyre"
variable N_rl::Real
"Normal load of the rear-right tyre"
variable N_rr::Real
"Longitudinal force of one front tyre"
variable S_f::Real
"Longitudinal force of one rear tyre"
variable S_r::Real
"Lateral force of the front-left tyre"
variable F_fl::Real
"Lateral force of the front-right tyre"
variable F_fr::Real
"Lateral force of the rear-left tyre"
variable F_rl::Real
"Lateral force of the rear-right tyre"
variable F_rr::Real
"Rate of the lateral offset"
variable ndot::Real
"Rate of the relative heading"
variable alphadot::Real
"Acceleration along the body axis"
variable Vdot::Real
"Rate of the body slip angle"
variable lambdadot::Real
"Yaw acceleration"
variable omegadot::Real
"Rate of the filtered longitudinal acceleration"
variable axdot::Real
"Rate of the filtered lateral acceleration"
variable aydot::Real
"Tractive power"
variable power::Real
"Tractive power relative to the engine power limit (one at the limit)"
variable power_norm::Real
"Throttle minus brake, the signed thrust of dymos"
variable thrust::Real
"Friction ellipse of the front-left tyre (one at the limit of adherence)"
variable c_fl::Real
"Friction ellipse of the front-right tyre"
variable c_fr::Real
"Friction ellipse of the rear-left tyre"
variable c_rl::Real
"Friction ellipse of the rear-right tyre"
variable c_rr::Real
"Longitudinal tyre force of the front-left tyre relative to its limit of adherence"
variable sx_fl::Real
"Longitudinal tyre force of the front-right tyre relative to its limit of adherence"
variable sx_fr::Real
"Longitudinal tyre force of the rear-left tyre relative to its limit of adherence"
variable sx_rl::Real
"Longitudinal tyre force of the rear-right tyre relative to its limit of adherence"
variable sx_rr::Real
"Lateral tyre force of the front-left tyre relative to its limit of adherence, linear in the slip angle"
variable sy_fl::Real
"Lateral tyre force of the front-right tyre relative to its limit of adherence"
variable sy_fr::Real
"Lateral tyre force of the rear-left tyre relative to its limit of adherence"
variable sy_rl::Real
"Lateral tyre force of the rear-right tyre relative to its limit of adherence"
variable sy_rr::Real
"Facets of the octagon inscribed in the friction ellipse of the front-left tyre, each at most `adh_max`: the form the controller constrains"
variable adh_fl::Real[nfacet]
"Facets of the octagon inscribed in the friction ellipse of the front-right tyre"
variable adh_fr::Real[nfacet]
"Facets of the octagon inscribed in the friction ellipse of the rear-left tyre"
variable adh_rl::Real[nfacet]
"Facets of the octagon inscribed in the friction ellipse of the rear-right tyre"
variable adh_rr::Real[nfacet]
relations
initial s = s0
initial n = n0
initial alpha = alpha0
initial V = V0
initial lambda = 0
initial omega = 0
initial ax = 0
initial ay = 0
initial delta = delta0
initial throttle = throttle0
initial brake = brake0
# Curvature of the centerline at s: each segment contributes between its start and its end, with a
# cubic blend (3t^2 - 2t^3, continuous with a continuous derivative) of length `blend` at either end.
# The tables describe one lap, so the arc length is reduced to the lap before the lookup; the
# derivative of floor is zero, so the Jacobian of the lookup is that of the tables themselves
seg_start[1] = 0
s_lap = s - seg_start[nbound] * floor(s / seg_start[nbound])
kappa_k[1] = 0
for k in 1:nseg
seg_start[k + 1] = seg_start[k] + seg_length[k]
t_in[k] = max(min((s_lap - seg_start[k]) / blend, 1), 0)
t_out[k] = max(min((s_lap - seg_start[k + 1]) / blend, 1), 0)
kappa_k[k + 1] = kappa_k[k] + seg_curvature[k] * (t_in[k] ^ 2 * (3 - 2 * t_in[k]) - t_out[k] ^ 2 * (3 - 2 * t_out[k]))
end
kappa = kappa_k[nbound]
# Aerodynamics and normal loads
downforce = 0.5 * rho * ClA * V ^ 2
drag = 0.5 * rho * CdA * V ^ 2
N_fl = N0_f + M / 4 * (-(ax * h) / (a + b) + ay * chi * h / tw) + downforce * (1 - CoP / (a + b)) / 2
N_fr = N0_f + M / 4 * (-(ax * h) / (a + b) - ay * chi * h / tw) + downforce * (1 - CoP / (a + b)) / 2
N_rl = N0_r + M / 4 * ((ax * h) / (a + b) + ay * (1 - chi) * h / tw) + downforce * (CoP / (a + b)) / 2
N_rr = N0_r + M / 4 * ((ax * h) / (a + b) - ay * (1 - chi) * h / tw) + downforce * (CoP / (a + b)) / 2
# Tyre forces
S_f = -(M * g / 2) * brake * beta
S_r = (M * g / 2) * (throttle - brake * (1 - beta))
F_rr = N_rr * k_lambda * (lambda + omega * (b + lambda * tw) / V)
F_rl = N_rl * k_lambda * (lambda + omega * (b - lambda * tw) / V)
F_fr = N_fr * k_lambda * (lambda + delta - omega * (a - lambda * tw) / V)
F_fl = N_fl * k_lambda * (lambda + delta - omega * (a + lambda * tw) / V)
# Motion in the track frame: the time rates of the states, which the plant integrates over time and
# the spatial model divides by sdot to integrate over the arc length
sdot = V * cos(alpha - lambda) / (1 - n * kappa)
ndot = V * sin(alpha - lambda)
alphadot = omega - kappa * sdot
Vdot = (2 * S_f + 2 * S_r) / M - delta * (F_fl + F_fr) / M - drag / M - omega * V * lambda
lambdadot = omega - Vdot * lambda / V - delta * 2 * S_f / (M * V) - (F_fl + F_fr + F_rl + F_rr) / (M * V)
omegadot = (a * (F_fr + F_fl) - b * (F_rr + F_rl)) / Iz
axdot = (Vdot + omega * V * lambda - ax) / tau_x
aydot = (omega * V - (V * lambdadot + Vdot * lambda) - ay) / tau_y
# Constrained quantities
power = V * (2 * S_f + 2 * S_r)
power_norm = power / P_max
thrust = throttle - brake
c_fl = (S_f / (N_fl * (mu0_x + k_mu * N_fl / N0_f))) ^ 2 + (F_fl / (N_fl * (mu0_y + k_mu * N_fl / N0_f))) ^ 2
c_fr = (S_f / (N_fr * (mu0_x + k_mu * N_fr / N0_f))) ^ 2 + (F_fr / (N_fr * (mu0_y + k_mu * N_fr / N0_f))) ^ 2
c_rl = (S_r / (N_rl * (mu0_x + k_mu * N_rl / N0_r))) ^ 2 + (F_rl / (N_rl * (mu0_y + k_mu * N_rl / N0_r))) ^ 2
c_rr = (S_r / (N_rr * (mu0_x + k_mu * N_rr / N0_r))) ^ 2 + (F_rr / (N_rr * (mu0_y + k_mu * N_rr / N0_r))) ^ 2
# The same limits as a polygon inscribed in the ellipse of each tyre, in the coordinates (S / mu_x N,
# F / mu_y N). The lateral coordinate is k_lambda times the slip angle over mu_y, linear in the slip
# angle, which is what makes the facets well conditioned for the sequential quadratic programming of
# the controller: the ellipse itself spans a slip angle of only mu_y / k_lambda and is too curved
sx_fl = S_f / ((mu0_x + k_mu * N_fl / N0_f) * N_fl)
sx_fr = S_f / ((mu0_x + k_mu * N_fr / N0_f) * N_fr)
sx_rl = S_r / ((mu0_x + k_mu * N_rl / N0_r) * N_rl)
sx_rr = S_r / ((mu0_x + k_mu * N_rr / N0_r) * N_rr)
sy_fl = k_lambda * (lambda + delta - omega * (a + lambda * tw) / V) / (mu0_y + k_mu * N_fl / N0_f)
sy_fr = k_lambda * (lambda + delta - omega * (a - lambda * tw) / V) / (mu0_y + k_mu * N_fr / N0_f)
sy_rl = k_lambda * (lambda + omega * (b - lambda * tw) / V) / (mu0_y + k_mu * N_rl / N0_r)
sy_rr = k_lambda * (lambda + omega * (b + lambda * tw) / V) / (mu0_y + k_mu * N_rr / N0_r)
for j in 1:nfacet
adh_fl[j] = facet_cos[j] * sx_fl + facet_sin[j] * sy_fl
adh_fr[j] = facet_cos[j] * sx_fr + facet_sin[j] * sy_fr
adh_rl[j] = facet_cos[j] * sx_rl + facet_sin[j] * sy_rl
adh_rr[j] = facet_cos[j] * sx_rr + facet_sin[j] * sy_rr
end
s_out = s
n_out = n
alpha_out = alpha
V_out = V
lambda_out = lambda
omega_out = omega
ax_out = ax
ay_out = ay
delta_out = delta
throttle_out = throttle
brake_out = brake
for k in 1:nseg
seg_curvature_out[k] = seg_curvature[k]
seg_length_out[k] = seg_length[k]
end
endFlattened Source
"""
Race car of the dymos race car example (P. de Buck's lap simulation,
https://openmdao.github.io/dymos/examples/racecar/racecar.html), in the track frame and in the time
domain: a single-track vehicle with four tyres, driven by the steering angle ``\\delta``, the throttle
and the brake.
# Coordinates
The position is given relative to the centerline of the track: `s` is the arc length along the
centerline, `n` the lateral offset from it (positive to the left) and `alpha` the heading of the car
relative to the tangent of the centerline. `V` is the speed, `lambda` the body slip angle (the angle
from the velocity to the body axis), `omega` the yaw rate, and `ax`, `ay` the filtered longitudinal and
lateral accelerations through which the load transfer between the tyres acts (time constants `tau_x`,
`tau_y`). With ``\\kappa(s)`` the curvature of the centerline,
```math
\\dot s = \\frac{V \\cos(\\alpha - \\lambda)}{1 - n \\kappa(s)}, \\qquad
\\dot n = V \\sin(\\alpha - \\lambda), \\qquad
\\dot\\alpha = \\omega - \\kappa(s) \\dot s.
```
dymos integrates the same equations over `s` (dividing every rate by ``\\dot s``) because its
collocation nodes are then fixed in space; a receding-horizon controller runs on a clock and integrates
over time, so the model is kept in the time domain and the curvature is evaluated at the state `s`.
# Tyres and loads
The normal loads follow from the static weight distribution, the longitudinal and lateral load
transfer (`h`, `chi`) and the downforce ``\\tfrac{1}{2} \\rho C_l A V^2`` split at the centre of
pressure `CoP`. The longitudinal tyre forces are set directly by the controls: the throttle puts
``\\tfrac{1}{2} M g \\, \\mathrm{throttle}`` on each rear tyre, the brake puts ``M g \\, \\mathrm{brake}``
on the car split by the brake bias `beta` between the front and the rear. The lateral tyre forces are
linear in the slip angle of each tyre with the stiffness `k_lambda` times the normal load. dymos has
one signed `thrust` control split into a throttle and a brake by its sign; here the two are separate
nonnegative controls, which gives the same forces without the kink at zero, and `thrust` is their
difference. The tyre adherence `c_fl`, ..., `c_rr` is the friction ellipse
``(S / \\mu_x N)^2 + (F / \\mu_y N)^2`` of each tyre and `power` the tractive power. The controller
constrains the power and, in place of the ellipse of each tyre, the facets `adh_fl`, ..., `adh_rr` of a
regular octagon inscribed in it, with two vertices on the axes so that pure braking and pure cornering
keep the whole adherence and combined braking and cornering lose at most 8 % of it. The lateral
coordinate of the polygon is linear in the slip angle of the tyre, and that is the point: the ellipse
spans a slip angle of only ``\\mu_y / k_\\lambda \\approx 0.04`` rad, and it is quadratic in it, so its
linearization at a small slip angle carries no information about the lateral force: run to convergence
the iterations stall on it, and capped at a few iterations per tick they let the tyres exceed it by a
factor of 3 to 4 in the corners, with either prediction model (the time-domain one and
`RaceCarSpatialModel`). The ellipse written as a smoothed norm, whose gradient has unit length away
from the origin, fails from the first ticks for the same reason: the car starts with zero slip, where
that gradient vanishes too. The facets have constant gradients and the iterations converge on them.
The ellipse itself is enforced by `ACADOSMPCRaceCarSpatialExample` through the convex-over-nonlinear
constraint module of acados (`nl_convex_inner`/`nl_convex_outer`), which adds the curvature of the
ellipse to the QP: the iterations then keep the tyres within a few percent of it.
# Track
The centerline is the sequence of straight segments and circular arcs of the track, given by the
curvature and the length of each segment (`seg_curvature`, `seg_length`; see `racetrack_curvatures`).
The curvature at the arc length `s` is the sum over the segments of what each contributes, one for a
segment the arc length has entered and zero for one it has left, blended with the cubic
``3t^2 - 2t^3`` over `blend` metres at either end so that ``\\kappa(s)`` and its derivative are
continuous (the sequential quadratic programming of the controller relies on a continuous Jacobian);
the blend is symmetric, so the heading turned through a segment stays exactly its curvature times its
length. The tables describe one lap and are evaluated at the arc length within the lap, `s_lap`, which
wraps at their total length, so that any number of laps is driven on the tables of one; the first and
the last segment must be straights longer than the blend, as they are on the oval, for the curvature to
be zero on both sides of the wrap. The two tables are online parameters of the controller, as the path
is in `OmniRobotPathModel`.
The parameter values are the ones of the dymos example.
This partial component holds the parameters, the variables, the output connectors and every algebraic
relation, so that `RaceCarPlant` (the car in the time domain) and `RaceCarSpatialModel` (the car with
the arc length as the independent variable) share them and differ in the derivatives alone.
"""
partial component RaceCarModel
"Rate of the steering angle"
delta_rate = RealInput() {}
"Rate of the throttle"
throttle_rate = RealInput() {}
"Rate of the brake"
brake_rate = RealInput() {}
"Arc length along the centerline"
s_out = RealOutput() {}
"Lateral offset from the centerline, positive to the left"
n_out = RealOutput() {}
"Heading relative to the centerline"
alpha_out = RealOutput() {}
"Speed"
V_out = RealOutput() {}
"Body slip angle"
lambda_out = RealOutput() {}
"Yaw rate"
omega_out = RealOutput() {}
"Longitudinal acceleration (filtered)"
ax_out = RealOutput() {}
"Lateral acceleration (filtered)"
ay_out = RealOutput() {}
"Steering angle"
delta_out = RealOutput() {}
"Throttle"
throttle_out = RealOutput() {}
"Brake"
brake_out = RealOutput() {}
"Curvature of each track segment, the table `seg_curvature` as a signal (for a controller that takes the track as online parameters)"
seg_curvature_out = [RealOutput() for k in 1:nseg] {}
"Length of each track segment, the table `seg_length` as a signal"
seg_length_out = [RealOutput() for k in 1:nseg] {}
"Mass"
parameter M::Real = 800.0
"Distance from the centre of gravity to the front axle"
parameter a::Real = 1.8
"Distance from the centre of gravity to the rear axle"
parameter b::Real = 1.6
"Half track width"
parameter tw::Real = 0.73
"Yaw inertia"
parameter Iz::Real = 450.0
"Height of the centre of gravity"
parameter h::Real = 0.3
"Roll stiffness distribution (share of the lateral load transfer taken by the front axle)"
parameter chi::Real = 0.5
"Distance from the centre of pressure to the front axle"
parameter CoP::Real = 1.6
"Brake bias (share of the braking force on the front axle)"
parameter beta::Real = 0.62
"Lateral tyre stiffness per unit normal load"
parameter k_lambda::Real = 44.0
"Longitudinal friction coefficient at the static load"
parameter mu0_x::Real = 1.68
"Lateral friction coefficient at the static load"
parameter mu0_y::Real = 1.68
"Load sensitivity of the friction coefficient"
parameter k_mu::Real = 0.0
"Time constant of the longitudinal load transfer"
parameter tau_x::Real = 0.2
"Time constant of the lateral load transfer"
parameter tau_y::Real = 0.2
"Air density"
parameter rho::Real = 1.2
"Drag coefficient times frontal area"
parameter CdA::Real = 2.0
"Downforce coefficient times wing area"
parameter ClA::Real = 4.0
"Gravitational acceleration"
parameter g::Real = 9.8
"Engine power limit, the scale of the normalized tractive power `power_norm`"
parameter P_max::Real = 960000.0
"Arc length at the start"
parameter s0::Real = 0.0
"Lateral offset at the start"
parameter n0::Real = 0.0
"Relative heading at the start"
parameter alpha0::Real = 0.0
"Speed at the start (positive: the speed divides the slip angle dynamics)"
parameter V0::Real = 20.0
"Steering angle at the start"
parameter delta0::Real = 0.0
"Throttle at the start"
parameter throttle0::Real = 0.0
"Brake at the start"
parameter brake0::Real = 0.0
"Arc length over which the curvature blends from one segment to the next"
parameter blend::Real = racetrack_blend()
"Number of segments of the track (derived)"
final structural parameter nseg::Integer = racetrack_segment_count()
"Number of segment boundaries of the track (derived)"
final structural parameter nbound::Integer = nseg + 1
"Curvature of each segment of the track; an online parameter of the controller"
parameter seg_curvature::Real[nseg] = racetrack_curvatures()
"Length of each segment of the track; an online parameter of the controller"
parameter seg_length::Real[nseg] = racetrack_lengths()
"Static normal load of one front tyre (derived)"
final parameter N0_f::Real = M * g / 2 * b / (a + b)
"Static normal load of one rear tyre (derived)"
final parameter N0_r::Real = M * g / 2 * a / (a + b)
"Number of facets of the polygon inscribed in the friction ellipse (derived)"
final structural parameter nfacet::Integer = friction_polygon_facets()
"Cosine of the direction of each facet normal in the (longitudinal, lateral) plane of the tyre forces (derived)"
final parameter facet_cos::Real[nfacet] = friction_polygon_cos()
"Sine of the direction of each facet normal (derived)"
final parameter facet_sin::Real[nfacet] = friction_polygon_sin()
"Distance of the facets from the origin, the bound of `adh_fl` and its siblings (derived)"
final parameter adh_max::Real = friction_polygon_bound()
"Arc length along the centerline"
variable s::Real
"Arc length within the lap, at which the track tables are evaluated"
variable s_lap::Real
"Lateral offset from the centerline"
variable n::Real
"Heading relative to the centerline"
variable alpha::Real
"Speed"
variable V::Real
"Body slip angle"
variable lambda::Real
"Yaw rate"
variable omega::Real
"Longitudinal acceleration (filtered)"
variable ax::Real
"Lateral acceleration (filtered)"
variable ay::Real
"Steering angle"
variable delta::Real
"Throttle: the rear longitudinal tyre force as a fraction of the weight (nonnegative)"
variable throttle::Real
"Brake: the braking force as a fraction of the weight (nonnegative)"
variable brake::Real
"Arc length at which each segment starts (derived from the lengths)"
variable seg_start::Real[nbound]
"Fraction of the blend into each segment covered, clipped to [0, 1]"
variable t_in::Real[nseg]
"Fraction of the blend out of each segment covered, clipped to [0, 1]"
variable t_out::Real[nseg]
"Curvature contributed by the first k segments"
variable kappa_k::Real[nbound]
"Curvature of the centerline at the arc length s"
variable kappa::Real
"Rate of progress along the centerline"
variable sdot::Real
"Downforce"
variable downforce::Real
"Aerodynamic drag"
variable drag::Real
"Normal load of the front-left tyre"
variable N_fl::Real
"Normal load of the front-right tyre"
variable N_fr::Real
"Normal load of the rear-left tyre"
variable N_rl::Real
"Normal load of the rear-right tyre"
variable N_rr::Real
"Longitudinal force of one front tyre"
variable S_f::Real
"Longitudinal force of one rear tyre"
variable S_r::Real
"Lateral force of the front-left tyre"
variable F_fl::Real
"Lateral force of the front-right tyre"
variable F_fr::Real
"Lateral force of the rear-left tyre"
variable F_rl::Real
"Lateral force of the rear-right tyre"
variable F_rr::Real
"Rate of the lateral offset"
variable ndot::Real
"Rate of the relative heading"
variable alphadot::Real
"Acceleration along the body axis"
variable Vdot::Real
"Rate of the body slip angle"
variable lambdadot::Real
"Yaw acceleration"
variable omegadot::Real
"Rate of the filtered longitudinal acceleration"
variable axdot::Real
"Rate of the filtered lateral acceleration"
variable aydot::Real
"Tractive power"
variable power::Real
"Tractive power relative to the engine power limit (one at the limit)"
variable power_norm::Real
"Throttle minus brake, the signed thrust of dymos"
variable thrust::Real
"Friction ellipse of the front-left tyre (one at the limit of adherence)"
variable c_fl::Real
"Friction ellipse of the front-right tyre"
variable c_fr::Real
"Friction ellipse of the rear-left tyre"
variable c_rl::Real
"Friction ellipse of the rear-right tyre"
variable c_rr::Real
"Longitudinal tyre force of the front-left tyre relative to its limit of adherence"
variable sx_fl::Real
"Longitudinal tyre force of the front-right tyre relative to its limit of adherence"
variable sx_fr::Real
"Longitudinal tyre force of the rear-left tyre relative to its limit of adherence"
variable sx_rl::Real
"Longitudinal tyre force of the rear-right tyre relative to its limit of adherence"
variable sx_rr::Real
"Lateral tyre force of the front-left tyre relative to its limit of adherence, linear in the slip angle"
variable sy_fl::Real
"Lateral tyre force of the front-right tyre relative to its limit of adherence"
variable sy_fr::Real
"Lateral tyre force of the rear-left tyre relative to its limit of adherence"
variable sy_rl::Real
"Lateral tyre force of the rear-right tyre relative to its limit of adherence"
variable sy_rr::Real
"Facets of the octagon inscribed in the friction ellipse of the front-left tyre, each at most `adh_max`: the form the controller constrains"
variable adh_fl::Real[nfacet]
"Facets of the octagon inscribed in the friction ellipse of the front-right tyre"
variable adh_fr::Real[nfacet]
"Facets of the octagon inscribed in the friction ellipse of the rear-left tyre"
variable adh_rl::Real[nfacet]
"Facets of the octagon inscribed in the friction ellipse of the rear-right tyre"
variable adh_rr::Real[nfacet]
relations
initial s = s0
initial n = n0
initial alpha = alpha0
initial V = V0
initial lambda = 0
initial omega = 0
initial ax = 0
initial ay = 0
initial delta = delta0
initial throttle = throttle0
initial brake = brake0
# Curvature of the centerline at s: each segment contributes between its start and its end, with a
# cubic blend (3t^2 - 2t^3, continuous with a continuous derivative) of length `blend` at either end.
# The tables describe one lap, so the arc length is reduced to the lap before the lookup; the
# derivative of floor is zero, so the Jacobian of the lookup is that of the tables themselves
seg_start[1] = 0
s_lap = s - seg_start[nbound] * floor(s / seg_start[nbound])
kappa_k[1] = 0
for k in 1:nseg
seg_start[k + 1] = seg_start[k] + seg_length[k]
t_in[k] = max(min((s_lap - seg_start[k]) / blend, 1), 0)
t_out[k] = max(min((s_lap - seg_start[k + 1]) / blend, 1), 0)
kappa_k[k + 1] = kappa_k[k] + seg_curvature[k] * (t_in[k] ^ 2 * (3 - 2 * t_in[k]) - t_out[k] ^ 2 * (3 - 2 * t_out[k]))
end
kappa = kappa_k[nbound]
# Aerodynamics and normal loads
downforce = 0.5 * rho * ClA * V ^ 2
drag = 0.5 * rho * CdA * V ^ 2
N_fl = N0_f + M / 4 * (-(ax * h) / (a + b) + ay * chi * h / tw) + downforce * (1 - CoP / (a + b)) / 2
N_fr = N0_f + M / 4 * (-(ax * h) / (a + b) - ay * chi * h / tw) + downforce * (1 - CoP / (a + b)) / 2
N_rl = N0_r + M / 4 * ((ax * h) / (a + b) + ay * (1 - chi) * h / tw) + downforce * (CoP / (a + b)) / 2
N_rr = N0_r + M / 4 * ((ax * h) / (a + b) - ay * (1 - chi) * h / tw) + downforce * (CoP / (a + b)) / 2
# Tyre forces
S_f = -(M * g / 2) * brake * beta
S_r = (M * g / 2) * (throttle - brake * (1 - beta))
F_rr = N_rr * k_lambda * (lambda + omega * (b + lambda * tw) / V)
F_rl = N_rl * k_lambda * (lambda + omega * (b - lambda * tw) / V)
F_fr = N_fr * k_lambda * (lambda + delta - omega * (a - lambda * tw) / V)
F_fl = N_fl * k_lambda * (lambda + delta - omega * (a + lambda * tw) / V)
# Motion in the track frame: the time rates of the states, which the plant integrates over time and
# the spatial model divides by sdot to integrate over the arc length
sdot = V * cos(alpha - lambda) / (1 - n * kappa)
ndot = V * sin(alpha - lambda)
alphadot = omega - kappa * sdot
Vdot = (2 * S_f + 2 * S_r) / M - delta * (F_fl + F_fr) / M - drag / M - omega * V * lambda
lambdadot = omega - Vdot * lambda / V - delta * 2 * S_f / (M * V) - (F_fl + F_fr + F_rl + F_rr) / (M * V)
omegadot = (a * (F_fr + F_fl) - b * (F_rr + F_rl)) / Iz
axdot = (Vdot + omega * V * lambda - ax) / tau_x
aydot = (omega * V - (V * lambdadot + Vdot * lambda) - ay) / tau_y
# Constrained quantities
power = V * (2 * S_f + 2 * S_r)
power_norm = power / P_max
thrust = throttle - brake
c_fl = (S_f / (N_fl * (mu0_x + k_mu * N_fl / N0_f))) ^ 2 + (F_fl / (N_fl * (mu0_y + k_mu * N_fl / N0_f))) ^ 2
c_fr = (S_f / (N_fr * (mu0_x + k_mu * N_fr / N0_f))) ^ 2 + (F_fr / (N_fr * (mu0_y + k_mu * N_fr / N0_f))) ^ 2
c_rl = (S_r / (N_rl * (mu0_x + k_mu * N_rl / N0_r))) ^ 2 + (F_rl / (N_rl * (mu0_y + k_mu * N_rl / N0_r))) ^ 2
c_rr = (S_r / (N_rr * (mu0_x + k_mu * N_rr / N0_r))) ^ 2 + (F_rr / (N_rr * (mu0_y + k_mu * N_rr / N0_r))) ^ 2
# The same limits as a polygon inscribed in the ellipse of each tyre, in the coordinates (S / mu_x N,
# F / mu_y N). The lateral coordinate is k_lambda times the slip angle over mu_y, linear in the slip
# angle, which is what makes the facets well conditioned for the sequential quadratic programming of
# the controller: the ellipse itself spans a slip angle of only mu_y / k_lambda and is too curved
sx_fl = S_f / ((mu0_x + k_mu * N_fl / N0_f) * N_fl)
sx_fr = S_f / ((mu0_x + k_mu * N_fr / N0_f) * N_fr)
sx_rl = S_r / ((mu0_x + k_mu * N_rl / N0_r) * N_rl)
sx_rr = S_r / ((mu0_x + k_mu * N_rr / N0_r) * N_rr)
sy_fl = k_lambda * (lambda + delta - omega * (a + lambda * tw) / V) / (mu0_y + k_mu * N_fl / N0_f)
sy_fr = k_lambda * (lambda + delta - omega * (a - lambda * tw) / V) / (mu0_y + k_mu * N_fr / N0_f)
sy_rl = k_lambda * (lambda + omega * (b - lambda * tw) / V) / (mu0_y + k_mu * N_rl / N0_r)
sy_rr = k_lambda * (lambda + omega * (b + lambda * tw) / V) / (mu0_y + k_mu * N_rr / N0_r)
for j in 1:nfacet
adh_fl[j] = facet_cos[j] * sx_fl + facet_sin[j] * sy_fl
adh_fr[j] = facet_cos[j] * sx_fr + facet_sin[j] * sy_fr
adh_rl[j] = facet_cos[j] * sx_rl + facet_sin[j] * sy_rl
adh_rr[j] = facet_cos[j] * sx_rr + facet_sin[j] * sy_rr
end
s_out = s
n_out = n
alpha_out = alpha
V_out = V
lambda_out = lambda
omega_out = omega
ax_out = ax
ay_out = ay
delta_out = delta
throttle_out = throttle
brake_out = brake
for k in 1:nseg
seg_curvature_out[k] = seg_curvature[k]
seg_length_out[k] = seg_length[k]
end
metadata {}
endTest Cases ​
No test cases defined.
Related ​
Examples
Experiments
Analyses