Update spline after compilation

Hi :wave:

I’m developing an MPC for an autonomous car. This is part of the student organization fuel fighter at NTNU. The goal is to make the most energy efficient autonomous car. We will compete in Shell Eco-Marathon this summer.

I’m using the python interface to define the MPC and then use the generated c-code together with my C++ code for ROS to run the MPC.

I want to use splines to describe the track. Since the track is not know before we start this spline needs to be updated as the system is running. I have not found a good way of doing this. I tried implementing the solution from this topic. I got it working by modifying race_cars example. I modfied line 58 in this file.

# old spline, can't update after compile
kapparef_s = interpolant("kapparef_s_old", "bspline", [s0], kapparef)

# new spline, can update after compile by setting parameters p.
model.p = MX.sym("spilne_p", len(s0), 1)
interp_path = interpolant("kapparef_s_new", "bspline", [s0])
kapparef_s = Function("interp_func", [s], [interp_path(s, p)])

# specifying the parameters later for new solution:
ocp.parameter_values = np.array(kapparef)

Here s0 is the distance along the trajectory, for example [0, 0.5, 1, … , 0.5*n]. Kapparef is the curvature of the trajectory at each point. It works, however it is painfully slow. ~4000 times slower in my case… I think the issue is that instead of calculating the parameters for the spline once and the using them for the rest of the calculations, it’s calculating the parameters every time the function is called.

What I want is that if the track is updated then the I want to update the spline. Otherwise I want to use the spline from the previous calculation. I think that if it would be possible to send the spline parameters (the internal coefficients) to acados it would work. Then I would generate the interpolant function myself and pass this to acados. I could either pass the internal parameters or what would be very nice is that if I could pass a function pointer or something like that :slight_smile: . Is this possible?

Thanks for your time!

Hi @torpedo,

thanks for your detailed description. In my opinion, I would calculate it offline (not in acados) and pass the final coefficients as parameters in your OCP. Then you are also able to update them only whenever it makes sense for your problem.


Thanks @mss.
That makes sense. What I’m unsure about is whats the best way of passing these parameters. Since the number of coefficients are dependent on number of points I have. If I use a casadi.MX variable doesn’t that assume that the dimensions is know at compilation?

Also given that I’m able to pass the parameters to acados. How do I avoid writing my own spline code? Do you have any suggestions on how i could calculate the coefficients and also use them without doing it all from scratch? Would be nice if I could retrieve the parameters from casADi interpolant function in my code and then pass the internal coefficients to acados. Then I could give these to a casADi interpolant function in acados and use that. I have not found a way of doing this. Do you know if it’s possible or have something similar I could try?

the numbers of parameters should be constant. So that your solver always know how to interpret the parameters.

I haven’t worked yet so much with splines, but if you are satisfied with the CasADi spline workflow, you can use it as follows:

  • Create a CasADi function for spline generation (use constant amount of parameters/gridpoints)
  • Generate C-code of this function CasADi - Docs
  • Use this code in your ROS-code

(not tested yet)