Simulink Interface added
Hello, I worked on a simulink interface for daqp that works without any parameters for dimensionality of the qp-problem. Everything is infered at compile time based on the input dimensions.
I am not so sure how to do the CI/CD workflow and there is a conceptional problem: To use the s-function in Simulink only the compiled file (the file "DAQP_sfunc.mexw64" (windows) is created with the "make_sfunc") is needed.
However for code generation in Simulink to a real-time target, the original DAQP-framework is needed and the relative path to the framework needs to be the same as in the current git. Therefore the creation of a "release build" is not a good idea since all the original c-code and folder structure would be needed and transferred too.
What do you think? Should we create a release build for the users that only want to use it in Simulink and not for code generation or would that confuse the users that want to generate code for real-time targets? Another idea would be that the release builds have the whole git-project and the pre-compiled mex-files similar to other open source projects like casadi.
Great work! Would there principally be a problem if one has an install script similar to DAQP's MATLAB interface? Where one runs a command in the MATLAB prompt, which will download the source code and compiles the S-Function?
This should be no problem, but the new install script would work for the simulink and matlab interface since it would download the whole framework and the matlab interface script would only work for matlab.
Therefore I would suggest a one-fits-all solution, where the whole framework is downloaded in both cases
When you say "one-fits-all solution", do you mean something that does not rely on MATLAB? Since Simulink is almost always used together with MATLAB, I think it is reasonable to install the interface through MATLAB.
I am thinking of something like passing an argument to the install_daqp function in MATLAB to download the whole framework (source code, S-function, and mex-files.) What do you think about that? Why I am hesitant of including everything by default in install_daqp is that I don't want to clutter up things for users that only want to use the MATLAB interface.
When you say "one-fits-all solution", do you mean something that does not rely on MATLAB? Since Simulink is almost always used together with MATLAB, I think it is reasonable to install the interface through MATLAB.
My idea is that the install_daqp function should download the whole framework with the compiled matlab mex and simulink mex file. After that, the needed folders (interface/matlab and interface/simulink) are added to the path.
I am thinking of something like passing an argument to the install_daqp function in MATLAB to download the whole framework (source code, S-function, and mex-files.) What do you think about that? Why I am hesitant of including everything by default in install_daqp is that I don't want to clutter up things for users that only want to use the MATLAB interface.
We could do something like this, maybe some kind of selection window with "matlab" and "matlab + simulink" as options. Then the "matlab" option would be the old procedure, whereas the "matlab + simulink" version would download the whole framework with the compiled matlab mex and simulink mex file. But I want to point out that other frameworks for matlab (like casadi) download the whole framework and I would prefere this version as well since it is easier to maintain and two versions could confuse the user and probably should be adressed in the documentation.
Hi guys, have you arrived to any conclusions? I have a similar interface for Simulink that I was going to propose, but I think @Don-Chris 's proposal is quite more elegant. If I can help you anyway getting this ahead please let me know.
Thanks for the support. I am currently waiting on feedback by @darnstrom. But if you are well versed in the CI/CD workflows, you could maybe help there?
Is it possible to make the S-function handle cases when the user does not provide complete information @Don-Chris ? For example, if blower is not given (which should default to a vector of -Infs) and if sense is not given (which should default to a vector of 0s)
I looked into it and yes there is a way to do it. Can you tell me, what dimensions and values are the default, if one or multiple inputs are missing?
First idea:
- sense missing: get dimension from b_lower, sense = zeros
- b_upper missing: get dimension from b_lower, b_upper = infs
- b_lower missing: get dimension from b_upper, b_lower = -infs
- sense and b_upper missing: get dimension from b_lower, sense = zeros, b_upper = infs
- sense, b_upper, b_lower missing: ??
- sense and b_lower missing: get dimension from b_upper, sense = zeros, b_lower = -infs
- A missing: ?
- A and sense is missing: ?
- H/g should never miss?
An additional thing: I understand that you don't want examples. However maybe we should add a Simulink-Library with these blocks from my example so that it is easier for non-experts?
Thanks for looking into it!
I think the default for sense, bupper, and blower are the most relevant, and the one you suggest are what I had in mind.
Regarding the example. I mainly removed it because I could not get the example to run on my own computer (I do not know why, maybe because it was created with another OS or version of Simulink?)
I agree that we should add blocks to make it easier for users.
One thing with the interface that is suboptimal is the reliance on daqp_quadprog, which required memory to be allocated dynamically for the generated C-code. The ideal thing would be to first set up a workspace and then call daqp_ldp, as I did here.
Hey @darnstrom, I changed what you asked for in my latest commit and I added new unit tests. It is similar to your first unit test and it calls daqp in simulink and then the primal_errors, dual_errors and f_val_errors are calculated.
Here, I first realized, that the dual_error and primal_error is wrong and I think it is wrong because I get the wrong lambda and f_val. Could you check if I got the right values from the work-object in DAQP_sfunc.c in lines 618-626?
@darnstrom I fixed it today, I used daqp_extract_result() since the f_val in the Workspace seems to be wrong. Now primal_errors, dual_errors and f_val_errors are correct.
Further questions:
- Should "eps_prox" be added as a parameter or other settings?
- Should we add daqp_bnb or daqp_prox for simulink? Should the switch happen through a parameter?
- What kind of unit tests should we add?
Looks great! Thank you very much for all your work. The daqp_prox/daqp_bnb could be added, but would require some modifications to the sfunc (I think it is mainly a metter of calling daqp_solve rather than daqp_ldp.) Adding support for "eps_prox" as a parameter would be nice to allow for the user to regularize the QP.
Now we just have to iron out how we want to include the interface in the CI/CD workflow before merging...
The daqp_prox/daqp_bnb could be added, but would require some modifications to the sfunc (I think it is mainly a metter of calling daqp_solve rather than daqp_ldp.) Adding support for "eps_prox" as a parameter would be nice to allow for the user to regularize the QP.
Okay, I will try my best in the next few days.
Now we just have to iron out how we want to include the interface in the CI/CD workflow before merging...
Yeah... I think it should be your decision to make. There are a lot of options and no wrong decisions. My opinion is that the command:
websave('install_daqp','https://raw.githubusercontent.com/darnstrom/daqp/master/interfaces/daqp-matlab/install_daqp.m')
install_daqp
should install the whole framework with all c files to that it automatically works for matlab, simulink and simulink with codegeneration. But again, you should decide.
@Don-Chris What do you think about merging this? I will release v0.7.0 soon, and I think it would be nice to include your work there. For the installation, I think it is enough for now to let the user run make_sfunc themselves from the source code. This would ensure that the user can do code generation.
@Don-Chris What do you think about merging this? I will release v0.7.0 soon, and I think it would be nice to include your work there. For the installation, I think it is enough for now to let the user run
make_sfuncthemselves from the source code. This would ensure that the user can do code generation.
I added a copy-and-paste snippet in the installation section of the documentation to make it straightforward to the user.
@darnstrom Sounds good! if you need any help in the future, just contact me.
@darnstrom Sounds good! if you need any help in the future, just contact me.
Great! Thank again for your contribution, it is very much appreciated :)