PSOPT / psopt

PSOPT Optimal Control Software
GNU Lesser General Public License v2.1
201 stars 76 forks source link

Use SNOPT C++ interface. #5

Closed chrisdembia closed 9 years ago

chrisdembia commented 9 years ago

Hey @vmbecerra.

I got SNOPT to work using their C++ interface. They distrubute the C++ interface via https://github.com/snopt/snopt-interface, but I copied the files directory into this repo since their license permits it and I don't know if they promise backwards compatibility.

There is at least one limitation of what I've done: I've resorted back to using a global pointer for the Workspace. I tried to think of other ways around this but I can't think of a promising solution. The C++ interface still uses a similar function pointer; it doesn't allow you to create a class that defines your problem, like IPOPT does.

The snPSOPTusrf does take 3 user workspace parameters...we could try to pass the workspace pointer as part of the int (iu) workspace, though I don't think this is a good idea.

The other potential shortcoming is that the code might not deal with automatic derivatives correctly. As written, I think SNOPT is determining sparsity, itself. So even if automatic derivatives are available, it could be the case that numerical derivatives are used (not sure; didn't look too far into this). If this is a problem, we should be able to fix it by rearranging some code (maybe removing the snprob.computeJac() call or moving it).

I tested the SNOPT algorithm on the twolink problem and it solved.

I also wrote a script install-ubuntu-snopt.sh that should facilitate building the snopt C++ interface and using SNOPT with PSOPT. A user might need to run that script before running install-ubuntu.sh, since it modifies the makefiles.

vmbecerra commented 9 years ago

@chrisdembia , many thanks for this update. The way I solved the issue with the SNOPT derivatives in the previous releases of PSOPT (which used the C interface of SNOPT) was to enable user supplied derivatives in SNOPT, and then in the user supplied functions expected by SNOPT the automatic derivatives were loaded and assigned to the right variables. It should be possible to do something similar with the C++ interface. With regard to the avoidance of global variables, I will have a look to see if there is any way around.

vmbecerra commented 9 years ago

Hi @chrisdembia, I have managed to do some testing of the SNOPT interface (without any changes). Here is my log:

SNOPTA EXIT 40 -- terminated after numerical difficulties SNOPTA INFO 43 -- cannot satisfy the general constraints

- The 'launch' example also gives the elemProduct() error at the end.
- The 'missile' example runs well with SNOPT.
- 'twoburn' example has a problem. It gives the same errors as the launch problem.
- The elemProduct() problem seems to occur only in problems with multiple phases 
chrisdembia commented 9 years ago

Thanks for doing that testing. I'm happy it worked. Do you know if those are new issues or if SNOPT had variable success in PSOPT 3?

I could perhaps to some checking in my version of PSOPT 3 in which I used the new C++ SNOPT interface.

vmbecerra commented 9 years ago

We will need to test the cases that are giving a problem (twoburn, launch) using SNOPT and PSOPT3. If the problems occur with the C++ inferface and PSOPT3, it may be necessary to check as well with the old C interface to SNOPT that was originally part of PSOPT3.

vmbecerra commented 9 years ago

@chrisdembia, I have updated the SNOPT interface so that it can use automatic derivatives. Also I have made one change in psopt.cxx to avoid the elemProduct() error that occurs when nevents=0 in one phase and SNOPT is being used.

I have also made tests using the previous version of SNOPT, PSOPT3 and its C interface to SNOPT, and I noticed that the SNOPT also had the same issues with the same examples in PSOPT3 (e.g. the 'launch' and 'twoburn' examples), which I detected with the newer SNOPT, as reported above in this thread.

chrisdembia commented 9 years ago

Oh, fantastic!