Skip to content

Commit

Permalink
Update longitudinal mpc with follow distance param
Browse files Browse the repository at this point in the history
Update generator.cpp to parameterize the follow time. Then, using the process outlined in
the ACADO docs (https://acado.github.io/cgt_overview.html), rebuild the generator binary
and run it to regenerate the source files in lib_mpc_export, then manually copy them into
the openpilot repo.

Update longitudinal_mpc.c, libmpc_py.py, and planner.py to take in the additional
follow_time parameter.

Incorporate arne182's PR to update the Makefile
(commaai#248). Note that I did not use the generate
recipie inside the repo; I created the files outside of the repo as stated above.
  • Loading branch information
David Walsh committed Mar 11, 2019
1 parent 737f2ac commit 2acdf9c
Show file tree
Hide file tree
Showing 8 changed files with 77 additions and 61 deletions.
10 changes: 4 additions & 6 deletions selfdrive/controls/lib/longitudinal_mpc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ QPOASES_FLAGS = -I$(PHONELIBS)/qpoases -I$(PHONELIBS)/qpoases/INCLUDE -I$(PHONEL

ACADO_FLAGS = -I$(PHONELIBS)/acado/include -I$(PHONELIBS)/acado/include/acado

ifeq ($(UNAME_S),Darwin)
ACADO_LIBS := -lacado_toolkit_s
else ifeq ($(UNAME_M),aarch64)
ACADO_LIBS := -L $(PHONELIBS)/acado/aarch64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a
ifeq ($(UNAME_M),aarch64)
ACADO_LIBS := -L $(PHONELIBS)/acado/aarch64/lib -l:libacado_toolkit_s.so -l:libacado_casadi.a -l:libacado_csparse.a
else
ACADO_LIBS := -L $(PHONELIBS)/acado/x64/lib -l:libacado_toolkit.a -l:libacado_casadi.a -l:libacado_csparse.a
ACADO_LIBS := -L $(PHONELIBS)/acado/x64/lib -l:libacado_toolkit_s.so -l:libacado_casadi.a -l:libacado_csparse.a
endif

OBJS = \
Expand Down Expand Up @@ -80,7 +78,7 @@ generator: generator.cpp

.PHONY: generate
generate: generator
./generator
LD_LIBRARY_PATH=../../../../phonelibs/acado/x64/lib ./generator

.PHONY: clean
clean:
Expand Down
18 changes: 11 additions & 7 deletions selfdrive/controls/lib/longitudinal_mpc/generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ const int controlHorizon = 50;
using namespace std;

#define G 9.81
#define TR 1.8

#define RW(v_ego, v_l) (v_ego * TR - (v_l - v_ego) * TR + v_ego*v_ego/(2*G) - v_l*v_l / (2*G))
#define NORM_RW_ERROR(v_ego, v_l, p) ((RW(v_ego, v_l) + 4.0 - p)/(sqrt(v_ego + 0.5) + 0.1))
#define RW(v_ego, v_l, follow_time) (v_ego * follow_time - (v_l - v_ego) * follow_time + v_ego*v_ego/(2*G) - v_l*v_l / (2*G))
#define NORM_RW_ERROR(v_ego, v_l, p, follow_time) ((RW(v_ego, v_l, follow_time) + 4.0 - p)/(sqrt(v_ego + 0.5) + 0.1))

int main( )
{
Expand All @@ -24,7 +23,12 @@ int main( )

Control j_ego;

auto desired = 4.0 + RW(v_ego, v_l);
// follow distance expressed as a stopping distance in seconds
// see https://github.com/rhinodavid/CommaButtons
// see https://github.com/acado/acado/issues/54 for a discussion of `OnlineData`
OnlineData follow_time;

auto desired = 4.0 + RW(v_ego, v_l, follow_time);
auto d_l = x_l - x_ego;

// Directly calculate a_l to prevent instabilites due to discretization
Expand All @@ -41,7 +45,7 @@ int main( )

// Running cost
Function h;
h << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l)) - exp(0.3 * NORM_RW_ERROR(v_ego, v_l, desired));
h << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l, follow_time)) - exp(0.3 * NORM_RW_ERROR(v_ego, v_l, desired, follow_time));
h << (d_l - desired) / (0.05 * v_ego + 0.5);
h << a_ego * (0.1 * v_ego + 1.0);
h << j_ego * (0.1 * v_ego + 1.0);
Expand All @@ -51,7 +55,7 @@ int main( )

// Terminal cost
Function hN;
hN << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l)) - exp(0.3 * NORM_RW_ERROR(v_ego, v_l, desired));
hN << exp(0.3 * NORM_RW_ERROR(v_ego, v_l, d_l, follow_time)) - exp(0.3 * NORM_RW_ERROR(v_ego, v_l, desired, follow_time));
hN << (d_l - desired) / (0.05 * v_ego + 0.5);
hN << a_ego * (0.1 * v_ego + 1.0);

Expand Down Expand Up @@ -79,7 +83,7 @@ int main( )
ocp.minimizeLSQEndTerm(QN, hN);

ocp.subjectTo( 0.0 <= v_ego);
ocp.setNOD(2);
ocp.setNOD(3);

OCPexport mpc(ocp);
mpc.set( HESSIAN_APPROXIMATION, GAUSS_NEWTON );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ extern "C"
/** Number of control/estimation intervals. */
#define ACADO_N 20
/** Number of online data values. */
#define ACADO_NOD 2
#define ACADO_NOD 3
/** Number of path constraints. */
#define ACADO_NPAC 0
/** Number of control variables. */
Expand Down Expand Up @@ -114,11 +114,11 @@ real_t x[ 126 ];
*/
real_t u[ 20 ];

/** Matrix of size: 21 x 2 (row major format)
/** Matrix of size: 21 x 3 (row major format)
*
* Matrix containing 21 online data vectors.
*/
real_t od[ 42 ];
real_t od[ 63 ];

/** Column vector of size: 80
*
Expand Down Expand Up @@ -160,14 +160,14 @@ real_t rhs_aux[ 10 ];

real_t rk_ttt;

/** Row vector of size: 51 */
real_t rk_xxx[ 51 ];
/** Row vector of size: 52 */
real_t rk_xxx[ 52 ];

/** Matrix of size: 4 x 48 (row major format) */
real_t rk_kkk[ 192 ];

/** Row vector of size: 51 */
real_t state[ 51 ];
/** Row vector of size: 52 */
real_t state[ 52 ];

/** Column vector of size: 120 */
real_t d[ 120 ];
Expand All @@ -187,8 +187,8 @@ real_t evGu[ 120 ];
/** Column vector of size: 30 */
real_t objAuxVar[ 30 ];

/** Row vector of size: 9 */
real_t objValueIn[ 9 ];
/** Row vector of size: 10 */
real_t objValueIn[ 10 ];

/** Row vector of size: 32 */
real_t objValueOut[ 32 ];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ rk_eta[47] = 0.0000000000000000e+00;
acadoWorkspace.rk_xxx[48] = rk_eta[48];
acadoWorkspace.rk_xxx[49] = rk_eta[49];
acadoWorkspace.rk_xxx[50] = rk_eta[50];
acadoWorkspace.rk_xxx[51] = rk_eta[51];

for (run1 = 0; run1 < 1; ++run1)
{
Expand Down

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion selfdrive/controls/lib/longitudinal_mpc/libmpc_py.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def _get_libmpc(mpc_id):
void init(double ttcCost, double distanceCost, double accelerationCost, double jerkCost);
void init_with_simulation(double v_ego, double x_l, double v_l, double a_l, double l);
int run_mpc(state_t * x0, log_t * solution,
double l, double a_l_0);
double l, double a_l_0, double follow_time);
""")

return (ffi, ffi.dlopen(libmpc_fn))
Expand All @@ -48,3 +48,4 @@ def _get_libmpc(mpc_id):

def get_libmpc(mpc_id):
return mpcs[mpc_id - 1]

3 changes: 2 additions & 1 deletion selfdrive/controls/lib/longitudinal_mpc/longitudinal_mpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,13 @@ void init_with_simulation(double v_ego, double x_l_0, double v_l_0, double a_l_0
for (i = 0; i < NYN; ++i) acadoVariables.yN[ i ] = 0.0;
}

int run_mpc(state_t * x0, log_t * solution, double l, double a_l_0){
int run_mpc(state_t * x0, log_t * solution, double l, double a_l_0, double follow_time){
int i;

for (i = 0; i <= NOD * N; i+= NOD){
acadoVariables.od[i] = l;
acadoVariables.od[i+1] = a_l_0;
acadoVariables.od[i+2] = follow_time;
}

acadoVariables.x[0] = acadoVariables.x0[0] = x0->x_ego;
Expand Down
4 changes: 3 additions & 1 deletion selfdrive/controls/lib/planner.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ def update(self, CS, lead, v_cruise_setpoint):

# Calculate mpc
t = sec_since_boot()
n_its = self.libmpc.run_mpc(self.cur_state, self.mpc_solution, self.a_lead_tau, a_lead)
# hardcode follow time for now
follow_time = 1.8
n_its = self.libmpc.run_mpc(self.cur_state, self.mpc_solution, self.a_lead_tau, a_lead, follow_time)
duration = int((sec_since_boot() - t) * 1e9)
self.send_mpc_solution(n_its, duration)

Expand Down

0 comments on commit 2acdf9c

Please sign in to comment.