HJReachability / ilqgames

Iterative Linear-Quadratic Games!
https://hjreachability.github.io/ilqgames/
BSD 3-Clause "New" or "Revised" License
132 stars 41 forks source link

FlatRoundaboutMergingExample: Initializing operating_point #56

Closed rallen10 closed 3 years ago

rallen10 commented 3 years ago

I am trying to mimic some of the FlatRoundaboutMergingExample::ConstructInitialOperatingPoint() functionality for a new example problem, however when I simply try to run the an unmodified version of FlatRoundaboutMergingExample I get the error:

.... initialize_along_route.cpp:59] Check failed: 'operating_point' Must be non NULL
*** Check failure stack trace: ***
    @        0x10e2f1953  google::LogMessage::Flush()
    @        0x10e2f4d21  google::LogMessageFatal::~LogMessageFatal()
    @        0x10e2f2275  google::LogMessageFatal::~LogMessageFatal()
    @        0x10e16192b  ilqgames::InitializeAlongRoute()
    @        0x10e1573fa  ilqgames::FlatRoundaboutMergingExample::ConstructInitialOperatingPoint()
    @        0x10e19acea  ilqgames::Problem::Initialize()
    @        0x10e133752  main
Abort trap: 6

I can see where the error comes from but it's not clear what the fix should be. It seems like an operating_point should be initialized before calling InitializeAlongRoute, but the initialization is also the purpose of the ConstructInitialOperatingPoint(). I kinda seems like a chicken-and-egg problem

dfridovi commented 3 years ago

Yeah so I'm almost positive this is a relic of a refactor I did a few months ago. Pretty much what should happen is that the operating point should get initialized by ConstructInitialOperatingPoint() which should turn around and call InitializeAlongRoute(), but I must have goofed that up in this case. The larger comment I have is that the Flat* stuff is all fairly deprecated, so it should run ok, but I haven't been using it a long time and I would not expect it to be in such great shape since I haven't really tested any of it in a long time despite many code changes. My advice would be to use the equivalent non-differentiably-flat versions for everything... it'll save a lot of headaches. As one of the papers on the front README describes, exploiting differential flatness can simplify the problem a lot and help the solver, but it can also make things more complicated in some cases (and the paper explains more).

rallen10 commented 3 years ago

Thank you for the response. I found a workaround by simply calling the parent's function Problem::ConstructInitialOperatingPoint() within and at the beginning of the child's FlatRoundaboutMergingExample::ConstructInitialOperatingPoint(), and then proceeded to call the InitializeAlongRoute(). This fixed the above error, but it didn't achieve what I intended; i.e. when I run the example, my agents do not appear to follow the route I define in InitializeAlongRoute() during iteration 0. I need to see if I have a bug somewhere, but if you have any further insights on how to initialize an operating point, it would be appreciated.

dfridovi commented 3 years ago

Oof I would have expected that to work. I'm not sure what's going on then. One thing to double check because it has definitely changed during different refactors and I keep waffling on what the right way to do it is: basically, the solver might be doing something like not logging the initial operating point under some conditions. Just good to double check that's not happening.

rallen10 commented 3 years ago

Thanks again for the further feedback.

I managed to get my desired behavior by implementing a ConstructInitialStrategies() function along with the ConstructInitialOperatingPoint(). In the ConstructInitialStrategies function, I prescribe the alphas (i.e. what I understand to be the feedforward control terms) to roughly match those needed to produce the state trajectory prescribed in InitializeAlongRoute() within ConstructInitialOperatingPoint().

The problem might have been due to the fact that my example problem---which is different than FlatRoundaboutMergingExample, inspite of the title of this issue---uses very simple dynamics (i.e. heading is the control, not a state variable, see the canonical target guarding problem from Isaacs' Differential Games book).

Even though I haven't fully hunted down all possible issues, I'm going to close this issue since I have a workaround for the time being. Thank you for all of the help!