anassinator / ilqr

Iterative Linear Quadratic Regulator with auto-differentiatiable dynamics models
GNU General Public License v3.0
384 stars 80 forks source link

time varying MPC #14

Closed nag92 closed 4 years ago

nag92 commented 4 years ago

I am trying to create a MPC to follow a path. So the cost function is time varying. I was reading through the code and you commented the cost:

"If your cost or dynamics are time dependent, then you might need to shift their internal state accordingly."

I think I understand what you mean by this but I am unsure of how I would implement such a thing. Do you have any insight on how to do this?

nag92 commented 4 years ago

Is this repo being maintained?

anassinator commented 4 years ago

"If your cost or dynamics are time dependent, then you might need to shift their internal state accordingly."

I think I understand what you mean by this but I am unsure of how I would implement such a thing. Do you have any insight on how to do this?

If your cost function is time varying then the i passed into your cost function by the RecedingHorizonController will be 0-indexed differently each iteration and you need to account for that. If you just assume i = 0 is the first step and change your cost's internal state after each call to RecedingHorizonController.control() with whatever your expected time point is, you should be fine.

Is this repo being maintained?

Not particularly.

nag92 commented 4 years ago

will be 0-indexed differently each iteration and you need to account for that

what do you mean by this?

anassinator commented 4 years ago

IIRC, the way the RecedingHorizonController works is by iteratively calling iLQR.fit() and advancing the state and action paths by a given step_size. So on every iteration, your cost function will be called with an i ranging from 0 to path length. That means during the first iteration, an i of 0 will be the first step, but on the second iteration, an i of 0 will be the step_size-d step. So you can't just blindly assume that i is your time step and need to account for that.

nag92 commented 4 years ago

0 will be the step_size-d step. So you can't just blindly assume that i is your time step and need to account for that.

I am still a little confused. Sorry for the repeated questions and thankyou for your time and patience.

In the cost function, I have to account for the advancing state that move the system forward? So on each iteration I do i - state_index

add state_index goes to a path length?

anassinator commented 4 years ago

Let's start with the non-receding horizon case:

We assume your cost is a function of unix time t e.g. sin(x t). i does not equal t since i is in the range of [0, N[. So you would need some function that goes from i -> t. That would probably look like:

t = i * dt + start_t

where dt is the step size in absolute time and start_t is whatever starting time you want to associate with i = 0 (likely the result of time.time() when you first start the controller).

Now when we add the receding horizon into play, we will always be calling your cost with i in the range of [0, N[ (not [iteration_count * step_size, iteration_count * step_size + N[) even though we're stepping through the trajectory one step_size at a time. You can compensate for this either by changing your cost to something like:

t = i * iteration_count * step_size + start_t

without ever changing start_t or keeping it as:

t = i * dt + start_t

but resetting start_t to the new current time.time() before each new iteration (i.e. after each step_size). I would recommend the latter since that's more accurate and less likely to drift.

nag92 commented 4 years ago

that helps a lot thankyou for your time. I think I got it now.