PSOPT / psopt

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

Constraint functions should be std::function instead of function pointers #27

Closed schulz0r closed 3 years ago

schulz0r commented 3 years ago

Every example in this project has predefined constraint functions (e.g. events) where values do not change during runtime. Since I have a lot of trajectories to plan which can have arbitrary start and endpoints, I need to reset the functions every time I want to plan a new trajectory. Sadly, the problem definition struct uses C-style function pointers, which do not allow for that.

I would like to see std::function to replace the C-style pointers, so it is possible to use lambdas which capture variables (e.g. the start and stop state) from outside the function. I think this change would not even require any changes to the examples because std::functions are pretty backward compatible. To illustrate what I want to do, see following code. The first block depicts what is possible right now:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately
Prob problem;
// you can assign lambdas to function pointers btw
problem.events = [](adouble* some_args) {
    // cannot see myFinalState
    // thus cannot set it
}

With std::function, following will be possible:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately
Prob problem;
// std::function allows to capture myFinalState
problem.events = [&myFinalState](adouble* some_args) {
    Eigen::Map<Eigen::Matrix<adouble, 6, 1>> eventVector(e, 6);    // wrap pointer into eigen vector
    eventVector << myFinalState;    // set final state values here
}
vmbecerra commented 3 years ago

Philip,

Ok - let me look into this I will come back to you a.s.a.p.

Best

Victor.

On Wed, 9 Sep 2020 at 10:09, schulz0r notifications@github.com wrote:

Every example in this project has predefined constraint functions (e.g. events) where values do not change during runtime. Since I have a lot of trajectories to plan which can have arbitrary start and endpoints, I need to reset the functions every time I want to plan a new trajectory. Sadly, the problem definition struct uses C-style function pointers, which do not allow for that.

I would like to see std::function to replace the C-style pointers, so it is possible to use lambdas which capture variables (e.g. the start and stop state) from outside the function. I think this change would not even require any changes to the examples because std::functions are pretty backward compatible. To illustrate what I want to do, see following code. The first block depicts what is possible right now:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // you can assign lambdas to function pointers btw problem.events = [](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { // cannot see myFinalState // thus cannot set it }

With std::function, following will be possible:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // std::function allows to capture myFinalState problem.events = [&myFinalState](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { Eigen::Map<Eigen::Matrix<adouble, 6, 1>> eventVector(e, 6); // wrap pointer into eigen vector eventVector << myFinalState; // set final state values here }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGCMBK4E7SSHF3B7DVR37TSE5A4TANCNFSM4RBT42YA .

schulz0r commented 3 years ago

I received your advise to simply set the event constraint bounds:

problem.phases(1).bounds.lower.events << x0, xf;
problem.phases(1).bounds.upper.events << x0, xf;

The event function looks like the one from the Alpine Rider example.

schulz0r commented 3 years ago

Hello Victor, I think I figured out what is the problem with the linking. I cannot compile the new SNOPT interface thou, so I have to fix that problem first. I will report back in the next days.

Philipp

Am 09.09.2020 um 19:50 schrieb vmbecerra notifications@github.com:

Philip,

Ok - let me look into this I will come back to you a.s.a.p.

Best

Victor.

On Wed, 9 Sep 2020 at 10:09, schulz0r notifications@github.com wrote:

Every example in this project has predefined constraint functions (e.g. events) where values do not change during runtime. Since I have a lot of trajectories to plan which can have arbitrary start and endpoints, I need to reset the functions every time I want to plan a new trajectory. Sadly, the problem definition struct uses C-style function pointers, which do not allow for that.

I would like to see std::function to replace the C-style pointers, so it is possible to use lambdas which capture variables (e.g. the start and stop state) from outside the function. I think this change would not even require any changes to the examples because std::functions are pretty backward compatible. To illustrate what I want to do, see following code. The first block depicts what is possible right now:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // you can assign lambdas to function pointers btw problem.events = [](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { // cannot see myFinalState // thus cannot set it }

With std::function, following will be possible:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // std::function allows to capture myFinalState problem.events = [&myFinalState](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { Eigen::Map<Eigen::Matrix<adouble, 6, 1>> eventVector(e, 6); // wrap pointer into eigen vector eventVector << myFinalState; // set final state values here }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGCMBK4E7SSHF3B7DVR37TSE5A4TANCNFSM4RBT42YA .

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27#issuecomment-689719690, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC7OZDSR3AMVPWCM34WZZXTSE6563ANCNFSM4RBT42YA.

vmbecerra commented 3 years ago

Philipp

Ok, many thanks. I will wait for your update. I have been updating the documentation in the meantime.

Best

Victor.

On Mon, 21 Sep 2020 at 15:38, schulz0r notifications@github.com wrote:

Hello Victor, I think I figured out what is the problem with the linking. I cannot compile the new SNOPT interface thou, so I have to fix that problem first. I will report back in the next days.

Philipp

Am 09.09.2020 um 19:50 schrieb vmbecerra notifications@github.com:

Philip,

Ok - let me look into this I will come back to you a.s.a.p.

Best

Victor.

On Wed, 9 Sep 2020 at 10:09, schulz0r notifications@github.com wrote:

Every example in this project has predefined constraint functions (e.g. events) where values do not change during runtime. Since I have a lot of trajectories to plan which can have arbitrary start and endpoints, I need to reset the functions every time I want to plan a new trajectory. Sadly, the problem definition struct uses C-style function pointers, which do not allow for that.

I would like to see std::function to replace the C-style pointers, so it is possible to use lambdas which capture variables (e.g. the start and stop state) from outside the function. I think this change would not even require any changes to the examples because std::functions are pretty backward compatible. To illustrate what I want to do, see following code. The first block depicts what is possible right now:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // you can assign lambdas to function pointers btw problem.events = [](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { // cannot see myFinalState // thus cannot set it }

With std::function, following will be possible:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // std::function allows to capture myFinalState problem.events = [&myFinalState](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { Eigen::Map<Eigen::Matrix<adouble, 6, 1>> eventVector(e, 6); // wrap pointer into eigen vector eventVector << myFinalState; // set final state values here }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27, or unsubscribe < https://github.com/notifications/unsubscribe-auth/ADGCMBK4E7SSHF3B7DVR37TSE5A4TANCNFSM4RBT42YA

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub < https://github.com/PSOPT/psopt/issues/27#issuecomment-689719690>, or unsubscribe < https://github.com/notifications/unsubscribe-auth/AC7OZDSR3AMVPWCM34WZZXTSE6563ANCNFSM4RBT42YA .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27#issuecomment-696158712, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGCMBI7ULTMS6THRPSWFNLSG5QPVANCNFSM4RBT42YA .

schulz0r commented 3 years ago

Good night,

I couldn’t rest without having solved the problem first. The latest PR should adds some lines to the examples' CMakeLists to make them work with SNOPT. I hope this helps you to avoid manual linking. Tomorrow I will check why there are no debug symbols generated when using -DCMAKE_BUILD_TYPE=Debug, as you mentioned earlier.

Philipp

Am 21.09.2020 um 16:47 schrieb vmbecerra notifications@github.com:

Philipp

Ok, many thanks. I will wait for your update. I have been updating the documentation in the meantime.

Best

Victor.

On Mon, 21 Sep 2020 at 15:38, schulz0r notifications@github.com wrote:

Hello Victor, I think I figured out what is the problem with the linking. I cannot compile the new SNOPT interface thou, so I have to fix that problem first. I will report back in the next days.

Philipp

Am 09.09.2020 um 19:50 schrieb vmbecerra notifications@github.com:

Philip,

Ok - let me look into this I will come back to you a.s.a.p.

Best

Victor.

On Wed, 9 Sep 2020 at 10:09, schulz0r notifications@github.com wrote:

Every example in this project has predefined constraint functions (e.g. events) where values do not change during runtime. Since I have a lot of trajectories to plan which can have arbitrary start and endpoints, I need to reset the functions every time I want to plan a new trajectory. Sadly, the problem definition struct uses C-style function pointers, which do not allow for that.

I would like to see std::function to replace the C-style pointers, so it is possible to use lambdas which capture variables (e.g. the start and stop state) from outside the function. I think this change would not even require any changes to the examples because std::functions are pretty backward compatible. To illustrate what I want to do, see following code. The first block depicts what is possible right now:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // you can assign lambdas to function pointers btw problem.events = [](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { // cannot see myFinalState // thus cannot set it }

With std::function, following will be possible:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // std::function allows to capture myFinalState problem.events = [&myFinalState](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { Eigen::Map<Eigen::Matrix<adouble, 6, 1>> eventVector(e, 6); // wrap pointer into eigen vector eventVector << myFinalState; // set final state values here }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27, or unsubscribe < https://github.com/notifications/unsubscribe-auth/ADGCMBK4E7SSHF3B7DVR37TSE5A4TANCNFSM4RBT42YA

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub < https://github.com/PSOPT/psopt/issues/27#issuecomment-689719690>, or unsubscribe < https://github.com/notifications/unsubscribe-auth/AC7OZDSR3AMVPWCM34WZZXTSE6563ANCNFSM4RBT42YA .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27#issuecomment-696158712, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGCMBI7ULTMS6THRPSWFNLSG5QPVANCNFSM4RBT42YA .

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27#issuecomment-696164167, or unsubscribe https://github.com/notifications/unsubscribe-auth/AC7OZDWEK7J54PQ6A5OIYADSG5RQ3ANCNFSM4RBT42YA.

vmbecerra commented 3 years ago

Philip

Excellent, many thanks for that. I have now merged your pull request.

Best

Victor.

On Mon, 21 Sep 2020 at 23:24, schulz0r notifications@github.com wrote:

Good night,

I couldn’t rest without having solved the problem first. The latest PR should adds some lines to the examples' CMakeLists to make them work with SNOPT. I hope this helps you to avoid manual linking. Tomorrow I will check why there are no debug symbols generated when using -DCMAKE_BUILD_TYPE=Debug, as you mentioned earlier.

Philipp

Am 21.09.2020 um 16:47 schrieb vmbecerra notifications@github.com:

Philipp

Ok, many thanks. I will wait for your update. I have been updating the documentation in the meantime.

Best

Victor.

On Mon, 21 Sep 2020 at 15:38, schulz0r notifications@github.com wrote:

Hello Victor, I think I figured out what is the problem with the linking. I cannot compile the new SNOPT interface thou, so I have to fix that problem first. I will report back in the next days.

Philipp

Am 09.09.2020 um 19:50 schrieb vmbecerra notifications@github.com:

Philip,

Ok - let me look into this I will come back to you a.s.a.p.

Best

Victor.

On Wed, 9 Sep 2020 at 10:09, schulz0r notifications@github.com wrote:

Every example in this project has predefined constraint functions (e.g. events) where values do not change during runtime. Since I have a lot of trajectories to plan which can have arbitrary start and endpoints, I need to reset the functions every time I want to plan a new trajectory. Sadly, the problem definition struct uses C-style function pointers, which do not allow for that.

I would like to see std::function to replace the C-style pointers, so it is possible to use lambdas which capture variables (e.g. the start and stop state) from outside the function. I think this change would not even require any changes to the examples because std::functions are pretty backward compatible. To illustrate what I want to do, see following code. The first block depicts what is possible right now:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // you can assign lambdas to function pointers btw problem.events = [](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { // cannot see myFinalState // thus cannot set it }

With std::function, following will be possible:

Eigen::Matrix<adouble, 6, 1> myFinalState; // fill this vector appropriately Prob problem; // std::function allows to capture myFinalState problem.events = [&myFinalState](adouble e, adouble initial_states, adouble final_states, adouble parameters,adouble& t0, adouble& tf, adouble xad, int iphase, Workspace workspace) { Eigen::Map<Eigen::Matrix<adouble, 6, 1>> eventVector(e, 6); // wrap pointer into eigen vector eventVector << myFinalState; // set final state values here }

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/ADGCMBK4E7SSHF3B7DVR37TSE5A4TANCNFSM4RBT42YA

.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub < https://github.com/PSOPT/psopt/issues/27#issuecomment-689719690>, or unsubscribe <

https://github.com/notifications/unsubscribe-auth/AC7OZDSR3AMVPWCM34WZZXTSE6563ANCNFSM4RBT42YA

.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27#issuecomment-696158712, or unsubscribe < https://github.com/notifications/unsubscribe-auth/ADGCMBI7ULTMS6THRPSWFNLSG5QPVANCNFSM4RBT42YA

.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub < https://github.com/PSOPT/psopt/issues/27#issuecomment-696164167>, or unsubscribe < https://github.com/notifications/unsubscribe-auth/AC7OZDWEK7J54PQ6A5OIYADSG5RQ3ANCNFSM4RBT42YA .

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/PSOPT/psopt/issues/27#issuecomment-696410780, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADGCMBJGG4MCZKBKWHMXXCDSG7HATANCNFSM4RBT42YA .