move all third party stuff into third_party/ (#26853)

* mv fastcluster

* move msm_kgsl.h

* camerad include

* update path

* mv pyextra

* fix tici build

* add acados_template to release build

Co-authored-by: Comma Device <device@comma.ai>
old-commit-hash: cd8e03d53e
beeps
Adeeb Shihadeh 2 years ago committed by GitHub
parent 4d1e15b85c
commit b3e47c691b
  1. 12
      .pre-commit-config.yaml
  2. 1
      Dockerfile.openpilot
  3. 1
      README.md
  4. 5
      SConstruct
  5. 2
      docs/Makefile
  6. 1
      docs/docker/Dockerfile
  7. 2
      launch_chffrplus.sh
  8. 2
      mypy.ini
  9. 3
      pyextra/.gitignore
  10. 3
      pyextra/acados_template/.gitignore
  11. 3
      pyextra/acados_template/__init__.py
  12. 3
      pyextra/acados_template/acados_layout.json
  13. 3
      pyextra/acados_template/acados_model.py
  14. 3
      pyextra/acados_template/acados_ocp.py
  15. 3
      pyextra/acados_template/acados_ocp_solver.py
  16. 3
      pyextra/acados_template/acados_ocp_solver_pyx.pyx
  17. 3
      pyextra/acados_template/acados_sim.py
  18. 3
      pyextra/acados_template/acados_sim_layout.json
  19. 3
      pyextra/acados_template/acados_sim_solver.py
  20. 3
      pyextra/acados_template/acados_solver_common.pxd
  21. 3
      pyextra/acados_template/builders.py
  22. 3
      pyextra/acados_template/c_templates_tera/CMakeLists.in.txt
  23. 3
      pyextra/acados_template/c_templates_tera/CPPLINT.cfg
  24. 3
      pyextra/acados_template/c_templates_tera/Makefile.in
  25. 3
      pyextra/acados_template/c_templates_tera/acados_mex_create.in.c
  26. 3
      pyextra/acados_template/c_templates_tera/acados_mex_free.in.c
  27. 3
      pyextra/acados_template/c_templates_tera/acados_mex_set.in.c
  28. 3
      pyextra/acados_template/c_templates_tera/acados_mex_solve.in.c
  29. 3
      pyextra/acados_template/c_templates_tera/acados_sim_solver.in.c
  30. 3
      pyextra/acados_template/c_templates_tera/acados_sim_solver.in.h
  31. 3
      pyextra/acados_template/c_templates_tera/acados_sim_solver_sfun.in.c
  32. 3
      pyextra/acados_template/c_templates_tera/acados_solver.in.c
  33. 3
      pyextra/acados_template/c_templates_tera/acados_solver.in.h
  34. 3
      pyextra/acados_template/c_templates_tera/acados_solver.in.pxd
  35. 3
      pyextra/acados_template/c_templates_tera/acados_solver_sfun.in.c
  36. 3
      pyextra/acados_template/c_templates_tera/cost_y_0_fun.in.h
  37. 3
      pyextra/acados_template/c_templates_tera/cost_y_e_fun.in.h
  38. 3
      pyextra/acados_template/c_templates_tera/cost_y_fun.in.h
  39. 3
      pyextra/acados_template/c_templates_tera/external_cost.in.h
  40. 3
      pyextra/acados_template/c_templates_tera/external_cost_0.in.h
  41. 3
      pyextra/acados_template/c_templates_tera/external_cost_e.in.h
  42. 3
      pyextra/acados_template/c_templates_tera/h_constraint.in.h
  43. 3
      pyextra/acados_template/c_templates_tera/h_e_constraint.in.h
  44. 3
      pyextra/acados_template/c_templates_tera/main.in.c
  45. 3
      pyextra/acados_template/c_templates_tera/main_mex.in.c
  46. 3
      pyextra/acados_template/c_templates_tera/main_sim.in.c
  47. 3
      pyextra/acados_template/c_templates_tera/make_main_mex.in.m
  48. 3
      pyextra/acados_template/c_templates_tera/make_mex.in.m
  49. 3
      pyextra/acados_template/c_templates_tera/make_sfun.in.m
  50. 3
      pyextra/acados_template/c_templates_tera/make_sfun_sim.in.m
  51. 3
      pyextra/acados_template/c_templates_tera/mex_solver.in.m
  52. 3
      pyextra/acados_template/c_templates_tera/model.in.h
  53. 3
      pyextra/acados_template/c_templates_tera/phi_constraint.in.h
  54. 3
      pyextra/acados_template/c_templates_tera/phi_e_constraint.in.h
  55. 3
      pyextra/acados_template/generate_c_code_constraint.py
  56. 3
      pyextra/acados_template/generate_c_code_discrete_dynamics.py
  57. 3
      pyextra/acados_template/generate_c_code_explicit_ode.py
  58. 3
      pyextra/acados_template/generate_c_code_external_cost.py
  59. 3
      pyextra/acados_template/generate_c_code_gnsf.py
  60. 3
      pyextra/acados_template/generate_c_code_implicit_ode.py
  61. 3
      pyextra/acados_template/generate_c_code_nls_cost.py
  62. 3
      pyextra/acados_template/simulink_default_opts.json
  63. 3
      pyextra/acados_template/utils.py
  64. 11
      release/files_common
  65. 6
      selfdrive/controls/lib/lateral_mpc_lib/SConscript
  66. 2
      selfdrive/controls/lib/lateral_mpc_lib/lat_mpc.py
  67. 6
      selfdrive/controls/lib/longitudinal_mpc_lib/SConscript
  68. 2
      selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py
  69. 2
      selfdrive/controls/radard.py
  70. 4
      selfdrive/controls/tests/test_clustering.py
  71. 2
      selfdrive/manager/manager.py
  72. 3
      selfdrive/modeld/thneed/include/msm_kgsl.h
  73. 2
      selfdrive/modeld/thneed/thneed.h
  74. 14
      system/camerad/SConscript
  75. 1
      third_party/.gitignore
  76. 2
      third_party/SConscript
  77. 6
      third_party/acados/acados_template/.gitignore
  78. 43
      third_party/acados/acados_template/__init__.py
  79. 804
      third_party/acados/acados_template/acados_layout.json
  80. 167
      third_party/acados/acados_template/acados_model.py
  81. 2955
      third_party/acados/acados_template/acados_ocp.py
  82. 1818
      third_party/acados/acados_template/acados_ocp_solver.py
  83. 707
      third_party/acados/acados_template/acados_ocp_solver_pyx.pyx
  84. 331
      third_party/acados/acados_template/acados_sim.py
  85. 47
      third_party/acados/acados_template/acados_sim_layout.json
  86. 454
      third_party/acados/acados_template/acados_sim_solver.py
  87. 103
      third_party/acados/acados_template/acados_solver_common.pxd
  88. 116
      third_party/acados/acados_template/builders.py
  89. 374
      third_party/acados/acados_template/c_templates_tera/CMakeLists.in.txt
  90. 1
      third_party/acados/acados_template/c_templates_tera/CPPLINT.cfg
  91. 406
      third_party/acados/acados_template/c_templates_tera/Makefile.in
  92. 387
      third_party/acados/acados_template/c_templates_tera/acados_mex_create.in.c
  93. 70
      third_party/acados/acados_template/c_templates_tera/acados_mex_free.in.c
  94. 570
      third_party/acados/acados_template/c_templates_tera/acados_mex_set.in.c
  95. 59
      third_party/acados/acados_template/c_templates_tera/acados_mex_solve.in.c
  96. 508
      third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.c
  97. 103
      third_party/acados/acados_template/c_templates_tera/acados_sim_solver.in.h
  98. 233
      third_party/acados/acados_template/c_templates_tera/acados_sim_solver_sfun.in.c
  99. 2495
      third_party/acados/acados_template/c_templates_tera/acados_solver.in.c
  100. 217
      third_party/acados/acados_template/c_templates_tera/acados_solver.in.h
  101. Some files were not shown because too many files have changed in this diff Show More

@ -7,7 +7,7 @@ repos:
rev: v4.1.0 rev: v4.1.0
hooks: hooks:
- id: check-ast - id: check-ast
exclude: '^(pyextra)/' exclude: '^(third_party)/'
- id: check-json - id: check-json
- id: check-xml - id: check-xml
- id: check-yaml - id: check-yaml
@ -19,7 +19,7 @@ repos:
rev: v2.2.1 rev: v2.2.1
hooks: hooks:
- id: codespell - id: codespell
exclude: '^(pyextra/)|(third_party/)|(body/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)|(include/)|(selfdrive/ui/translations/.*.ts)|(selfdrive/controls/lib/cluster)' exclude: '^(third_party/)|(body/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)|(selfdrive/ui/translations/.*.ts)'
args: args:
# if you've got a short variable name that's getting flagged, add it here # if you've got a short variable name that's getting flagged, add it here
- -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup - -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup
@ -31,12 +31,12 @@ repos:
entry: mypy entry: mypy
language: system language: system
types: [python] types: [python]
exclude: '^(pyextra/)|(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/)' exclude: '^(third_party/)|(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/)'
- repo: https://github.com/PyCQA/flake8 - repo: https://github.com/PyCQA/flake8
rev: 4.0.1 rev: 4.0.1
hooks: hooks:
- id: flake8 - id: flake8
exclude: '^(pyextra/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(selfdrive/debug/)/' exclude: '^(third_party/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(selfdrive/debug/)/'
additional_dependencies: ['flake8-no-implicit-concat'] additional_dependencies: ['flake8-no-implicit-concat']
args: args:
- --indent-size=2 - --indent-size=2
@ -51,7 +51,7 @@ repos:
entry: pylint entry: pylint
language: system language: system
types: [python] types: [python]
exclude: '^(pyextra/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(laika_repo/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)' exclude: '^(third_party/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(laika_repo/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)'
args: args:
- -j0 - -j0
- -rn - -rn
@ -64,7 +64,7 @@ repos:
entry: cppcheck entry: cppcheck
language: system language: system
types: [c++] types: [c++]
exclude: '^(third_party/)|(pyextra/)|(cereal/)|(body/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(tools/)|(selfdrive/modeld/thneed/debug/)|(selfdrive/modeld/test/)|(selfdrive/camerad/test/)|(installer/)' exclude: '^(third_party/)|(cereal/)|(body/)|(rednose/)|(rednose_repo/)|(opendbc/)|(panda/)|(tools/)|(selfdrive/modeld/thneed/debug/)|(selfdrive/modeld/test/)|(selfdrive/camerad/test/)|(installer/)'
args: args:
- --error-exitcode=1 - --error-exitcode=1
- --language=c++ - --language=c++

@ -10,7 +10,6 @@ WORKDIR ${OPENPILOT_PATH}
COPY SConstruct ${OPENPILOT_PATH} COPY SConstruct ${OPENPILOT_PATH}
COPY ./pyextra ${OPENPILOT_PATH}/pyextra
COPY ./third_party ${OPENPILOT_PATH}/third_party COPY ./third_party ${OPENPILOT_PATH}/third_party
COPY ./site_scons ${OPENPILOT_PATH}/site_scons COPY ./site_scons ${OPENPILOT_PATH}/site_scons
COPY ./laika ${OPENPILOT_PATH}/laika COPY ./laika ${OPENPILOT_PATH}/laika

@ -103,7 +103,6 @@ Directory Structure
├── opendbc # Files showing how to interpret data from cars ├── opendbc # Files showing how to interpret data from cars
├── panda # Code used to communicate on CAN ├── panda # Code used to communicate on CAN
├── third_party # External libraries ├── third_party # External libraries
├── pyextra # Extra python packages
└── system # Generic services └── system # Generic services
├── camerad # Driver to capture images from the camera sensors ├── camerad # Driver to capture images from the camera sensors
├── clocksd # Broadcasts current time ├── clocksd # Broadcasts current time

@ -71,10 +71,10 @@ if arch == "aarch64" and AGNOS:
lenv = { lenv = {
"PATH": os.environ['PATH'], "PATH": os.environ['PATH'],
"LD_LIBRARY_PATH": [Dir(f"#third_party/acados/{arch}/lib").abspath], "LD_LIBRARY_PATH": [Dir(f"#third_party/acados/{arch}/lib").abspath],
"PYTHONPATH": Dir("#").abspath + ":" + Dir("#pyextra/").abspath, "PYTHONPATH": Dir("#").abspath,
"ACADOS_SOURCE_DIR": Dir("#third_party/acados/include/acados").abspath, "ACADOS_SOURCE_DIR": Dir("#third_party/acados/include/acados").abspath,
"ACADOS_PYTHON_INTERFACE_PATH": Dir("#pyextra/acados_template").abspath, "ACADOS_PYTHON_INTERFACE_PATH": Dir("#third_party/acados/acados_template").abspath,
"TERA_PATH": Dir("#").abspath + f"/third_party/acados/{arch}/t_renderer" "TERA_PATH": Dir("#").abspath + f"/third_party/acados/{arch}/t_renderer"
} }
@ -422,7 +422,6 @@ SConscript(['common/transformations/SConscript'])
SConscript(['selfdrive/modeld/SConscript']) SConscript(['selfdrive/modeld/SConscript'])
SConscript(['selfdrive/controls/lib/cluster/SConscript'])
SConscript(['selfdrive/controls/lib/lateral_mpc_lib/SConscript']) SConscript(['selfdrive/controls/lib/lateral_mpc_lib/SConscript'])
SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript']) SConscript(['selfdrive/controls/lib/longitudinal_mpc_lib/SConscript'])

@ -41,7 +41,7 @@ clean:
@echo "Building rst files..." @echo "Building rst files..."
sphinx-apidoc -o "$(DOCSBUILDDIR)" ../ \ sphinx-apidoc -o "$(DOCSBUILDDIR)" ../ \
../xx ../laika_repo ../rednose_repo ../pyextra ../notebooks ../panda_jungle \ ../xx ../laika_repo ../rednose_repo ../notebooks ../panda_jungle \
../third_party \ ../third_party \
../panda/examples \ ../panda/examples \
../scripts \ ../scripts \

@ -11,7 +11,6 @@ WORKDIR ${OPENPILOT_PATH}
COPY SConstruct ${OPENPILOT_PATH} COPY SConstruct ${OPENPILOT_PATH}
COPY ./pyextra ${OPENPILOT_PATH}/pyextra
COPY ./third_party ${OPENPILOT_PATH}/third_party COPY ./third_party ${OPENPILOT_PATH}/third_party
COPY ./site_scons ${OPENPILOT_PATH}/site_scons COPY ./site_scons ${OPENPILOT_PATH}/site_scons
COPY ./laika ${OPENPILOT_PATH}/laika COPY ./laika ${OPENPILOT_PATH}/laika

@ -74,7 +74,7 @@ function launch {
# handle pythonpath # handle pythonpath
ln -sfn $(pwd) /data/pythonpath ln -sfn $(pwd) /data/pythonpath
export PYTHONPATH="$PWD:$PWD/pyextra" export PYTHONPATH="$PWD"
# hardware specific init # hardware specific init
agnos_init agnos_init

@ -2,7 +2,7 @@
python_version = 3.8 python_version = 3.8
plugins = numpy.typing.mypy_plugin plugins = numpy.typing.mypy_plugin
files = body, common, docs, scripts, selfdrive, site_scons, system, tools files = body, common, docs, scripts, selfdrive, site_scons, system, tools
exclude = ^(pyextra/)|(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/) exclude = ^(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/)
; third-party packages ; third-party packages
ignore_missing_imports = True ignore_missing_imports = True

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:094c25031dcfe5c288666671bc2012866293b3797ea53c796af798bda4c32f01
size 6

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:477f73573a50b1ae2740849e1aed4f8d353ead59116f95b897e8f620e8dbf31b
size 62

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dc3561a615e9baefc436c341280cac6634008a3b4a1773227604db4bf15b00d8
size 1971

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c116b7b6dae6a24ed2e3f55604edce722d6b86c9c25451e3ebe96c278f700cc9
size 14258

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:af19df99d9669672bfdc72d959bd444919a16c800f764873c923db425c26e70d
size 8289

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:00a5921254ea36f5cb0c80838bbc18bd7544990f4366979152c9a81cd0f302b8
size 101018

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:88265ec648408897af39ffe030823b009dde3cf56e588d3e717c60898432461c
size 84016

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:74e00646a8d51f0f4e8d0aa3d0e31160949f9a69df05b3d6b200ec3d60c560fb
size 29596

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ded40649250d2bb047cadb87584e5f2bbbd1c8b88276ca8d7909acd11454cfa9
size 12029

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7e21d44ed88590aaa52541839e2e8a8d008ceb5d82c7e2af9736df7b0f4eb5e9
size 759

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5969249d08301184bdfb0f90adeb23e518a892d38005c3b34ab1d32114f7820f
size 18884

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9166b8d29e88c53739da15d79f1a39ef007bac88b3219af171f738f57937286f
size 4335

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6e365ee08adc63a7d366dd283171bcd4b7f8e25825ea1d4fff09b36ba1ab754a
size 5454

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:259e9620ab3810be89004b58838f7a72edd4729928a899c3938d49c05bd10359
size 14199

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:082e141c424fbec023b900efb4f8d5d4e9f13634eb9e92bfe3b076d298585e68
size 78

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a5cfdabde7dd957124c1dcac1ad41c5144f7359b95498bbdc833d6e50bcbfea9
size 13858

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5a837cf6930efa41eb33fe32bd126ac5acea7afcac8ff3f6aee65e1ec5f974a3
size 17505

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cfab0ed0fac52bea3bb4dae81dd45f18764330f56d08dfed5c80d11923ad6b44
size 2555

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:cac8dd3c940a2b07d7104aeae846f4238a711a973da1667fa7bfdf91dea65cd4
size 19922

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1b5a8e5e2f2bf2456962c53842de00d236d67000b98cb61e48c968fe760eb6a5
size 2206

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f2a7be5c4f4c3afdcb7e252b72c90a8c0f92992c63bd97977f0470745feb2b6e
size 26035

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9299ceb39f13dfc8adac44ca5965713b64c76626f216de0d95505204229daed6
size 4445

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b1ee39cbcb027288fcaae01deaafba0f7ccfa863f3cf30a19a2e19860ab32e1f
size 7226

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:933ccc120f3eb064619c1b1b7c69dee3d48492d7bbcbede5480f5e146aae103c
size 101177

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:17274e2daf731a43a8e28cb8da55e767cffe907a16d9d1338271494649a77715
size 10723

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8c2eb33568b8c3a7fdc13bab1c922329b6e7c55b0e99eb93becc3853ab9c1ae8
size 4000

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6dad085983af45f46d30dd3ac45615fe0224c4821992de7b8d20b0fff625878a
size 29202

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:40972ebe4461c432b5802c7f4a0d2644b1c2a4727fbc629695cb30c5b71c4d68
size 3125

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1f26921d2f60b054e9c2a5ee3cef9663540e885131c66efba6be3b36857798c5
size 3125

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0baa31610dd9fcf653e4b2289911cb5251787606125ec101739570d28e818bf3
size 3081

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ba8e07cf179230f65ec8c46905ad969f82c41ed8580fb6d45c3376b416f1e52e
size 3354

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eb7fff7be0adbc647ec0af0e8bd68a2b10cbe7eacfc38d8c5665d856c66abb4e
size 3403

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7d7754b835a25342af3e1bb53887469daacd53675b1cc86c0562e7f46e5819bd
size 3402

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7b411cbfab08ca9ecbe1d75c80ab71f0551db4050cbcce7dae330f92c7473a4f
size 3272

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d1e42330752c441b92bc0f7cc4ef73cac67f8dba664e050cb88cdc682dd545f4
size 3317

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b0476231619e9b58e9d9f1ac38b23d7b07267af02b9fc059b3e96a881f692cbb
size 8044

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:2a6d9e4529cb352a13c65ea30dec561c5423cd191c32510099d9a6e0c2948966
size 6326

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:659efc1476d5b27bb6ade88223762fe65d2aa1e96bae0c1fdd7dec6e167fe02a
size 4677

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:148d43fb0fa9fa42fc571648c94a344d69e7c8e26b47d023b323773adddbb6f7
size 4293

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0df5010cd2c049661bb45da3ab20cfc78adeea15612bc710259e36d855a1800e
size 4558

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b8d2619181da8938064c8e867ae7b511e476002f6c33e73324f60ac88bea7f22
size 15658

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:eeb1550ed63d4d9d561a133db36c4d11c9d03634f466f2ab80ba54ac69dac83a
size 4496

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:4ac71216686385bcf4dedd49a2e4b85e510f36b9d1e1748245d0a7abefad0d9d
size 6185

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:64753b01879d27e824a86c26ca15b29956efa3b2a5f536dbe78220df4f01fbdc
size 10420

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:16ef8e23d19800aaf0bc433571c4b2da5a117a1128a3011c3208192880e80d3b
size 2321

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:da836e689945ebed0a730f6bbcd3a6922770a07216469cc4898bfcb4bb330c14
size 658

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e3ca280cc474c3fa50496ca7e21d3b7c918843c6c4f3737627538eb3a8847148
size 6728

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:90b41224841a3bc26fef52eed4f88b4a2c7e6c4ab08ebc3b943f45dde83847db
size 3702

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:148abc2a03f578abaea318edd1042c01d3bb04fc6d9e33b7cab0bab48d9ca53f
size 4418

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:df61d4a3b7c0e04bb02dab5408be15db88e293b481301febb129aedd12cd0cab
size 4337

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8ad9558c20c7bf4a526874c51204a86cc41b884d071ff55fab9c778a6f2ef999
size 4935

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:14938e8888f7fc72cbf0d1c8614d39952be8909aeb707975afb9b03e2aa817eb
size 5201

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:b76eeb34b5ff74e072d53cbd08e464ebab8361e805aa6063b23de821ea400287
size 3864

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:947332713be607beb2599a93f0d999b4019d096322766564fa1bcaed01b0eebd
size 778

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:122176a24fd4a96f0a14201ddea9883bf4ca279ba62aaec78c97bcf1eb3a3174
size 15953

@ -192,8 +192,6 @@ selfdrive/controls/lib/pid.py
selfdrive/controls/lib/radar_helpers.py selfdrive/controls/lib/radar_helpers.py
selfdrive/controls/lib/vehicle_model.py selfdrive/controls/lib/vehicle_model.py
selfdrive/controls/lib/cluster/*
selfdrive/controls/lib/lateral_mpc_lib/.gitignore selfdrive/controls/lib/lateral_mpc_lib/.gitignore
selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore selfdrive/controls/lib/longitudinal_mpc_lib/.gitignore
selfdrive/controls/lib/lateral_mpc_lib/* selfdrive/controls/lib/lateral_mpc_lib/*
@ -328,7 +326,6 @@ system/camerad/SConscript
system/camerad/main.cc system/camerad/main.cc
system/camerad/snapshot/* system/camerad/snapshot/*
system/camerad/include/*
system/camerad/cameras/camera_common.h system/camerad/cameras/camera_common.h
system/camerad/cameras/camera_common.cc system/camerad/cameras/camera_common.cc
system/camerad/cameras/sensor2_i2c.h system/camerad/cameras/sensor2_i2c.h
@ -384,7 +381,6 @@ selfdrive/modeld/thneed/thneed.h
selfdrive/modeld/thneed/thneed_common.cc selfdrive/modeld/thneed/thneed_common.cc
selfdrive/modeld/thneed/thneed_qcom2.cc selfdrive/modeld/thneed/thneed_qcom2.cc
selfdrive/modeld/thneed/serialize.cc selfdrive/modeld/thneed/serialize.cc
selfdrive/modeld/thneed/include/*
selfdrive/modeld/runners/snpemodel.cc selfdrive/modeld/runners/snpemodel.cc
selfdrive/modeld/runners/snpemodel.h selfdrive/modeld/runners/snpemodel.h
@ -412,8 +408,11 @@ selfdrive/assets/offroad/*
selfdrive/assets/sounds/* selfdrive/assets/sounds/*
selfdrive/assets/training/* selfdrive/assets/training/*
third_party/.gitignore
third_party/SConscript third_party/SConscript
third_party/cluster/*
third_party/linux/** third_party/linux/**
third_party/opencl/** third_party/opencl/**
@ -436,15 +435,13 @@ third_party/snpe/dsp**
third_party/acados/x86_64/** third_party/acados/x86_64/**
third_party/acados/larch64/** third_party/acados/larch64/**
third_party/acados/include/** third_party/acados/include/**
third_party/acados/acados_template/**
third_party/qt5/larch64/bin/** third_party/qt5/larch64/bin/**
scripts/update_now.sh scripts/update_now.sh
scripts/stop_updater.sh scripts/stop_updater.sh
pyextra/.gitignore
pyextra/acados_template/**
rednose/.gitignore rednose/.gitignore
rednose/** rednose/**
laika/** laika/**

@ -44,7 +44,7 @@ generated_files = [
] + build_files ] + build_files
acados_dir = '#third_party/acados' acados_dir = '#third_party/acados'
acados_templates_dir = '#pyextra/acados_template/c_templates_tera' acados_templates_dir = '#third_party/acados/acados_template/c_templates_tera'
source_list = ['lat_mpc.py', source_list = ['lat_mpc.py',
f'{acados_dir}/include/acados_c/ocp_nlp_interface.h', f'{acados_dir}/include/acados_c/ocp_nlp_interface.h',
@ -70,8 +70,8 @@ lib_solver = lenv.SharedLibrary(f"{gen}/acados_ocp_solver_lat",
LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e']) LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e'])
# generate cython stuff # generate cython stuff
acados_ocp_solver_pyx = File("#pyextra/acados_template/acados_ocp_solver_pyx.pyx") acados_ocp_solver_pyx = File("#third_party/acados/acados_template/acados_ocp_solver_pyx.pyx")
acados_ocp_solver_common = File("#pyextra/acados_template/acados_solver_common.pxd") acados_ocp_solver_common = File("#third_party/acados/acados_template/acados_solver_common.pxd")
libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd') libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd')
libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c') libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c')

@ -8,7 +8,7 @@ from common.realtime import sec_since_boot
from selfdrive.modeld.constants import T_IDXS from selfdrive.modeld.constants import T_IDXS
if __name__ == '__main__': # generating code if __name__ == '__main__': # generating code
from pyextra.acados_template import AcadosModel, AcadosOcp, AcadosOcpSolver from third_party.acados.acados_template import AcadosModel, AcadosOcp, AcadosOcpSolver
else: else:
from selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx import AcadosOcpSolverCython # pylint: disable=no-name-in-module, import-error from selfdrive.controls.lib.lateral_mpc_lib.c_generated_code.acados_ocp_solver_pyx import AcadosOcpSolverCython # pylint: disable=no-name-in-module, import-error

@ -51,7 +51,7 @@ generated_files = [
] + build_files ] + build_files
acados_dir = '#third_party/acados' acados_dir = '#third_party/acados'
acados_templates_dir = '#pyextra/acados_template/c_templates_tera' acados_templates_dir = '#third_party/acados/acados_template/c_templates_tera'
source_list = ['long_mpc.py', source_list = ['long_mpc.py',
f'{acados_dir}/include/acados_c/ocp_nlp_interface.h', f'{acados_dir}/include/acados_c/ocp_nlp_interface.h',
@ -77,8 +77,8 @@ lib_solver = lenv.SharedLibrary(f"{gen}/acados_ocp_solver_long",
LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e']) LIBS=['m', 'acados', 'hpipm', 'blasfeo', 'qpOASES_e'])
# generate cython stuff # generate cython stuff
acados_ocp_solver_pyx = File("#pyextra/acados_template/acados_ocp_solver_pyx.pyx") acados_ocp_solver_pyx = File("#third_party/acados/acados_template/acados_ocp_solver_pyx.pyx")
acados_ocp_solver_common = File("#pyextra/acados_template/acados_solver_common.pxd") acados_ocp_solver_common = File("#third_party/acados/acados_template/acados_solver_common.pxd")
libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd') libacados_ocp_solver_pxd = File(f'{gen}/acados_solver.pxd')
libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c') libacados_ocp_solver_c = File(f'{gen}/acados_ocp_solver_pyx.c')

@ -9,7 +9,7 @@ from selfdrive.modeld.constants import index_function
from selfdrive.controls.lib.radar_helpers import _LEAD_ACCEL_TAU from selfdrive.controls.lib.radar_helpers import _LEAD_ACCEL_TAU
if __name__ == '__main__': # generating code if __name__ == '__main__': # generating code
from pyextra.acados_template import AcadosModel, AcadosOcp, AcadosOcpSolver from third_party.acados.acados_template import AcadosModel, AcadosOcp, AcadosOcpSolver
else: else:
from selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx import AcadosOcpSolverCython # pylint: disable=no-name-in-module, import-error from selfdrive.controls.lib.longitudinal_mpc_lib.c_generated_code.acados_ocp_solver_pyx import AcadosOcpSolverCython # pylint: disable=no-name-in-module, import-error

@ -8,9 +8,9 @@ from cereal import car
from common.numpy_fast import interp from common.numpy_fast import interp
from common.params import Params from common.params import Params
from common.realtime import Ratekeeper, Priority, config_realtime_process from common.realtime import Ratekeeper, Priority, config_realtime_process
from selfdrive.controls.lib.cluster.fastcluster_py import cluster_points_centroid
from selfdrive.controls.lib.radar_helpers import Cluster, Track, RADAR_TO_CAMERA from selfdrive.controls.lib.radar_helpers import Cluster, Track, RADAR_TO_CAMERA
from system.swaglog import cloudlog from system.swaglog import cloudlog
from third_party.cluster.fastcluster_py import cluster_points_centroid
class KalmanParams(): class KalmanParams():

@ -7,8 +7,8 @@ from fastcluster import linkage_vector
from scipy.cluster import _hierarchy from scipy.cluster import _hierarchy
from scipy.spatial.distance import pdist from scipy.spatial.distance import pdist
from selfdrive.controls.lib.cluster.fastcluster_py import hclust, ffi from third_party.cluster.fastcluster_py import hclust, ffi
from selfdrive.controls.lib.cluster.fastcluster_py import cluster_points_centroid from third_party.cluster.fastcluster_py import cluster_points_centroid
def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None): def fcluster(Z, t, criterion='inconsistent', depth=2, R=None, monocrit=None):

@ -23,8 +23,6 @@ from system.version import is_dirty, get_commit, get_version, get_origin, get_sh
terms_version, training_version, is_tested_branch terms_version, training_version, is_tested_branch
sys.path.append(os.path.join(BASEDIR, "pyextra"))
def manager_init() -> None: def manager_init() -> None:
# update system time from panda # update system time from panda

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:089b21b377325c0b0f04b96b6ed4a8e5975b1c050191598cd64dc0a3a3565a71
size 45343

@ -12,7 +12,7 @@
#include <CL/cl.h> #include <CL/cl.h>
#include "selfdrive/modeld/thneed/include/msm_kgsl.h" #include "msm_kgsl.h"
using namespace std; using namespace std;

@ -2,17 +2,13 @@ Import('env', 'arch', 'cereal', 'messaging', 'common', 'gpucommon', 'visionipc')
libs = ['m', 'pthread', common, 'jpeg', 'OpenCL', 'yuv', cereal, messaging, 'zmq', 'capnp', 'kj', visionipc, gpucommon, 'atomic'] libs = ['m', 'pthread', common, 'jpeg', 'OpenCL', 'yuv', cereal, messaging, 'zmq', 'capnp', 'kj', visionipc, gpucommon, 'atomic']
cenv = env.Clone() camera_obj = env.Object(['cameras/camera_qcom2.cc', 'cameras/camera_common.cc', 'cameras/camera_util.cc'])
cenv['CPPPATH'].append('include/') env.Program('camerad', [
camera_obj = cenv.Object(['cameras/camera_qcom2.cc', 'cameras/camera_common.cc', 'cameras/camera_util.cc'])
cenv.Program('camerad', [
'main.cc', 'main.cc',
camera_obj, camera_obj,
], LIBS=libs) ], LIBS=libs)
if GetOption("test") and arch == "x86_64": if GetOption("test") and arch == "x86_64":
cenv.Program('test/ae_gray_test', [ env.Program('test/ae_gray_test',
'test/ae_gray_test.cc', ['test/ae_gray_test.cc', camera_obj],
camera_obj, LIBS=libs)
], LIBS=libs)

@ -0,0 +1 @@
*.pyc

@ -4,3 +4,5 @@ env.Library('json11', ['json11/json11.cpp'], CCFLAGS=env['CCFLAGS'] + ['-Wno-unq
env.Append(CPPPATH=[Dir('json11')]) env.Append(CPPPATH=[Dir('json11')])
env.Library('kaitai', ['kaitai/kaitaistream.cpp'], CPPDEFINES=['KS_STR_ENCODING_NONE']) env.Library('kaitai', ['kaitai/kaitaistream.cpp'], CPPDEFINES=['KS_STR_ENCODING_NONE'])
SConscript(['cluster/SConscript'])

@ -0,0 +1,6 @@
__pycache__/
# Cython intermediates
*_pyx.c
*_pyx.o
*_pyx.so

@ -0,0 +1,43 @@
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
from .acados_model import *
from .generate_c_code_explicit_ode import *
from .generate_c_code_implicit_ode import *
from .generate_c_code_constraint import *
from .generate_c_code_nls_cost import *
from .acados_ocp import *
from .acados_sim import *
from .acados_ocp_solver import *
from .acados_sim_solver import *
from .utils import *

@ -0,0 +1,804 @@
{
"code_export_directory": [
"str"
],
"acados_include_path": [
"str"
],
"cython_include_dirs": [
"str"
],
"model": {
"name" : [
"str"
],
"dyn_ext_fun_type" : [
"str"
],
"dyn_source_discrete" : [
"str"
],
"dyn_disc_fun_jac_hess" : [
"str"
],
"dyn_disc_fun_jac" : [
"str"
],
"dyn_disc_fun" : [
"str"
],
"gnsf" : {
"nontrivial_f_LO": [
"int"
],
"purely_linear": [
"int"
]
}
},
"parameter_values": [
"ndarray",
[
"np"
]
],
"acados_lib_path": [
"str"
],
"problem_class": [
"str"
],
"constraints": {
"constr_type": [
"str"
],
"constr_type_e": [
"str"
],
"lbx": [
"ndarray",
[
"nbx"
]
],
"lbu": [
"ndarray",
[
"nbu"
]
],
"ubx": [
"ndarray",
[
"nbx"
]
],
"ubu": [
"ndarray",
[
"nbu"
]
],
"idxbx": [
"ndarray",
[
"nbx"
]
],
"idxbu": [
"ndarray",
[
"nbu"
]
],
"lbx_e": [
"ndarray",
[
"nbx_e"
]
],
"ubx_e": [
"ndarray",
[
"nbx_e"
]
],
"idxbx_e": [
"ndarray",
[
"nbx_e"
]
],
"lbx_0": [
"ndarray",
[
"nbx_0"
]
],
"ubx_0": [
"ndarray",
[
"nbx_0"
]
],
"idxbx_0": [
"ndarray",
[
"nbx_0"
]
],
"idxbxe_0": [
"ndarray",
[
"nbxe_0"
]
],
"lg": [
"ndarray",
[
"ng"
]
],
"ug": [
"ndarray",
[
"ng"
]
],
"D": [
"ndarray",
[
"ng",
"nu"
]
],
"C": [
"ndarray",
[
"ng",
"nx"
]
],
"C_e": [
"ndarray",
[
"ng_e",
"nx"
]
],
"lg_e": [
"ndarray",
[
"ng_e"
]
],
"ug_e": [
"ndarray",
[
"ng_e"
]
],
"lh": [
"ndarray",
[
"nh"
]
],
"uh": [
"ndarray",
[
"nh"
]
],
"lh_e": [
"ndarray",
[
"nh_e"
]
],
"uh_e": [
"ndarray",
[
"nh_e"
]
],
"lphi": [
"ndarray",
[
"nphi"
]
],
"uphi": [
"ndarray",
[
"nphi"
]
],
"lphi_e": [
"ndarray",
[
"nphi_e"
]
],
"uphi_e": [
"ndarray",
[
"nphi_e"
]
],
"lsbx": [
"ndarray",
[
"nsbx"
]
],
"usbx": [
"ndarray",
[
"nsbx"
]
],
"lsbu": [
"ndarray",
[
"nsbu"
]
],
"usbu": [
"ndarray",
[
"nsbu"
]
],
"idxsbx": [
"ndarray",
[
"nsbx"
]
],
"idxsbu": [
"ndarray",
[
"nsbu"
]
],
"lsbx_e": [
"ndarray",
[
"nsbx_e"
]
],
"usbx_e": [
"ndarray",
[
"nsbx_e"
]
],
"idxsbx_e": [
"ndarray",
[
"nsbx_e"
]
],
"lsg": [
"ndarray",
[
"nsg"
]
],
"usg": [
"ndarray",
[
"nsg"
]
],
"idxsg": [
"ndarray",
[
"nsg"
]
],
"lsg_e": [
"ndarray",
[
"nsg_e"
]
],
"usg_e": [
"ndarray",
[
"nsg_e"
]
],
"idxsg_e": [
"ndarray",
[
"nsg_e"
]
],
"lsh": [
"ndarray",
[
"nsh"
]
],
"ush": [
"ndarray",
[
"nsh"
]
],
"idxsh": [
"ndarray",
[
"nsh"
]
],
"lsh_e": [
"ndarray",
[
"nsh_e"
]
],
"ush_e": [
"ndarray",
[
"nsh_e"
]
],
"idxsh_e": [
"ndarray",
[
"nsh_e"
]
],
"lsphi": [
"ndarray",
[
"nsphi"
]
],
"usphi": [
"ndarray",
[
"nsphi"
]
],
"idxsphi": [
"ndarray",
[
"nsphi"
]
],
"lsphi_e": [
"ndarray",
[
"nsphi_e"
]
],
"usphi_e": [
"ndarray",
[
"nsphi_e"
]
],
"idxsphi_e": [
"ndarray",
[
"nsphi_e"
]
]
},
"cost": {
"cost_type_0": [
"str"
],
"cost_type": [
"str"
],
"cost_type_e": [
"str"
],
"cost_ext_fun_type_0": [
"str"
],
"cost_ext_fun_type": [
"str"
],
"cost_ext_fun_type_e": [
"str"
],
"Vu_0": [
"ndarray",
[
"ny_0",
"nu"
]
],
"Vu": [
"ndarray",
[
"ny",
"nu"
]
],
"Vx_0": [
"ndarray",
[
"ny_0",
"nx"
]
],
"Vx": [
"ndarray",
[
"ny",
"nx"
]
],
"Vx_e": [
"ndarray",
[
"ny_e",
"nx"
]
],
"Vz_0": [
"ndarray",
[
"ny_0",
"nz"
]
],
"Vz": [
"ndarray",
[
"ny",
"nz"
]
],
"W_0": [
"ndarray",
[
"ny_0",
"ny_0"
]
],
"W": [
"ndarray",
[
"ny",
"ny"
]
],
"Zl": [
"ndarray",
[
"ns"
]
],
"Zu": [
"ndarray",
[
"ns"
]
],
"zl": [
"ndarray",
[
"ns"
]
],
"zu": [
"ndarray",
[
"ns"
]
],
"W_e": [
"ndarray",
[
"ny_e",
"ny_e"
]
],
"yref_0": [
"ndarray",
[
"ny_0"
]
],
"yref": [
"ndarray",
[
"ny"
]
],
"yref_e": [
"ndarray",
[
"ny_e"
]
],
"Zl_e": [
"ndarray",
[
"ns_e"
]
],
"Zu_e": [
"ndarray",
[
"ns_e"
]
],
"zl_e": [
"ndarray",
[
"ns_e"
]
],
"zu_e": [
"ndarray",
[
"ns_e"
]
]
},
"dims": {
"N": [
"int"
],
"nbu": [
"int"
],
"nbx": [
"int"
],
"nsbu": [
"int"
],
"nsbx": [
"int"
],
"nsbx_e": [
"int"
],
"nbx_0": [
"int"
],
"nbx_e": [
"int"
],
"nbxe_0": [
"int"
],
"nsg": [
"int"
],
"nsg_e": [
"int"
],
"nsh": [
"int"
],
"nsh_e": [
"int"
],
"nsphi": [
"int"
],
"nsphi_e": [
"int"
],
"ns": [
"int"
],
"ns_e": [
"int"
],
"ng": [
"int"
],
"ng_e": [
"int"
],
"np": [
"int"
],
"nr": [
"int"
],
"nr_e": [
"int"
],
"nh": [
"int"
],
"nh_e": [
"int"
],
"nphi": [
"int"
],
"nphi_e": [
"int"
],
"nu": [
"int"
],
"nx": [
"int"
],
"ny": [
"int"
],
"ny_0": [
"int"
],
"ny_e": [
"int"
],
"nz": [
"int"
],
"gnsf_nx1": [
"int"
],
"gnsf_nz1": [
"int"
],
"gnsf_nuhat": [
"int"
],
"gnsf_ny": [
"int"
],
"gnsf_nout": [
"int"
]
},
"solver_options": {
"time_steps": [
"ndarray",
[
"N"
]
],
"hessian_approx": [
"str"
],
"hpipm_mode": [
"str"
],
"regularize_method": [
"str"
],
"integrator_type": [
"str"
],
"nlp_solver_type": [
"str"
],
"collocation_type": [
"str"
],
"globalization": [
"str"
],
"nlp_solver_step_length": [
"float"
],
"levenberg_marquardt": [
"float"
],
"qp_solver": [
"str"
],
"tf": [
"float"
],
"Tsim": [
"float"
],
"alpha_min": [
"float"
],
"alpha_reduction": [
"float"
],
"line_search_use_sufficient_descent": [
"int"
],
"globalization_use_SOC": [
"int"
],
"full_step_dual": [
"int"
],
"eps_sufficient_descent": [
"float"
],
"sim_method_num_stages": [
"ndarray",
[
"N"
]
],
"sim_method_num_steps": [
"ndarray",
[
"N"
]
],
"sim_method_newton_iter": [
"int"
],
"sim_method_jac_reuse": [
"ndarray",
[
"N"
]
],
"qp_solver_cond_N": [
"int"
],
"qp_solver_warm_start": [
"int"
],
"qp_solver_tol_stat": [
"float"
],
"qp_solver_tol_eq": [
"float"
],
"qp_solver_tol_ineq": [
"float"
],
"qp_solver_tol_comp": [
"float"
],
"qp_solver_iter_max": [
"int"
],
"nlp_solver_tol_stat": [
"float"
],
"nlp_solver_tol_eq": [
"float"
],
"nlp_solver_tol_ineq": [
"float"
],
"nlp_solver_tol_comp": [
"float"
],
"nlp_solver_max_iter": [
"int"
],
"print_level": [
"int"
],
"initialize_t_slacks": [
"int"
],
"exact_hess_cost": [
"int"
],
"exact_hess_constr": [
"int"
],
"exact_hess_dyn": [
"int"
],
"ext_cost_num_hess": [
"int"
],
"model_external_shared_lib_dir": [
"str"
],
"model_external_shared_lib_name": [
"str"
]
}
}

@ -0,0 +1,167 @@
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
class AcadosModel():
"""
Class containing all the information to code generate the external CasADi functions
that are needed when creating an acados ocp solver or acados integrator.
Thus, this class contains:
a) the :py:attr:`name` of the model,
b) all CasADi variables/expressions needed in the CasADi function generation process.
"""
def __init__(self):
## common for OCP and Integrator
self.name = None
"""
The model name is used for code generation. Type: string. Default: :code:`None`
"""
self.x = None #: CasADi variable describing the state of the system; Default: :code:`None`
self.xdot = None #: CasADi variable describing the derivative of the state wrt time; Default: :code:`None`
self.u = None #: CasADi variable describing the input of the system; Default: :code:`None`
self.z = [] #: CasADi variable describing the algebraic variables of the DAE; Default: :code:`empty`
self.p = [] #: CasADi variable describing parameters of the DAE; Default: :code:`empty`
# dynamics
self.f_impl_expr = None
"""
CasADi expression for the implicit dynamics :math:`f_\\text{impl}(\dot{x}, x, u, z, p) = 0`.
Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.integrator_type` == 'IRK'.
Default: :code:`None`
"""
self.f_expl_expr = None
"""
CasADi expression for the explicit dynamics :math:`\dot{x} = f_\\text{expl}(x, u, p)`.
Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.integrator_type` == 'ERK'.
Default: :code:`None`
"""
self.disc_dyn_expr = None
"""
CasADi expression for the discrete dynamics :math:`x_{+} = f_\\text{disc}(x, u, p)`.
Used if :py:attr:`acados_template.acados_ocp.AcadosOcpOptions.integrator_type` == 'DISCRETE'.
Default: :code:`None`
"""
self.dyn_ext_fun_type = 'casadi' #: type of external functions for dynamics module; 'casadi' or 'generic'; Default: 'casadi'
self.dyn_source_discrete = None #: name of source file for discrete dyanamics; Default: :code:`None`
self.dyn_disc_fun_jac_hess = None #: name of function discrete dyanamics + jacobian and hessian; Default: :code:`None`
self.dyn_disc_fun_jac = None #: name of function discrete dyanamics + jacobian; Default: :code:`None`
self.dyn_disc_fun = None #: name of function discrete dyanamics; Default: :code:`None`
# for GNSF models
self.gnsf = {'nontrivial_f_LO': 1, 'purely_linear': 0}
"""
dictionary containing information on GNSF structure needed when rendering templates.
Contains integers `nontrivial_f_LO`, `purely_linear`.
"""
## for OCP
# constraints
self.con_h_expr = None #: CasADi expression for the constraint :math:`h`; Default: :code:`None`
self.con_phi_expr = None #: CasADi expression for the constraint phi; Default: :code:`None`
self.con_r_expr = None #: CasADi expression for the constraint phi(r); Default: :code:`None`
self.con_r_in_phi = None
# terminal
self.con_h_expr_e = None #: CasADi expression for the terminal constraint :math:`h^e`; Default: :code:`None`
self.con_r_expr_e = None #: CasADi expression for the terminal constraint; Default: :code:`None`
self.con_phi_expr_e = None #: CasADi expression for the terminal constraint; Default: :code:`None`
self.con_r_in_phi_e = None
# cost
self.cost_y_expr = None #: CasADi expression for nonlinear least squares; Default: :code:`None`
self.cost_y_expr_e = None #: CasADi expression for nonlinear least squares, terminal; Default: :code:`None`
self.cost_y_expr_0 = None #: CasADi expression for nonlinear least squares, initial; Default: :code:`None`
self.cost_expr_ext_cost = None #: CasADi expression for external cost; Default: :code:`None`
self.cost_expr_ext_cost_e = None #: CasADi expression for external cost, terminal; Default: :code:`None`
self.cost_expr_ext_cost_0 = None #: CasADi expression for external cost, initial; Default: :code:`None`
self.cost_expr_ext_cost_custom_hess = None #: CasADi expression for custom hessian (only for external cost); Default: :code:`None`
self.cost_expr_ext_cost_custom_hess_e = None #: CasADi expression for custom hessian (only for external cost), terminal; Default: :code:`None`
self.cost_expr_ext_cost_custom_hess_0 = None #: CasADi expression for custom hessian (only for external cost), initial; Default: :code:`None`
def acados_model_strip_casadi_symbolics(model):
out = model
if 'f_impl_expr' in out.keys():
del out['f_impl_expr']
if 'f_expl_expr' in out.keys():
del out['f_expl_expr']
if 'disc_dyn_expr' in out.keys():
del out['disc_dyn_expr']
if 'x' in out.keys():
del out['x']
if 'xdot' in out.keys():
del out['xdot']
if 'u' in out.keys():
del out['u']
if 'z' in out.keys():
del out['z']
if 'p' in out.keys():
del out['p']
# constraints
if 'con_phi_expr' in out.keys():
del out['con_phi_expr']
if 'con_h_expr' in out.keys():
del out['con_h_expr']
if 'con_r_expr' in out.keys():
del out['con_r_expr']
if 'con_r_in_phi' in out.keys():
del out['con_r_in_phi']
# terminal
if 'con_phi_expr_e' in out.keys():
del out['con_phi_expr_e']
if 'con_h_expr_e' in out.keys():
del out['con_h_expr_e']
if 'con_r_expr_e' in out.keys():
del out['con_r_expr_e']
if 'con_r_in_phi_e' in out.keys():
del out['con_r_in_phi_e']
# cost
if 'cost_y_expr' in out.keys():
del out['cost_y_expr']
if 'cost_y_expr_e' in out.keys():
del out['cost_y_expr_e']
if 'cost_y_expr_0' in out.keys():
del out['cost_y_expr_0']
if 'cost_expr_ext_cost' in out.keys():
del out['cost_expr_ext_cost']
if 'cost_expr_ext_cost_e' in out.keys():
del out['cost_expr_ext_cost_e']
if 'cost_expr_ext_cost_0' in out.keys():
del out['cost_expr_ext_cost_0']
if 'cost_expr_ext_cost_custom_hess' in out.keys():
del out['cost_expr_ext_cost_custom_hess']
if 'cost_expr_ext_cost_custom_hess_e' in out.keys():
del out['cost_expr_ext_cost_custom_hess_e']
if 'cost_expr_ext_cost_custom_hess_0' in out.keys():
del out['cost_expr_ext_cost_custom_hess_0']
return out

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,707 @@
# -*- coding: future_fstrings -*-
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
# cython: language_level=3
# cython: profile=False
# distutils: language=c
cimport cython
from libc cimport string
cimport acados_solver_common
# TODO: make this import more clear? it is not a general solver, but problem specific.
cimport acados_solver
cimport numpy as cnp
import os
from datetime import datetime
import numpy as np
cdef class AcadosOcpSolverCython:
"""
Class to interact with the acados ocp solver C object.
"""
cdef acados_solver.nlp_solver_capsule *capsule
cdef void *nlp_opts
cdef acados_solver_common.ocp_nlp_dims *nlp_dims
cdef acados_solver_common.ocp_nlp_config *nlp_config
cdef acados_solver_common.ocp_nlp_out *nlp_out
cdef acados_solver_common.ocp_nlp_out *sens_out
cdef acados_solver_common.ocp_nlp_in *nlp_in
cdef acados_solver_common.ocp_nlp_solver *nlp_solver
cdef int status
cdef bint solver_created
cdef str model_name
cdef int N
cdef str nlp_solver_type
def __cinit__(self, model_name, nlp_solver_type, N):
self.solver_created = False
self.N = N
self.model_name = model_name
self.nlp_solver_type = nlp_solver_type
# create capsule
self.capsule = acados_solver.acados_create_capsule()
# create solver
assert acados_solver.acados_create(self.capsule) == 0
self.solver_created = True
# get pointers solver
self.__get_pointers_solver()
self.status = 0
def __get_pointers_solver(self):
"""
Private function to get the pointers for solver
"""
# get pointers solver
self.nlp_opts = acados_solver.acados_get_nlp_opts(self.capsule)
self.nlp_dims = acados_solver.acados_get_nlp_dims(self.capsule)
self.nlp_config = acados_solver.acados_get_nlp_config(self.capsule)
self.nlp_out = acados_solver.acados_get_nlp_out(self.capsule)
self.sens_out = acados_solver.acados_get_sens_out(self.capsule)
self.nlp_in = acados_solver.acados_get_nlp_in(self.capsule)
self.nlp_solver = acados_solver.acados_get_nlp_solver(self.capsule)
def solve(self):
"""
Solve the ocp with current input.
"""
return acados_solver.acados_solve(self.capsule)
def reset(self):
"""
Sets current iterate to all zeros.
"""
return acados_solver.acados_reset(self.capsule)
def set_new_time_steps(self, new_time_steps):
"""
Set new time steps.
Recreates the solver if N changes.
:param new_time_steps: 1 dimensional np array of new time steps for the solver
.. note:: This allows for different use-cases: either set a new size of time-steps or a new distribution of
the shooting nodes without changing the number, e.g., to reach a different final time. Both cases
do not require a new code export and compilation.
"""
raise NotImplementedError("AcadosOcpSolverCython: does not support set_new_time_steps() since it is only a prototyping feature")
# # unlikely but still possible
# if not self.solver_created:
# raise Exception('Solver was not yet created!')
# ## check if time steps really changed in value
# # get time steps
# cdef cnp.ndarray[cnp.float64_t, ndim=1] old_time_steps = np.ascontiguousarray(np.zeros((self.N,)), dtype=np.float64)
# assert acados_solver.acados_get_time_steps(self.capsule, self.N, <double *> old_time_steps.data)
# if np.array_equal(old_time_steps, new_time_steps):
# return
# N = new_time_steps.size
# cdef cnp.ndarray[cnp.float64_t, ndim=1] value = np.ascontiguousarray(new_time_steps, dtype=np.float64)
# # check if recreation of acados is necessary (no need to recreate acados if sizes are identical)
# if len(old_time_steps) == N:
# assert acados_solver.acados_update_time_steps(self.capsule, N, <double *> value.data) == 0
# else: # recreate the solver with the new time steps
# self.solver_created = False
# # delete old memory (analog to __del__)
# acados_solver.acados_free(self.capsule)
# # create solver with new time steps
# assert acados_solver.acados_create_with_discretization(self.capsule, N, <double *> value.data) == 0
# self.solver_created = True
# # get pointers solver
# self.__get_pointers_solver()
# # store time_steps, N
# self.time_steps = new_time_steps
# self.N = N
def update_qp_solver_cond_N(self, qp_solver_cond_N: int):
"""
Recreate solver with new value `qp_solver_cond_N` with a partial condensing QP solver.
This function is relevant for code reuse, i.e., if either `set_new_time_steps(...)` is used or
the influence of a different `qp_solver_cond_N` is studied without code export and compilation.
:param qp_solver_cond_N: new number of condensing stages for the solver
.. note:: This function can only be used in combination with a partial condensing QP solver.
.. note:: After `set_new_time_steps(...)` is used and depending on the new number of time steps it might be
necessary to change `qp_solver_cond_N` as well (using this function), i.e., typically
`qp_solver_cond_N < N`.
"""
raise NotImplementedError("AcadosOcpSolverCython: does not support update_qp_solver_cond_N() since it is only a prototyping feature")
# # unlikely but still possible
# if not self.solver_created:
# raise Exception('Solver was not yet created!')
# if self.N < qp_solver_cond_N:
# raise Exception('Setting qp_solver_cond_N to be larger than N does not work!')
# if self.qp_solver_cond_N != qp_solver_cond_N:
# self.solver_created = False
# # recreate the solver
# acados_solver.acados_update_qp_solver_cond_N(self.capsule, qp_solver_cond_N)
# # store the new value
# self.qp_solver_cond_N = qp_solver_cond_N
# self.solver_created = True
# # get pointers solver
# self.__get_pointers_solver()
def eval_param_sens(self, index, stage=0, field="ex"):
"""
Calculate the sensitivity of the curent solution with respect to the initial state component of index
:param index: integer corresponding to initial state index in range(nx)
"""
field_ = field
field = field_.encode('utf-8')
# checks
if not isinstance(index, int):
raise Exception('AcadosOcpSolverCython.eval_param_sens(): index must be Integer.')
cdef int nx = acados_solver_common.ocp_nlp_dims_get_from_attr(self.nlp_config, self.nlp_dims, self.nlp_out, 0, "x".encode('utf-8'))
if index < 0 or index > nx:
raise Exception(f'AcadosOcpSolverCython.eval_param_sens(): index must be in [0, nx-1], got: {index}.')
# actual eval_param
acados_solver_common.ocp_nlp_eval_param_sens(self.nlp_solver, field, stage, index, self.sens_out)
return
def get(self, int stage, str field_):
"""
Get the last solution of the solver:
:param stage: integer corresponding to shooting node
:param field: string in ['x', 'u', 'z', 'pi', 'lam', 't', 'sl', 'su',]
.. note:: regarding lam, t: \n
the inequalities are internally organized in the following order: \n
[ lbu lbx lg lh lphi ubu ubx ug uh uphi; \n
lsbu lsbx lsg lsh lsphi usbu usbx usg ush usphi]
.. note:: pi: multipliers for dynamics equality constraints \n
lam: multipliers for inequalities \n
t: slack variables corresponding to evaluation of all inequalities (at the solution) \n
sl: slack variables of soft lower inequality constraints \n
su: slack variables of soft upper inequality constraints \n
"""
out_fields = ['x', 'u', 'z', 'pi', 'lam', 't', 'sl', 'su']
field = field_.encode('utf-8')
if field_ not in out_fields:
raise Exception('AcadosOcpSolverCython.get(): {} is an invalid argument.\
\n Possible values are {}. Exiting.'.format(field_, out_fields))
if stage < 0 or stage > self.N:
raise Exception('AcadosOcpSolverCython.get(): stage index must be in [0, N], got: {}.'.format(self.N))
if stage == self.N and field_ == 'pi':
raise Exception('AcadosOcpSolverCython.get(): field {} does not exist at final stage {}.'\
.format(field_, stage))
cdef int dims = acados_solver_common.ocp_nlp_dims_get_from_attr(self.nlp_config,
self.nlp_dims, self.nlp_out, stage, field)
cdef cnp.ndarray[cnp.float64_t, ndim=1] out = np.zeros((dims,))
acados_solver_common.ocp_nlp_out_get(self.nlp_config, \
self.nlp_dims, self.nlp_out, stage, field, <void *> out.data)
return out
def print_statistics(self):
"""
prints statistics of previous solver run as a table:
- iter: iteration number
- res_stat: stationarity residual
- res_eq: residual wrt equality constraints (dynamics)
- res_ineq: residual wrt inequality constraints (constraints)
- res_comp: residual wrt complementarity conditions
- qp_stat: status of QP solver
- qp_iter: number of QP iterations
- qp_res_stat: stationarity residual of the last QP solution
- qp_res_eq: residual wrt equality constraints (dynamics) of the last QP solution
- qp_res_ineq: residual wrt inequality constraints (constraints) of the last QP solution
- qp_res_comp: residual wrt complementarity conditions of the last QP solution
"""
acados_solver.acados_print_stats(self.capsule)
def store_iterate(self, filename='', overwrite=False):
"""
Stores the current iterate of the ocp solver in a json file.
:param filename: if not set, use model_name + timestamp + '.json'
:param overwrite: if false and filename exists add timestamp to filename
"""
import json
if filename == '':
filename += self.model_name + '_' + 'iterate' + '.json'
if not overwrite:
# append timestamp
if os.path.isfile(filename):
filename = filename[:-5]
filename += datetime.utcnow().strftime('%Y-%m-%d-%H:%M:%S.%f') + '.json'
# get iterate:
solution = dict()
for i in range(self.N+1):
solution['x_'+str(i)] = self.get(i,'x')
solution['u_'+str(i)] = self.get(i,'u')
solution['z_'+str(i)] = self.get(i,'z')
solution['lam_'+str(i)] = self.get(i,'lam')
solution['t_'+str(i)] = self.get(i, 't')
solution['sl_'+str(i)] = self.get(i, 'sl')
solution['su_'+str(i)] = self.get(i, 'su')
for i in range(self.N):
solution['pi_'+str(i)] = self.get(i,'pi')
# save
with open(filename, 'w') as f:
json.dump(solution, f, default=lambda x: x.tolist(), indent=4, sort_keys=True)
print("stored current iterate in ", os.path.join(os.getcwd(), filename))
def load_iterate(self, filename):
"""
Loads the iterate stored in json file with filename into the ocp solver.
"""
import json
if not os.path.isfile(filename):
raise Exception('load_iterate: failed, file does not exist: ' + os.path.join(os.getcwd(), filename))
with open(filename, 'r') as f:
solution = json.load(f)
for key in solution.keys():
(field, stage) = key.split('_')
self.set(int(stage), field, np.array(solution[key]))
def get_stats(self, field_):
"""
Get the information of the last solver call.
:param field: string in ['statistics', 'time_tot', 'time_lin', 'time_sim', 'time_sim_ad', 'time_sim_la', 'time_qp', 'time_qp_solver_call', 'time_reg', 'sqp_iter']
Available fileds:
- time_tot: total CPU time previous call
- time_lin: CPU time for linearization
- time_sim: CPU time for integrator
- time_sim_ad: CPU time for integrator contribution of external function calls
- time_sim_la: CPU time for integrator contribution of linear algebra
- time_qp: CPU time qp solution
- time_qp_solver_call: CPU time inside qp solver (without converting the QP)
- time_qp_xcond: time_glob: CPU time globalization
- time_solution_sensitivities: CPU time for previous call to eval_param_sens
- time_reg: CPU time regularization
- sqp_iter: number of SQP iterations
- qp_iter: vector of QP iterations for last SQP call
- statistics: table with info about last iteration
- stat_m: number of rows in statistics matrix
- stat_n: number of columns in statistics matrix
- residuals: residuals of last iterate
- alpha: step sizes of SQP iterations
"""
double_fields = ['time_tot',
'time_lin',
'time_sim',
'time_sim_ad',
'time_sim_la',
'time_qp',
'time_qp_solver_call',
'time_qp_xcond',
'time_glob',
'time_solution_sensitivities',
'time_reg'
]
fields = double_fields + [
'sqp_iter',
'qp_iter',
'statistics',
'stat_m',
'stat_n',
'residuals',
'alpha',
]
field = field_.encode('utf-8')
if field_ in ['sqp_iter', 'stat_m', 'stat_n']:
return self.__get_stat_int(field)
elif field_ in double_fields:
return self.__get_stat_double(field)
elif field_ == 'statistics':
sqp_iter = self.get_stats("sqp_iter")
stat_m = self.get_stats("stat_m")
stat_n = self.get_stats("stat_n")
min_size = min([stat_m, sqp_iter+1])
return self.__get_stat_matrix(field, stat_n+1, min_size)
elif field_ == 'qp_iter':
full_stats = self.get_stats('statistics')
if self.nlp_solver_type == 'SQP':
return full_stats[6, :]
elif self.nlp_solver_type == 'SQP_RTI':
return full_stats[2, :]
elif field_ == 'alpha':
full_stats = self.get_stats('statistics')
if self.nlp_solver_type == 'SQP':
return full_stats[7, :]
else: # self.nlp_solver_type == 'SQP_RTI':
raise Exception("alpha values are not available for SQP_RTI")
elif field_ == 'residuals':
return self.get_residuals()
else:
raise NotImplementedError("TODO!")
def __get_stat_int(self, field):
cdef int out
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, field, <void *> &out)
return out
def __get_stat_double(self, field):
cdef cnp.ndarray[cnp.float64_t, ndim=1] out = np.zeros((1,))
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, field, <void *> out.data)
return out
def __get_stat_matrix(self, field, n, m):
cdef cnp.ndarray[cnp.float64_t, ndim=2] out_mat = np.ascontiguousarray(np.zeros((n, m)), dtype=np.float64)
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, field, <void *> out_mat.data)
return out_mat
def get_cost(self):
"""
Returns the cost value of the current solution.
"""
# compute cost internally
acados_solver_common.ocp_nlp_eval_cost(self.nlp_solver, self.nlp_in, self.nlp_out)
# create output
cdef double out
# call getter
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, "cost_value", <void *> &out)
return out
def get_residuals(self, recompute=False):
"""
Returns an array of the form [res_stat, res_eq, res_ineq, res_comp].
"""
# compute residuals if RTI
if self.nlp_solver_type == 'SQP_RTI' or recompute:
acados_solver_common.ocp_nlp_eval_residuals(self.nlp_solver, self.nlp_in, self.nlp_out)
# create output array
cdef cnp.ndarray[cnp.float64_t, ndim=1] out = np.ascontiguousarray(np.zeros((4,), dtype=np.float64))
cdef double double_value
field = "res_stat".encode('utf-8')
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, field, <void *> &double_value)
out[0] = double_value
field = "res_eq".encode('utf-8')
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, field, <void *> &double_value)
out[1] = double_value
field = "res_ineq".encode('utf-8')
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, field, <void *> &double_value)
out[2] = double_value
field = "res_comp".encode('utf-8')
acados_solver_common.ocp_nlp_get(self.nlp_config, self.nlp_solver, field, <void *> &double_value)
out[3] = double_value
return out
# Note: this function should not be used anymore, better use cost_set, constraints_set
def set(self, int stage, str field_, value_):
"""
Set numerical data inside the solver.
:param stage: integer corresponding to shooting node
:param field: string in ['x', 'u', 'pi', 'lam', 't', 'p']
.. note:: regarding lam, t: \n
the inequalities are internally organized in the following order: \n
[ lbu lbx lg lh lphi ubu ubx ug uh uphi; \n
lsbu lsbx lsg lsh lsphi usbu usbx usg ush usphi]
.. note:: pi: multipliers for dynamics equality constraints \n
lam: multipliers for inequalities \n
t: slack variables corresponding to evaluation of all inequalities (at the solution) \n
sl: slack variables of soft lower inequality constraints \n
su: slack variables of soft upper inequality constraints \n
"""
cost_fields = ['y_ref', 'yref']
constraints_fields = ['lbx', 'ubx', 'lbu', 'ubu']
out_fields = ['x', 'u', 'pi', 'lam', 't', 'z', 'sl', 'su']
mem_fields = ['xdot_guess', 'z_guess']
field = field_.encode('utf-8')
cdef cnp.ndarray[cnp.float64_t, ndim=1] value = np.ascontiguousarray(value_, dtype=np.float64)
# treat parameters separately
if field_ == 'p':
assert acados_solver.acados_update_params(self.capsule, stage, <double *> value.data, value.shape[0]) == 0
else:
if field_ not in constraints_fields + cost_fields + out_fields:
raise Exception("AcadosOcpSolverCython.set(): {} is not a valid argument.\
\nPossible values are {}. Exiting.".format(field, \
constraints_fields + cost_fields + out_fields + ['p']))
dims = acados_solver_common.ocp_nlp_dims_get_from_attr(self.nlp_config,
self.nlp_dims, self.nlp_out, stage, field)
if value_.shape[0] != dims:
msg = 'AcadosOcpSolverCython.set(): mismatching dimension for field "{}" '.format(field_)
msg += 'with dimension {} (you have {})'.format(dims, value_.shape[0])
raise Exception(msg)
if field_ in constraints_fields:
acados_solver_common.ocp_nlp_constraints_model_set(self.nlp_config,
self.nlp_dims, self.nlp_in, stage, field, <void *> value.data)
elif field_ in cost_fields:
acados_solver_common.ocp_nlp_cost_model_set(self.nlp_config,
self.nlp_dims, self.nlp_in, stage, field, <void *> value.data)
elif field_ in out_fields:
acados_solver_common.ocp_nlp_out_set(self.nlp_config,
self.nlp_dims, self.nlp_out, stage, field, <void *> value.data)
elif field_ in mem_fields:
acados_solver_common.ocp_nlp_set(self.nlp_config, \
self.nlp_solver, stage, field, <void *> value.data)
def cost_set(self, int stage, str field_, value_):
"""
Set numerical data in the cost module of the solver.
:param stage: integer corresponding to shooting node
:param field: string, e.g. 'yref', 'W', 'ext_cost_num_hess'
:param value: of appropriate size
"""
field = field_.encode('utf-8')
cdef int dims[2]
acados_solver_common.ocp_nlp_cost_dims_get_from_attr(self.nlp_config, \
self.nlp_dims, self.nlp_out, stage, field, &dims[0])
cdef double[::1,:] value
value_shape = value_.shape
if len(value_shape) == 1:
value_shape = (value_shape[0], 0)
value = np.asfortranarray(value_[None,:])
elif len(value_shape) == 2:
# Get elements in column major order
value = np.asfortranarray(value_)
if value_shape[0] != dims[0] or value_shape[1] != dims[1]:
raise Exception('AcadosOcpSolverCython.cost_set(): mismatching dimension' +
f' for field "{field_}" at stage {stage} with dimension {tuple(dims)} (you have {value_shape})')
acados_solver_common.ocp_nlp_cost_model_set(self.nlp_config, \
self.nlp_dims, self.nlp_in, stage, field, <void *> &value[0][0])
def constraints_set(self, int stage, str field_, value_):
"""
Set numerical data in the constraint module of the solver.
:param stage: integer corresponding to shooting node
:param field: string in ['lbx', 'ubx', 'lbu', 'ubu', 'lg', 'ug', 'lh', 'uh', 'uphi', 'C', 'D']
:param value: of appropriate size
"""
field = field_.encode('utf-8')
cdef int dims[2]
acados_solver_common.ocp_nlp_constraint_dims_get_from_attr(self.nlp_config, \
self.nlp_dims, self.nlp_out, stage, field, &dims[0])
cdef double[::1,:] value
value_shape = value_.shape
if len(value_shape) == 1:
value_shape = (value_shape[0], 0)
value = np.asfortranarray(value_[None,:])
elif len(value_shape) == 2:
# Get elements in column major order
value = np.asfortranarray(value_)
if value_shape[0] != dims[0] or value_shape[1] != dims[1]:
raise Exception(f'AcadosOcpSolverCython.constraints_set(): mismatching dimension' +
f' for field "{field_}" at stage {stage} with dimension {tuple(dims)} (you have {value_shape})')
acados_solver_common.ocp_nlp_constraints_model_set(self.nlp_config, \
self.nlp_dims, self.nlp_in, stage, field, <void *> &value[0][0])
return
def dynamics_get(self, int stage, str field_):
"""
Get numerical data from the dynamics module of the solver:
:param stage: integer corresponding to shooting node
:param field: string, e.g. 'A'
"""
field = field_.encode('utf-8')
# get dims
cdef int[2] dims
acados_solver_common.ocp_nlp_dynamics_dims_get_from_attr(self.nlp_config, self.nlp_dims, self.nlp_out, stage, field, &dims[0])
# create output data
cdef cnp.ndarray[cnp.float64_t, ndim=2] out = np.zeros((dims[0], dims[1]), order='F')
# call getter
acados_solver_common.ocp_nlp_get_at_stage(self.nlp_config, self.nlp_dims, self.nlp_solver, stage, field, <void *> out.data)
return out
def options_set(self, str field_, value_):
"""
Set options of the solver.
:param field: string, e.g. 'print_level', 'rti_phase', 'initialize_t_slacks', 'step_length', 'alpha_min', 'alpha_reduction', 'qp_warm_start', 'line_search_use_sufficient_descent', 'full_step_dual', 'globalization_use_SOC', 'qp_tol_stat', 'qp_tol_eq', 'qp_tol_ineq', 'qp_tol_comp', 'qp_tau_min', 'qp_mu0'
:param value: of type int, float, string
- qp_tol_stat: QP solver tolerance stationarity
- qp_tol_eq: QP solver tolerance equalities
- qp_tol_ineq: QP solver tolerance inequalities
- qp_tol_comp: QP solver tolerance complementarity
- qp_tau_min: for HPIPM QP solvers: minimum value of barrier parameter in HPIPM
- qp_mu0: for HPIPM QP solvers: initial value for complementarity slackness
- warm_start_first_qp: indicates if first QP in SQP is warm_started
"""
int_fields = ['print_level', 'rti_phase', 'initialize_t_slacks', 'qp_warm_start', 'line_search_use_sufficient_descent', 'full_step_dual', 'globalization_use_SOC', 'warm_start_first_qp']
double_fields = ['step_length', 'tol_eq', 'tol_stat', 'tol_ineq', 'tol_comp', 'alpha_min', 'alpha_reduction', 'eps_sufficient_descent',
'qp_tol_stat', 'qp_tol_eq', 'qp_tol_ineq', 'qp_tol_comp', 'qp_tau_min', 'qp_mu0']
string_fields = ['globalization']
# encode
field = field_.encode('utf-8')
cdef int int_value
cdef double double_value
cdef unsigned char[::1] string_value
# check field availability and type
if field_ in int_fields:
if not isinstance(value_, int):
raise Exception('solver option {} must be of type int. You have {}.'.format(field_, type(value_)))
if field_ == 'rti_phase':
if value_ < 0 or value_ > 2:
raise Exception('AcadosOcpSolverCython.solve(): argument \'rti_phase\' can '
'take only values 0, 1, 2 for SQP-RTI-type solvers')
if self.nlp_solver_type != 'SQP_RTI' and value_ > 0:
raise Exception('AcadosOcpSolverCython.solve(): argument \'rti_phase\' can '
'take only value 0 for SQP-type solvers')
int_value = value_
acados_solver_common.ocp_nlp_solver_opts_set(self.nlp_config, self.nlp_opts, field, <void *> &int_value)
elif field_ in double_fields:
if not isinstance(value_, float):
raise Exception('solver option {} must be of type float. You have {}.'.format(field_, type(value_)))
double_value = value_
acados_solver_common.ocp_nlp_solver_opts_set(self.nlp_config, self.nlp_opts, field, <void *> &double_value)
elif field_ in string_fields:
if not isinstance(value_, bytes):
raise Exception('solver option {} must be of type str. You have {}.'.format(field_, type(value_)))
string_value = value_.encode('utf-8')
acados_solver_common.ocp_nlp_solver_opts_set(self.nlp_config, self.nlp_opts, field, <void *> &string_value[0])
else:
raise Exception('AcadosOcpSolverCython.options_set() does not support field {}.'\
'\n Possible values are {}.'.format(field_, ', '.join(int_fields + double_fields + string_fields)))
def __del__(self):
if self.solver_created:
acados_solver.acados_free(self.capsule)
acados_solver.acados_free_capsule(self.capsule)

@ -0,0 +1,331 @@
# -*- coding: future_fstrings -*-
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
import numpy as np
import casadi as ca
import os
from .acados_model import AcadosModel
from .utils import get_acados_path
class AcadosSimDims:
"""
Class containing the dimensions of the model to be simulated.
"""
def __init__(self):
self.__nx = None
self.__nu = None
self.__nz = 0
self.__np = 0
@property
def nx(self):
""":math:`n_x` - number of states. Type: int > 0"""
return self.__nx
@property
def nz(self):
""":math:`n_z` - number of algebraic variables. Type: int >= 0"""
return self.__nz
@property
def nu(self):
""":math:`n_u` - number of inputs. Type: int >= 0"""
return self.__nu
@property
def np(self):
""":math:`n_p` - number of parameters. Type: int >= 0"""
return self.__np
@nx.setter
def nx(self, nx):
if isinstance(nx, int) and nx > 0:
self.__nx = nx
else:
raise Exception('Invalid nx value, expected positive integer. Exiting.')
@nz.setter
def nz(self, nz):
if isinstance(nz, int) and nz > -1:
self.__nz = nz
else:
raise Exception('Invalid nz value, expected nonnegative integer. Exiting.')
@nu.setter
def nu(self, nu):
if isinstance(nu, int) and nu > -1:
self.__nu = nu
else:
raise Exception('Invalid nu value, expected nonnegative integer. Exiting.')
@np.setter
def np(self, np):
if isinstance(np, int) and np > -1:
self.__np = np
else:
raise Exception('Invalid np value, expected nonnegative integer. Exiting.')
def set(self, attr, value):
setattr(self, attr, value)
class AcadosSimOpts:
"""
class containing the solver options
"""
def __init__(self):
self.__integrator_type = 'ERK'
self.__collocation_type = 'GAUSS_LEGENDRE'
self.__Tsim = None
# ints
self.__sim_method_num_stages = 1
self.__sim_method_num_steps = 1
self.__sim_method_newton_iter = 3
# bools
self.__sens_forw = True
self.__sens_adj = False
self.__sens_algebraic = False
self.__sens_hess = False
self.__output_z = False
self.__sim_method_jac_reuse = 0
@property
def integrator_type(self):
"""Integrator type. Default: 'ERK'."""
return self.__integrator_type
@property
def num_stages(self):
"""Number of stages in the integrator. Default: 1"""
return self.__sim_method_num_stages
@property
def num_steps(self):
"""Number of steps in the integrator. Default: 1"""
return self.__sim_method_num_steps
@property
def newton_iter(self):
"""Number of Newton iterations in simulation method. Default: 3"""
return self.__sim_method_newton_iter
@property
def sens_forw(self):
"""Boolean determining if forward sensitivities are computed. Default: True"""
return self.__sens_forw
@property
def sens_adj(self):
"""Boolean determining if adjoint sensitivities are computed. Default: False"""
return self.__sens_adj
@property
def sens_algebraic(self):
"""Boolean determining if sensitivities wrt algebraic variables are computed. Default: False"""
return self.__sens_algebraic
@property
def sens_hess(self):
"""Boolean determining if hessians are computed. Default: False"""
return self.__sens_hess
@property
def output_z(self):
"""Boolean determining if values for algebraic variables (corresponding to start of simulation interval) are computed. Default: False"""
return self.__output_z
@property
def sim_method_jac_reuse(self):
"""Integer determining if jacobians are reused (0 or 1). Default: 0"""
return self.__sim_method_jac_reuse
@property
def T(self):
"""Time horizon"""
return self.__Tsim
@property
def collocation_type(self):
"""Collocation type: relevant for implicit integrators
-- string in {GAUSS_RADAU_IIA, GAUSS_LEGENDRE}
Default: GAUSS_LEGENDRE
"""
return self.__collocation_type
@integrator_type.setter
def integrator_type(self, integrator_type):
integrator_types = ('ERK', 'IRK', 'GNSF')
if integrator_type in integrator_types:
self.__integrator_type = integrator_type
else:
raise Exception('Invalid integrator_type value. Possible values are:\n\n' \
+ ',\n'.join(integrator_types) + '.\n\nYou have: ' + integrator_type + '.\n\nExiting.')
@collocation_type.setter
def collocation_type(self, collocation_type):
collocation_types = ('GAUSS_RADAU_IIA', 'GAUSS_LEGENDRE')
if collocation_type in collocation_types:
self.__collocation_type = collocation_type
else:
raise Exception('Invalid collocation_type value. Possible values are:\n\n' \
+ ',\n'.join(collocation_types) + '.\n\nYou have: ' + collocation_type + '.\n\nExiting.')
@T.setter
def T(self, T):
self.__Tsim = T
@num_stages.setter
def num_stages(self, num_stages):
if isinstance(num_stages, int):
self.__sim_method_num_stages = num_stages
else:
raise Exception('Invalid num_stages value. num_stages must be an integer.')
@num_steps.setter
def num_steps(self, num_steps):
if isinstance(num_steps, int):
self.__sim_method_num_steps = num_steps
else:
raise Exception('Invalid num_steps value. num_steps must be an integer.')
@newton_iter.setter
def newton_iter(self, newton_iter):
if isinstance(newton_iter, int):
self.__sim_method_newton_iter = newton_iter
else:
raise Exception('Invalid newton_iter value. newton_iter must be an integer.')
@sens_forw.setter
def sens_forw(self, sens_forw):
if sens_forw in (True, False):
self.__sens_forw = sens_forw
else:
raise Exception('Invalid sens_forw value. sens_forw must be a Boolean.')
@sens_adj.setter
def sens_adj(self, sens_adj):
if sens_adj in (True, False):
self.__sens_adj = sens_adj
else:
raise Exception('Invalid sens_adj value. sens_adj must be a Boolean.')
@sens_hess.setter
def sens_hess(self, sens_hess):
if sens_hess in (True, False):
self.__sens_hess = sens_hess
else:
raise Exception('Invalid sens_hess value. sens_hess must be a Boolean.')
@sens_algebraic.setter
def sens_algebraic(self, sens_algebraic):
if sens_algebraic in (True, False):
self.__sens_algebraic = sens_algebraic
else:
raise Exception('Invalid sens_algebraic value. sens_algebraic must be a Boolean.')
@output_z.setter
def output_z(self, output_z):
if output_z in (True, False):
self.__output_z = output_z
else:
raise Exception('Invalid output_z value. output_z must be a Boolean.')
@sim_method_jac_reuse.setter
def sim_method_jac_reuse(self, sim_method_jac_reuse):
if sim_method_jac_reuse in (0, 1):
self.__sim_method_jac_reuse = sim_method_jac_reuse
else:
raise Exception('Invalid sim_method_jac_reuse value. sim_method_jac_reuse must be 0 or 1.')
class AcadosSim:
"""
The class has the following properties that can be modified to formulate a specific simulation problem, see below:
:param acados_path: string with the path to acados. It is used to generate the include and lib paths.
- :py:attr:`dims` of type :py:class:`acados_template.acados_ocp.AcadosSimDims` - are automatically detected from model
- :py:attr:`model` of type :py:class:`acados_template.acados_model.AcadosModel`
- :py:attr:`solver_options` of type :py:class:`acados_template.acados_sim.AcadosSimOpts`
- :py:attr:`acados_include_path` (set automatically)
- :py:attr:`acados_lib_path` (set automatically)
- :py:attr:`parameter_values` - used to initialize the parameters (can be changed)
"""
def __init__(self, acados_path=''):
if acados_path == '':
acados_path = get_acados_path()
self.dims = AcadosSimDims()
"""Dimension definitions, automatically detected from :py:attr:`model`. Type :py:class:`acados_template.acados_sim.AcadosSimDims`"""
self.model = AcadosModel()
"""Model definitions, type :py:class:`acados_template.acados_model.AcadosModel`"""
self.solver_options = AcadosSimOpts()
"""Solver Options, type :py:class:`acados_template.acados_sim.AcadosSimOpts`"""
self.acados_include_path = os.path.join(acados_path, 'include').replace(os.sep, '/') # the replace part is important on Windows for CMake
"""Path to acados include directory (set automatically), type: `string`"""
self.acados_lib_path = os.path.join(acados_path, 'lib').replace(os.sep, '/') # the replace part is important on Windows for CMake
"""Path to where acados library is located (set automatically), type: `string`"""
self.code_export_directory = 'c_generated_code'
"""Path to where code will be exported. Default: `c_generated_code`."""
self.cython_include_dirs = ''
self.__parameter_values = np.array([])
@property
def parameter_values(self):
""":math:`p` - initial values for parameter - can be updated"""
return self.__parameter_values
@parameter_values.setter
def parameter_values(self, parameter_values):
if isinstance(parameter_values, np.ndarray):
self.__parameter_values = parameter_values
else:
raise Exception('Invalid parameter_values value. ' +
f'Expected numpy array, got {type(parameter_values)}.')
def set(self, attr, value):
# tokenize string
tokens = attr.split('_', 1)
if len(tokens) > 1:
setter_to_call = getattr(getattr(self, tokens[0]), 'set')
else:
setter_to_call = getattr(self, 'set')
setter_to_call(tokens[1], value)
return

@ -0,0 +1,47 @@
{
"acados_include_path": [
"str"
],
"model": {
"name" : [
"str"
]
},
"acados_lib_path": [
"str"
],
"dims": {
"np": [
"int"
],
"nu": [
"int"
],
"nx": [
"int"
],
"nz": [
"int"
]
},
"solver_options": {
"integrator_type": [
"str"
],
"collocation_type": [
"str"
],
"Tsim": [
"float"
],
"sim_method_num_stages": [
"int"
],
"sim_method_num_steps": [
"int"
],
"sim_method_newton_iter": [
"int"
]
}
}

@ -0,0 +1,454 @@
# -*- coding: future_fstrings -*-
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
import sys, os, json
import numpy as np
from ctypes import *
from copy import deepcopy
from .generate_c_code_explicit_ode import generate_c_code_explicit_ode
from .generate_c_code_implicit_ode import generate_c_code_implicit_ode
from .generate_c_code_gnsf import generate_c_code_gnsf
from .acados_sim import AcadosSim
from .acados_ocp import AcadosOcp
from .acados_model import acados_model_strip_casadi_symbolics
from .utils import is_column, render_template, format_class_dict, np_array_to_list,\
make_model_consistent, set_up_imported_gnsf_model, get_python_interface_path
from .builders import CMakeBuilder
def make_sim_dims_consistent(acados_sim):
dims = acados_sim.dims
model = acados_sim.model
# nx
if is_column(model.x):
dims.nx = model.x.shape[0]
else:
raise Exception("model.x should be column vector!")
# nu
if is_column(model.u):
dims.nu = model.u.shape[0]
elif model.u == None or model.u == []:
dims.nu = 0
else:
raise Exception("model.u should be column vector or None!")
# nz
if is_column(model.z):
dims.nz = model.z.shape[0]
elif model.z == None or model.z == []:
dims.nz = 0
else:
raise Exception("model.z should be column vector or None!")
# np
if is_column(model.p):
dims.np = model.p.shape[0]
elif model.p == None or model.p == []:
dims.np = 0
else:
raise Exception("model.p should be column vector or None!")
def get_sim_layout():
python_interface_path = get_python_interface_path()
abs_path = os.path.join(python_interface_path, 'acados_sim_layout.json')
with open(abs_path, 'r') as f:
sim_layout = json.load(f)
return sim_layout
def sim_formulation_json_dump(acados_sim, json_file='acados_sim.json'):
# Load acados_sim structure description
sim_layout = get_sim_layout()
# Copy input sim object dictionary
sim_dict = dict(deepcopy(acados_sim).__dict__)
for key, v in sim_layout.items():
# skip non dict attributes
if not isinstance(v, dict): continue
# Copy sim object attributes dictionaries
sim_dict[key]=dict(getattr(acados_sim, key).__dict__)
sim_dict['model'] = acados_model_strip_casadi_symbolics(sim_dict['model'])
sim_json = format_class_dict(sim_dict)
with open(json_file, 'w') as f:
json.dump(sim_json, f, default=np_array_to_list, indent=4, sort_keys=True)
def sim_get_default_cmake_builder() -> CMakeBuilder:
"""
If :py:class:`~acados_template.acados_sim_solver.AcadosSimSolver` is used with `CMake` this function returns a good first setting.
:return: default :py:class:`~acados_template.builders.CMakeBuilder`
"""
cmake_builder = CMakeBuilder()
cmake_builder.options_on = ['BUILD_ACADOS_SIM_SOLVER_LIB']
return cmake_builder
def sim_render_templates(json_file, model_name, code_export_dir, cmake_options: CMakeBuilder = None):
# setting up loader and environment
json_path = os.path.join(os.getcwd(), json_file)
if not os.path.exists(json_path):
raise Exception(f"{json_path} not found!")
template_dir = code_export_dir
## Render templates
in_file = 'acados_sim_solver.in.c'
out_file = f'acados_sim_solver_{model_name}.c'
render_template(in_file, out_file, template_dir, json_path)
in_file = 'acados_sim_solver.in.h'
out_file = f'acados_sim_solver_{model_name}.h'
render_template(in_file, out_file, template_dir, json_path)
# Builder
if cmake_options is not None:
in_file = 'CMakeLists.in.txt'
out_file = 'CMakeLists.txt'
render_template(in_file, out_file, template_dir, json_path)
else:
in_file = 'Makefile.in'
out_file = 'Makefile'
render_template(in_file, out_file, template_dir, json_path)
in_file = 'main_sim.in.c'
out_file = f'main_sim_{model_name}.c'
render_template(in_file, out_file, template_dir, json_path)
## folder model
template_dir = os.path.join(code_export_dir, model_name + '_model')
in_file = 'model.in.h'
out_file = f'{model_name}_model.h'
render_template(in_file, out_file, template_dir, json_path)
def sim_generate_casadi_functions(acados_sim):
model = acados_sim.model
model = make_model_consistent(model)
integrator_type = acados_sim.solver_options.integrator_type
opts = dict(generate_hess = acados_sim.solver_options.sens_hess,
code_export_directory = acados_sim.code_export_directory)
# generate external functions
if integrator_type == 'ERK':
generate_c_code_explicit_ode(model, opts)
elif integrator_type == 'IRK':
generate_c_code_implicit_ode(model, opts)
elif integrator_type == 'GNSF':
generate_c_code_gnsf(model, opts)
class AcadosSimSolver:
"""
Class to interact with the acados integrator C object.
:param acados_sim: type :py:class:`~acados_template.acados_ocp.AcadosOcp` (takes values to generate an instance :py:class:`~acados_template.acados_sim.AcadosSim`) or :py:class:`~acados_template.acados_sim.AcadosSim`
:param json_file: Default: 'acados_sim.json'
:param build: Default: True
:param cmake_builder: type :py:class:`~acados_template.utils.CMakeBuilder` generate a `CMakeLists.txt` and use
the `CMake` pipeline instead of a `Makefile` (`CMake` seems to be the better option in conjunction with
`MS Visual Studio`); default: `None`
"""
def __init__(self, acados_sim_, json_file='acados_sim.json', build=True, cmake_builder: CMakeBuilder = None):
self.solver_created = False
if isinstance(acados_sim_, AcadosOcp):
# set up acados_sim_
acados_sim = AcadosSim()
acados_sim.model = acados_sim_.model
acados_sim.dims.nx = acados_sim_.dims.nx
acados_sim.dims.nu = acados_sim_.dims.nu
acados_sim.dims.nz = acados_sim_.dims.nz
acados_sim.dims.np = acados_sim_.dims.np
acados_sim.solver_options.integrator_type = acados_sim_.solver_options.integrator_type
acados_sim.code_export_directory = acados_sim_.code_export_directory
elif isinstance(acados_sim_, AcadosSim):
acados_sim = acados_sim_
acados_sim.__problem_class = 'SIM'
model_name = acados_sim.model.name
make_sim_dims_consistent(acados_sim)
# reuse existing json and casadi functions, when creating integrator from ocp
if isinstance(acados_sim_, AcadosSim):
if acados_sim.solver_options.integrator_type == 'GNSF':
set_up_imported_gnsf_model(acados_sim)
sim_generate_casadi_functions(acados_sim)
sim_formulation_json_dump(acados_sim, json_file)
code_export_dir = acados_sim.code_export_directory
if build:
# render templates
sim_render_templates(json_file, model_name, code_export_dir, cmake_builder)
# Compile solver
cwd = os.getcwd()
code_export_dir = os.path.abspath(code_export_dir)
os.chdir(code_export_dir)
if cmake_builder is not None:
cmake_builder.exec(code_export_dir)
else:
os.system('make sim_shared_lib')
os.chdir(cwd)
self.sim_struct = acados_sim
model_name = self.sim_struct.model.name
self.model_name = model_name
# Load acados library to avoid unloading the library.
# This is necessary if acados was compiled with OpenMP, since the OpenMP threads can't be destroyed.
# Unloading a library which uses OpenMP results in a segfault (on any platform?).
# see [https://stackoverflow.com/questions/34439956/vc-crash-when-freeing-a-dll-built-with-openmp]
# or [https://python.hotexamples.com/examples/_ctypes/-/dlclose/python-dlclose-function-examples.html]
libacados_name = 'libacados.so'
libacados_filepath = os.path.join(acados_sim.acados_lib_path, libacados_name)
self.__acados_lib = CDLL(libacados_filepath)
# find out if acados was compiled with OpenMP
try:
self.__acados_lib_uses_omp = getattr(self.__acados_lib, 'omp_get_thread_num') is not None
except AttributeError as e:
self.__acados_lib_uses_omp = False
if self.__acados_lib_uses_omp:
print('acados was compiled with OpenMP.')
else:
print('acados was compiled without OpenMP.')
# Ctypes
lib_prefix = 'lib'
lib_ext = '.so'
if os.name == 'nt':
lib_prefix = ''
lib_ext = ''
self.shared_lib_name = os.path.join(code_export_dir, f'{lib_prefix}acados_sim_solver_{model_name}{lib_ext}')
print(f'self.shared_lib_name = "{self.shared_lib_name}"')
self.shared_lib = CDLL(self.shared_lib_name)
# create capsule
getattr(self.shared_lib, f"{model_name}_acados_sim_solver_create_capsule").restype = c_void_p
self.capsule = getattr(self.shared_lib, f"{model_name}_acados_sim_solver_create_capsule")()
# create solver
getattr(self.shared_lib, f"{model_name}_acados_sim_create").argtypes = [c_void_p]
getattr(self.shared_lib, f"{model_name}_acados_sim_create").restype = c_int
assert getattr(self.shared_lib, f"{model_name}_acados_sim_create")(self.capsule)==0
self.solver_created = True
getattr(self.shared_lib, f"{model_name}_acados_get_sim_opts").argtypes = [c_void_p]
getattr(self.shared_lib, f"{model_name}_acados_get_sim_opts").restype = c_void_p
self.sim_opts = getattr(self.shared_lib, f"{model_name}_acados_get_sim_opts")(self.capsule)
getattr(self.shared_lib, f"{model_name}_acados_get_sim_dims").argtypes = [c_void_p]
getattr(self.shared_lib, f"{model_name}_acados_get_sim_dims").restype = c_void_p
self.sim_dims = getattr(self.shared_lib, f"{model_name}_acados_get_sim_dims")(self.capsule)
getattr(self.shared_lib, f"{model_name}_acados_get_sim_config").argtypes = [c_void_p]
getattr(self.shared_lib, f"{model_name}_acados_get_sim_config").restype = c_void_p
self.sim_config = getattr(self.shared_lib, f"{model_name}_acados_get_sim_config")(self.capsule)
getattr(self.shared_lib, f"{model_name}_acados_get_sim_out").argtypes = [c_void_p]
getattr(self.shared_lib, f"{model_name}_acados_get_sim_out").restype = c_void_p
self.sim_out = getattr(self.shared_lib, f"{model_name}_acados_get_sim_out")(self.capsule)
getattr(self.shared_lib, f"{model_name}_acados_get_sim_in").argtypes = [c_void_p]
getattr(self.shared_lib, f"{model_name}_acados_get_sim_in").restype = c_void_p
self.sim_in = getattr(self.shared_lib, f"{model_name}_acados_get_sim_in")(self.capsule)
getattr(self.shared_lib, f"{model_name}_acados_get_sim_solver").argtypes = [c_void_p]
getattr(self.shared_lib, f"{model_name}_acados_get_sim_solver").restype = c_void_p
self.sim_solver = getattr(self.shared_lib, f"{model_name}_acados_get_sim_solver")(self.capsule)
nu = self.sim_struct.dims.nu
nx = self.sim_struct.dims.nx
nz = self.sim_struct.dims.nz
self.gettable = {
'x': nx,
'xn': nx,
'u': nu,
'z': nz,
'S_forw': nx*(nx+nu),
'Sx': nx*nx,
'Su': nx*nu,
'S_adj': nx+nu,
'S_hess': (nx+nu)*(nx+nu),
'S_algebraic': (nz)*(nx+nu),
}
self.settable = ['S_adj', 'T', 'x', 'u', 'xdot', 'z', 'p'] # S_forw
def solve(self):
"""
Solve the simulation problem with current input.
"""
getattr(self.shared_lib, f"{self.model_name}_acados_sim_solve").argtypes = [c_void_p]
getattr(self.shared_lib, f"{self.model_name}_acados_sim_solve").restype = c_int
status = getattr(self.shared_lib, f"{self.model_name}_acados_sim_solve")(self.capsule)
return status
def get(self, field_):
"""
Get the last solution of the solver.
:param str field: string in ['x', 'u', 'z', 'S_forw', 'Sx', 'Su', 'S_adj', 'S_hess', 'S_algebraic']
"""
field = field_
field = field.encode('utf-8')
if field_ in self.gettable.keys():
# allocate array
dims = self.gettable[field_]
out = np.ascontiguousarray(np.zeros((dims,)), dtype=np.float64)
out_data = cast(out.ctypes.data, POINTER(c_double))
self.shared_lib.sim_out_get.argtypes = [c_void_p, c_void_p, c_void_p, c_char_p, c_void_p]
self.shared_lib.sim_out_get(self.sim_config, self.sim_dims, self.sim_out, field, out_data)
if field_ == 'S_forw':
nu = self.sim_struct.dims.nu
nx = self.sim_struct.dims.nx
out = out.reshape(nx, nx+nu, order='F')
elif field_ == 'Sx':
nx = self.sim_struct.dims.nx
out = out.reshape(nx, nx, order='F')
elif field_ == 'Su':
nx = self.sim_struct.dims.nx
nu = self.sim_struct.dims.nu
out = out.reshape(nx, nu, order='F')
elif field_ == 'S_hess':
nx = self.sim_struct.dims.nx
nu = self.sim_struct.dims.nu
out = out.reshape(nx+nu, nx+nu, order='F')
elif field_ == 'S_algebraic':
nx = self.sim_struct.dims.nx
nu = self.sim_struct.dims.nu
nz = self.sim_struct.dims.nz
out = out.reshape(nz, nx+nu, order='F')
else:
raise Exception(f'AcadosSimSolver.get(): Unknown field {field_},' \
f' available fields are {", ".join(self.gettable.keys())}')
return out
def set(self, field_, value_):
"""
Set numerical data inside the solver.
:param field: string in ['p', 'S_adj', 'T', 'x', 'u', 'xdot', 'z']
:param value: the value with appropriate size.
"""
# cast value_ to avoid conversion issues
if isinstance(value_, (float, int)):
value_ = np.array([value_])
value_ = value_.astype(float)
value_data = cast(value_.ctypes.data, POINTER(c_double))
value_data_p = cast((value_data), c_void_p)
field = field_
field = field.encode('utf-8')
# treat parameters separately
if field_ == 'p':
model_name = self.sim_struct.model.name
getattr(self.shared_lib, f"{model_name}_acados_sim_update_params").argtypes = [c_void_p, POINTER(c_double), c_int]
value_data = cast(value_.ctypes.data, POINTER(c_double))
getattr(self.shared_lib, f"{model_name}_acados_sim_update_params")(self.capsule, value_data, value_.shape[0])
return
else:
# dimension check
dims = np.ascontiguousarray(np.zeros((2,)), dtype=np.intc)
dims_data = cast(dims.ctypes.data, POINTER(c_int))
self.shared_lib.sim_dims_get_from_attr.argtypes = [c_void_p, c_void_p, c_char_p, POINTER(c_int)]
self.shared_lib.sim_dims_get_from_attr(self.sim_config, self.sim_dims, field, dims_data)
value_ = np.ravel(value_, order='F')
value_shape = value_.shape
if len(value_shape) == 1:
value_shape = (value_shape[0], 0)
if value_shape != tuple(dims):
raise Exception('AcadosSimSolver.set(): mismatching dimension' \
' for field "{}" with dimension {} (you have {})'.format(field_, tuple(dims), value_shape))
# set
if field_ in ['xdot', 'z']:
self.shared_lib.sim_solver_set.argtypes = [c_void_p, c_char_p, c_void_p]
self.shared_lib.sim_solver_set(self.sim_solver, field, value_data_p)
elif field_ in self.settable:
self.shared_lib.sim_in_set.argtypes = [c_void_p, c_void_p, c_void_p, c_char_p, c_void_p]
self.shared_lib.sim_in_set(self.sim_config, self.sim_dims, self.sim_in, field, value_data_p)
else:
raise Exception(f'AcadosSimSolver.set(): Unknown field {field_},' \
f' available fields are {", ".join(self.settable)}')
return
def __del__(self):
if self.solver_created:
getattr(self.shared_lib, f"{self.model_name}_acados_sim_free").argtypes = [c_void_p]
getattr(self.shared_lib, f"{self.model_name}_acados_sim_free").restype = c_int
getattr(self.shared_lib, f"{self.model_name}_acados_sim_free")(self.capsule)
getattr(self.shared_lib, f"{self.model_name}_acados_sim_solver_free_capsule").argtypes = [c_void_p]
getattr(self.shared_lib, f"{self.model_name}_acados_sim_solver_free_capsule").restype = c_int
getattr(self.shared_lib, f"{self.model_name}_acados_sim_solver_free_capsule")(self.capsule)
try:
self.dlclose(self.shared_lib._handle)
except:
pass

@ -0,0 +1,103 @@
# -*- coding: future_fstrings -*-
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
cdef extern from "acados/ocp_nlp/ocp_nlp_common.h":
ctypedef struct ocp_nlp_config:
pass
ctypedef struct ocp_nlp_dims:
pass
ctypedef struct ocp_nlp_in:
pass
ctypedef struct ocp_nlp_out:
pass
cdef extern from "acados_c/ocp_nlp_interface.h":
ctypedef enum ocp_nlp_solver_t:
pass
ctypedef enum ocp_nlp_cost_t:
pass
ctypedef enum ocp_nlp_dynamics_t:
pass
ctypedef enum ocp_nlp_constraints_t:
pass
ctypedef enum ocp_nlp_reg_t:
pass
ctypedef struct ocp_nlp_plan:
pass
ctypedef struct ocp_nlp_solver:
pass
int ocp_nlp_cost_model_set(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_in *in_,
int start_stage, const char *field, void *value)
int ocp_nlp_constraints_model_set(ocp_nlp_config *config, ocp_nlp_dims *dims,
ocp_nlp_in *in_, int stage, const char *field, void *value)
# out
void ocp_nlp_out_set(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out,
int stage, const char *field, void *value)
void ocp_nlp_out_get(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out,
int stage, const char *field, void *value)
void ocp_nlp_get_at_stage(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_solver *solver,
int stage, const char *field, void *value)
int ocp_nlp_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out,
int stage, const char *field)
void ocp_nlp_constraint_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out,
int stage, const char *field, int *dims_out)
void ocp_nlp_cost_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out,
int stage, const char *field, int *dims_out)
void ocp_nlp_dynamics_dims_get_from_attr(ocp_nlp_config *config, ocp_nlp_dims *dims, ocp_nlp_out *out,
int stage, const char *field, int *dims_out)
# opts
void ocp_nlp_solver_opts_set(ocp_nlp_config *config, void *opts_, const char *field, void* value)
# solver
void ocp_nlp_eval_residuals(ocp_nlp_solver *solver, ocp_nlp_in *nlp_in, ocp_nlp_out *nlp_out)
void ocp_nlp_eval_param_sens(ocp_nlp_solver *solver, char *field, int stage, int index, ocp_nlp_out *sens_nlp_out)
void ocp_nlp_eval_cost(ocp_nlp_solver *solver, ocp_nlp_in *nlp_in_, ocp_nlp_out *nlp_out)
# get/set
void ocp_nlp_get(ocp_nlp_config *config, ocp_nlp_solver *solver, const char *field, void *return_value_)
void ocp_nlp_set(ocp_nlp_config *config, ocp_nlp_solver *solver, int stage, const char *field, void *value)

@ -0,0 +1,116 @@
# -*- coding: future_fstrings -*-
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
import os
import sys
from subprocess import call
class CMakeBuilder:
"""
Class to work with the `CMake` build system.
"""
def __init__(self):
self._source_dir = None # private source directory, this is set to code_export_dir
self.build_dir = 'build'
self._build_dir = None # private build directory, usually rendered to abspath(build_dir)
self.generator = None
"""Defines the generator, options can be found via `cmake --help` under 'Generator'. Type: string. Linux default 'Unix Makefiles', Windows 'Visual Studio 15 2017 Win64'; default value: `None`."""
# set something for Windows
if os.name == 'nt':
self.generator = 'Visual Studio 15 2017 Win64'
self.build_targets = None
"""A comma-separated list of the build targets, if `None` then all targets will be build; type: List of strings; default: `None`."""
self.options_on = None
"""List of strings as CMake options which are translated to '-D Opt[0]=ON -D Opt[1]=ON ...'; default: `None`."""
# Generate the command string for handling the cmake command.
def get_cmd1_cmake(self):
defines_str = ''
if self.options_on is not None:
defines_arr = [f' -D{opt}=ON' for opt in self.options_on]
defines_str = ' '.join(defines_arr)
generator_str = ''
if self.generator is not None:
generator_str = f' -G"{self.generator}"'
return f'cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX="{self._source_dir}"{defines_str}{generator_str} -Wdev -S"{self._source_dir}" -B"{self._build_dir}"'
# Generate the command string for handling the build.
def get_cmd2_build(self):
import multiprocessing
cmd = f'cmake --build "{self._build_dir}" --config Release -j{multiprocessing.cpu_count()}'
if self.build_targets is not None:
cmd += f' -t {self.build_targets}'
return cmd
# Generate the command string for handling the install command.
def get_cmd3_install(self):
return f'cmake --install "{self._build_dir}"'
def exec(self, code_export_directory):
"""
Execute the compilation using `CMake` with the given settings.
:param code_export_directory: must be the absolute path to the directory where the code was exported to
"""
if(os.path.isabs(code_export_directory) is False):
print(f'(W) the code export directory "{code_export_directory}" is not an absolute path!')
self._source_dir = code_export_directory
self._build_dir = os.path.abspath(self.build_dir)
try:
os.mkdir(self._build_dir)
except FileExistsError as e:
pass
try:
os.chdir(self._build_dir)
cmd_str = self.get_cmd1_cmake()
print(f'call("{cmd_str})"')
retcode = call(cmd_str, shell=True)
if retcode != 0:
raise RuntimeError(f'CMake command "{cmd_str}" was terminated by signal {retcode}')
cmd_str = self.get_cmd2_build()
print(f'call("{cmd_str}")')
retcode = call(cmd_str, shell=True)
if retcode != 0:
raise RuntimeError(f'Build command "{cmd_str}" was terminated by signal {retcode}')
cmd_str = self.get_cmd3_install()
print(f'call("{cmd_str}")')
retcode = call(cmd_str, shell=True)
if retcode != 0:
raise RuntimeError(f'Install command "{cmd_str}" was terminated by signal {retcode}')
except OSError as e:
print("Execution failed:", e, file=sys.stderr)
except Exception as e:
print("Execution failed:", e, file=sys.stderr)
exit(1)

@ -0,0 +1,374 @@
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
{%- if solver_options.qp_solver %}
{%- set qp_solver = solver_options.qp_solver %}
{%- else %}
{%- set qp_solver = "FULL_CONDENSING_HPIPM" %}
{%- endif %}
{%- if solver_options.hessian_approx %}
{%- set hessian_approx = solver_options.hessian_approx %}
{%- elif solver_options.sens_hess %}
{%- set hessian_approx = "EXACT" %}
{%- else %}
{%- set hessian_approx = "GAUSS_NEWTON" %}
{%- endif %}
{%- if constraints.constr_type %}
{%- set constr_type = constraints.constr_type %}
{%- else %}
{%- set constr_type = "NONE" %}
{%- endif %}
{%- if constraints.constr_type_e %}
{%- set constr_type_e = constraints.constr_type_e %}
{%- else %}
{%- set constr_type_e = "NONE" %}
{%- endif %}
{%- if cost.cost_type %}
{%- set cost_type = cost.cost_type %}
{%- else %}
{%- set cost_type = "NONE" %}
{%- endif %}
{%- if cost.cost_type_e %}
{%- set cost_type_e = cost.cost_type_e %}
{%- else %}
{%- set cost_type_e = "NONE" %}
{%- endif %}
{%- if cost.cost_type_0 %}
{%- set cost_type_0 = cost.cost_type_0 %}
{%- else %}
{%- set cost_type_0 = "NONE" %}
{%- endif %}
{%- if dims.nh %}
{%- set dims_nh = dims.nh %}
{%- else %}
{%- set dims_nh = 0 %}
{%- endif %}
{%- if dims.nphi %}
{%- set dims_nphi = dims.nphi %}
{%- else %}
{%- set dims_nphi = 0 %}
{%- endif %}
{%- if dims.nh_e %}
{%- set dims_nh_e = dims.nh_e %}
{%- else %}
{%- set dims_nh_e = 0 %}
{%- endif %}
{%- if dims.nphi_e %}
{%- set dims_nphi_e = dims.nphi_e %}
{%- else %}
{%- set dims_nphi_e = 0 %}
{%- endif %}
{%- if solver_options.model_external_shared_lib_dir %}
{%- set model_external_shared_lib_dir = solver_options.model_external_shared_lib_dir %}
{%- endif %}
{%- if solver_options.model_external_shared_lib_name %}
{%- set model_external_shared_lib_name = solver_options.model_external_shared_lib_name %}
{%- endif %}
{#- control operator #}
{%- if os and os == "pc" %}
{%- set control = "&" %}
{%- else %}
{%- set control = ";" %}
{%- endif %}
{%- if acados_link_libs and os and os == "pc" %}{# acados linking libraries and flags #}
{%- set link_libs = acados_link_libs.qpoases ~ " " ~ acados_link_libs.hpmpc ~ " " ~ acados_link_libs.osqp -%}
{%- set openmp_flag = acados_link_libs.openmp %}
{%- else %}
{%- set openmp_flag = " " %}
{%- if qp_solver == "FULL_CONDENSING_QPOASES" %}
{%- set link_libs = "-lqpOASES_e" %}
{%- else %}
{%- set link_libs = "" %}
{%- endif %}
{%- endif %}
cmake_minimum_required(VERSION 3.10)
project({{ model.name }})
# build options.
option(BUILD_ACADOS_SOLVER_LIB "Should the solver library acados_solver_{{ model.name }} be build?" OFF)
option(BUILD_ACADOS_OCP_SOLVER_LIB "Should the OCP solver library acados_ocp_solver_{{ model.name }} be build?" OFF)
option(BUILD_EXAMPLE "Should the example main_{{ model.name }} be build?" OFF)
{%- if solver_options.integrator_type != "DISCRETE" %}
option(BUILD_SIM_EXAMPLE "Should the simulation example main_sim_{{ model.name }} be build?" OFF)
option(BUILD_ACADOS_SIM_SOLVER_LIB "Should the simulation solver library acados_sim_solver_{{ model.name }} be build?" OFF)
{%- endif %}
# object target names
set(MODEL_OBJ model_{{ model.name }})
set(OCP_OBJ ocp_{{ model.name }})
set(SIM_OBJ sim_{{ model.name }})
# model
set(MODEL_SRC
{%- if solver_options.integrator_type == "ERK" %}
{{ model.name }}_model/{{ model.name }}_expl_ode_fun.c
{{ model.name }}_model/{{ model.name }}_expl_vde_forw.c
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_model/{{ model.name }}_expl_ode_hess.c
{%- endif %}
{%- elif solver_options.integrator_type == "IRK" %}
{{ model.name }}_model/{{ model.name }}_impl_dae_fun.c
{{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_z.c
{{ model.name }}_model/{{ model.name }}_impl_dae_jac_x_xdot_u_z.c
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_model/{{ model.name }}_impl_dae_hess.c
{%- endif %}
{%- elif solver_options.integrator_type == "LIFTED_IRK" %}
{{ model.name }}_model/{{ model.name }}_impl_dae_fun.c
{{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_u.c
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_model/{{ model.name }}_impl_dae_hess.c
{%- endif %}
{%- elif solver_options.integrator_type == "GNSF" %}
{% if model.gnsf.purely_linear != 1 %}
{{ model.name }}_model/{{ model.name }}_gnsf_phi_fun.c
{{ model.name }}_model/{{ model.name }}_gnsf_phi_fun_jac_y.c
{{ model.name }}_model/{{ model.name }}_gnsf_phi_jac_y_uhat.c
{% if model.gnsf.nontrivial_f_LO == 1 %}
{{ model.name }}_model/{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz.c
{%- endif %}
{%- endif %}
{{ model.name }}_model/{{ model.name }}_gnsf_get_matrices_fun.c
{%- elif solver_options.integrator_type == "DISCRETE" %}
{%- if model.dyn_ext_fun_type == "casadi" %}
{{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun.c
{{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac.c
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac_hess.c
{%- endif %}
{%- else %}
{{ model.name }}_model/{{ model.dyn_source_discrete }}
{%- endif %}
{%- endif -%}
)
add_library(${MODEL_OBJ} OBJECT ${MODEL_SRC} )
# optimal control problem - mostly CasADi exports
if(${BUILD_ACADOS_SOLVER_LIB} OR ${BUILD_ACADOS_OCP_SOLVER_LIB} OR ${BUILD_EXAMPLE})
set(OCP_SRC
{%- if constr_type == "BGP" and dims_nphi > 0 %}
{{ model.name }}_constraints/{{ model.name }}_phi_constraint.c
{%- endif %}
{%- if constr_type_e == "BGP" and dims_nphi_e > 0 %}
{{ model.name }}_constraints/{{ model.name }}_phi_e_constraint.c
{%- endif %}
{%- if constr_type == "BGH" and dims_nh > 0 %}
{{ model.name }}_constraints/{{ model.name }}_constr_h_fun_jac_uxt_zt.c
{{ model.name }}_constraints/{{ model.name }}_constr_h_fun.c
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_constraints/{{ model.name }}_constr_h_fun_jac_uxt_zt_hess.c
{%- endif %}
{%- endif %}
{%- if constr_type_e == "BGH" and dims_nh_e > 0 %}
{{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun_jac_uxt_zt.c
{{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun.c
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun_jac_uxt_zt_hess.c
{%- endif %}
{%- endif %}
{%- if cost_type_0 == "NONLINEAR_LS" %}
{{ model.name }}_cost/{{ model.name }}_cost_y_0_fun.c
{{ model.name }}_cost/{{ model.name }}_cost_y_0_fun_jac_ut_xt.c
{{ model.name }}_cost/{{ model.name }}_cost_y_0_hess.c
{%- elif cost_type_0 == "EXTERNAL" %}
{%- if cost.cost_ext_fun_type_0 == "casadi" %}
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun.c
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun_jac.c
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun_jac_hess.c
{%- else %}
{{ model.name }}_cost/{{ cost.cost_source_ext_cost_0 }}
{%- endif %}
{%- endif %}
{%- if cost_type == "NONLINEAR_LS" %}
{{ model.name }}_cost/{{ model.name }}_cost_y_fun.c
{{ model.name }}_cost/{{ model.name }}_cost_y_fun_jac_ut_xt.c
{{ model.name }}_cost/{{ model.name }}_cost_y_hess.c
{%- elif cost_type == "EXTERNAL" %}
{%- if cost.cost_ext_fun_type == "casadi" %}
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun.c
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun_jac.c
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun_jac_hess.c
{%- elif cost.cost_source_ext_cost != cost.cost_source_ext_cost_0 %}
{{ model.name }}_cost/{{ cost.cost_source_ext_cost }}
{%- endif %}
{%- endif %}
{%- if cost_type_e == "NONLINEAR_LS" %}
{{ model.name }}_cost/{{ model.name }}_cost_y_e_fun.c
{{ model.name }}_cost/{{ model.name }}_cost_y_e_fun_jac_ut_xt.c
{{ model.name }}_cost/{{ model.name }}_cost_y_e_hess.c
{%- elif cost_type_e == "EXTERNAL" %}
{%- if cost.cost_ext_fun_type_e == "casadi" %}
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun.c
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun_jac.c
{{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun_jac_hess.c
{%- elif cost.cost_source_ext_cost_e != cost.cost_source_ext_cost_0 %}
{{ model.name }}_cost/{{ cost.cost_source_ext_cost_e }}
{%- endif %}
{%- endif %}
acados_solver_{{ model.name }}.c)
add_library(${OCP_OBJ} OBJECT ${OCP_SRC})
endif()
{%- if solver_options.integrator_type != "DISCRETE" %}
# for sim solver
if(${BUILD_ACADOS_SOLVER_LIB} OR ${BUILD_EXAMPLE}
{%- if solver_options.integrator_type != "DISCRETE" %}
OR ${BUILD_SIM_EXAMPLE} OR ${BUILD_ACADOS_SIM_SOLVER_LIB}
{%- endif -%}
)
set(SIM_SRC acados_sim_solver_{{ model.name }}.c)
add_library(${SIM_OBJ} OBJECT ${SIM_SRC})
endif()
{%- endif %}
# for target example
set(EX_SRC main_{{ model.name }}.c)
set(EX_EXE main_{{ model.name }})
{%- if model_external_shared_lib_dir and model_external_shared_lib_name %}
set(EXTERNAL_DIR {{ model_external_shared_lib_dir }})
set(EXTERNAL_LIB {{ model_external_shared_lib_name }})
{%- else %}
set(EXTERNAL_DIR)
set(EXTERNAL_LIB)
{%- endif %}
# set some search paths for preprocessor and linker
set(ACADOS_INCLUDE_PATH {{ acados_include_path }} CACHE PATH "Define the path which contains the include directory for acados.")
set(ACADOS_LIB_PATH {{ acados_lib_path }} CACHE PATH "Define the path which contains the lib directory for acados.")
# c-compiler flags for debugging
set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb")
set(CMAKE_C_FLAGS "
{%- if qp_solver == "FULL_CONDENSING_QPOASES" -%}
-DACADOS_WITH_QPOASES
{%- endif -%}
{%- if qp_solver == "PARTIAL_CONDENSING_OSQP" -%}
-DACADOS_WITH_OSQP
{%- endif -%}
{%- if qp_solver == "PARTIAL_CONDENSING_QPDUNES" -%}
-DACADOS_WITH_QPDUNES
{%- endif -%}
-fPIC -std=c99 {{ openmp_flag }}")
#-fno-diagnostics-show-line-numbers -g
include_directories(
${ACADOS_INCLUDE_PATH}
${ACADOS_INCLUDE_PATH}/acados
${ACADOS_INCLUDE_PATH}/blasfeo/include
${ACADOS_INCLUDE_PATH}/hpipm/include
{%- if qp_solver == "FULL_CONDENSING_QPOASES" %}
${ACADOS_INCLUDE_PATH}/qpOASES_e/
{%- endif %}
)
# linker flags
link_directories(${ACADOS_LIB_PATH})
# link to libraries
if(UNIX)
link_libraries(acados hpipm blasfeo m {{ link_libs }})
else()
link_libraries(acados hpipm blasfeo {{ link_libs }})
endif()
# the targets
# bundled_shared_lib
if(${BUILD_ACADOS_SOLVER_LIB})
set(LIB_ACADOS_SOLVER acados_solver_{{ model.name }})
add_library(${LIB_ACADOS_SOLVER} SHARED $<TARGET_OBJECTS:${MODEL_OBJ}> $<TARGET_OBJECTS:${OCP_OBJ}>
{%- if solver_options.integrator_type != "DISCRETE" %}
$<TARGET_OBJECTS:${SIM_OBJ}>
{%- endif -%}
)
install(TARGETS ${LIB_ACADOS_SOLVER} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif(${BUILD_ACADOS_SOLVER_LIB})
# ocp_shared_lib
if(${BUILD_ACADOS_OCP_SOLVER_LIB})
set(LIB_ACADOS_OCP_SOLVER acados_ocp_solver_{{ model.name }})
add_library(${LIB_ACADOS_OCP_SOLVER} SHARED $<TARGET_OBJECTS:${MODEL_OBJ}> $<TARGET_OBJECTS:${OCP_OBJ}>)
# Specify libraries or flags to use when linking a given target and/or its dependents.
target_link_libraries(${LIB_ACADOS_OCP_SOLVER} PRIVATE ${EXTERNAL_LIB})
target_link_directories(${LIB_ACADOS_OCP_SOLVER} PRIVATE ${EXTERNAL_DIR})
install(TARGETS ${LIB_ACADOS_OCP_SOLVER} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif(${BUILD_ACADOS_OCP_SOLVER_LIB})
# example
if(${BUILD_EXAMPLE})
add_executable(${EX_EXE} ${EX_SRC} $<TARGET_OBJECTS:${MODEL_OBJ}> $<TARGET_OBJECTS:${OCP_OBJ}>
{%- if solver_options.integrator_type != "DISCRETE" %}
$<TARGET_OBJECTS:${SIM_OBJ}>
{%- endif -%}
)
install(TARGETS ${EX_EXE} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif(${BUILD_EXAMPLE})
{% if solver_options.integrator_type != "DISCRETE" -%}
# example_sim
if(${BUILD_SIM_EXAMPLE})
set(EX_SIM_SRC main_sim_{{ model.name }}.c)
set(EX_SIM_EXE main_sim_{{ model.name }})
add_executable(${EX_SIM_EXE} ${EX_SIM_SRC} $<TARGET_OBJECTS:${MODEL_OBJ}> $<TARGET_OBJECTS:${SIM_OBJ}>)
install(TARGETS ${EX_SIM_EXE} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif(${BUILD_SIM_EXAMPLE})
# sim_shared_lib
if(${BUILD_ACADOS_SIM_SOLVER_LIB})
set(LIB_ACADOS_SIM_SOLVER acados_sim_solver_{{ model.name }})
add_library(${LIB_ACADOS_SIM_SOLVER} SHARED $<TARGET_OBJECTS:${MODEL_OBJ}> $<TARGET_OBJECTS:${SIM_OBJ}>)
install(TARGETS ${LIB_ACADOS_SIM_SOLVER} DESTINATION ${CMAKE_INSTALL_PREFIX})
endif(${BUILD_ACADOS_SIM_SOLVER_LIB})
{%- endif %}

@ -0,0 +1 @@
exclude_files=[main, acados_solver, acados_solver_sfun, Makefile, model].*\.?

@ -0,0 +1,406 @@
#
# Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
# Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
# Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
# Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
#
# This file is part of acados.
#
# The 2-Clause BSD License
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.;
#
{%- if solver_options.qp_solver %}
{%- set qp_solver = solver_options.qp_solver %}
{%- else %}
{%- set qp_solver = "FULL_CONDENSING_HPIPM" %}
{%- endif %}
{%- if solver_options.hessian_approx %}
{%- set hessian_approx = solver_options.hessian_approx %}
{%- elif solver_options.sens_hess %}
{%- set hessian_approx = "EXACT" %}
{%- else %}
{%- set hessian_approx = "GAUSS_NEWTON" %}
{%- endif %}
{%- if constraints.constr_type %}
{%- set constr_type = constraints.constr_type %}
{%- else %}
{%- set constr_type = "NONE" %}
{%- endif %}
{%- if constraints.constr_type_e %}
{%- set constr_type_e = constraints.constr_type_e %}
{%- else %}
{%- set constr_type_e = "NONE" %}
{%- endif %}
{%- if cost.cost_type %}
{%- set cost_type = cost.cost_type %}
{%- else %}
{%- set cost_type = "NONE" %}
{%- endif %}
{%- if cost.cost_type_e %}
{%- set cost_type_e = cost.cost_type_e %}
{%- else %}
{%- set cost_type_e = "NONE" %}
{%- endif %}
{%- if cost.cost_type_0 %}
{%- set cost_type_0 = cost.cost_type_0 %}
{%- else %}
{%- set cost_type_0 = "NONE" %}
{%- endif %}
{%- if dims.nh %}
{%- set dims_nh = dims.nh %}
{%- else %}
{%- set dims_nh = 0 %}
{%- endif %}
{%- if dims.nphi %}
{%- set dims_nphi = dims.nphi %}
{%- else %}
{%- set dims_nphi = 0 %}
{%- endif %}
{%- if dims.nh_e %}
{%- set dims_nh_e = dims.nh_e %}
{%- else %}
{%- set dims_nh_e = 0 %}
{%- endif %}
{%- if dims.nphi_e %}
{%- set dims_nphi_e = dims.nphi_e %}
{%- else %}
{%- set dims_nphi_e = 0 %}
{%- endif %}
{%- if solver_options.model_external_shared_lib_dir %}
{%- set model_external_shared_lib_dir = solver_options.model_external_shared_lib_dir %}
{%- endif %}
{%- if solver_options.model_external_shared_lib_name %}
{%- set model_external_shared_lib_name = solver_options.model_external_shared_lib_name %}
{%- endif %}
{# control operator #}
{%- if os and os == "pc" %}
{%- set control = "&" %}
{%- else %}
{%- set control = ";" %}
{%- endif %}
{# acados linking libraries and flags #}
{%- if acados_link_libs and os and os == "pc" %}
{%- set link_libs = acados_link_libs.qpoases ~ " " ~ acados_link_libs.hpmpc ~ " " ~ acados_link_libs.osqp -%}
{%- set openmp_flag = acados_link_libs.openmp %}
{%- else %}
{%- set openmp_flag = " " %}
{%- if qp_solver == "FULL_CONDENSING_QPOASES" %}
{%- set link_libs = "-lqpOASES_e" %}
{%- else %}
{%- set link_libs = "" %}
{%- endif %}
{%- endif %}
# define sources and use make's implicit rules to generate object files (*.o)
# model
MODEL_SRC=
{%- if solver_options.integrator_type == "ERK" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_ode_fun.c
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_vde_forw.c
{%- if hessian_approx == "EXACT" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_expl_ode_hess.c
{%- endif %}
{%- elif solver_options.integrator_type == "IRK" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun.c
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_z.c
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_jac_x_xdot_u_z.c
{%- if hessian_approx == "EXACT" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_hess.c
{%- endif %}
{%- elif solver_options.integrator_type == "LIFTED_IRK" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun.c
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_fun_jac_x_xdot_u.c
{%- if hessian_approx == "EXACT" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_impl_dae_hess.c
{%- endif %}
{%- elif solver_options.integrator_type == "GNSF" %}
{% if model.gnsf.purely_linear != 1 %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_gnsf_phi_fun.c
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_gnsf_phi_fun_jac_y.c
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_gnsf_phi_jac_y_uhat.c
{% if model.gnsf.nontrivial_f_LO == 1 %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz.c
{%- endif %}
{%- endif %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_gnsf_get_matrices_fun.c
{%- elif solver_options.integrator_type == "DISCRETE" %}
{%- if model.dyn_ext_fun_type == "casadi" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun.c
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac.c
{%- if hessian_approx == "EXACT" %}
MODEL_SRC+= {{ model.name }}_model/{{ model.name }}_dyn_disc_phi_fun_jac_hess.c
{%- endif %}
{%- else %}
MODEL_SRC+= {{ model.name }}_model/{{ model.dyn_source_discrete }}
{%- endif %}
{%- endif %}
MODEL_OBJ := $(MODEL_SRC:.c=.o)
# optimal control problem - mostly CasADi exports
OCP_SRC=
{%- if constr_type == "BGP" and dims_nphi > 0 %}
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_phi_constraint.c
{%- endif %}
{%- if constr_type_e == "BGP" and dims_nphi_e > 0 %}
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_phi_e_constraint.c
{%- endif %}
{%- if constr_type == "BGH" and dims_nh > 0 %}
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_constr_h_fun_jac_uxt_zt.c
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_constr_h_fun.c
{%- if hessian_approx == "EXACT" %}
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_constr_h_fun_jac_uxt_zt_hess.c
{%- endif %}
{%- endif %}
{%- if constr_type_e == "BGH" and dims_nh_e > 0 %}
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun_jac_uxt_zt.c
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun.c
{%- if hessian_approx == "EXACT" %}
OCP_SRC+= {{ model.name }}_constraints/{{ model.name }}_constr_h_e_fun_jac_uxt_zt_hess.c
{%- endif %}
{%- endif %}
{%- if cost_type_0 == "NONLINEAR_LS" %}
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_0_fun_jac_ut_xt.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_0_hess.c
{%- elif cost_type_0 == "EXTERNAL" %}
{%- if cost.cost_ext_fun_type_0 == "casadi" %}
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun_jac.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_0_fun_jac_hess.c
{%- else %}
OCP_SRC+= {{ model.name }}_cost/{{ cost.cost_source_ext_cost_0 }}
{%- endif %}
{%- endif %}
{%- if cost_type == "NONLINEAR_LS" %}
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_fun.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_fun_jac_ut_xt.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_hess.c
{%- elif cost_type == "EXTERNAL" %}
{%- if cost.cost_ext_fun_type == "casadi" %}
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun_jac.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_fun_jac_hess.c
{%- elif cost.cost_source_ext_cost != cost.cost_source_ext_cost_0 %}
OCP_SRC+= {{ model.name }}_cost/{{ cost.cost_source_ext_cost }}
{%- endif %}
{%- endif %}
{%- if cost_type_e == "NONLINEAR_LS" %}
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_e_fun_jac_ut_xt.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_y_e_hess.c
{%- elif cost_type_e == "EXTERNAL" %}
{%- if cost.cost_ext_fun_type_e == "casadi" %}
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun_jac.c
OCP_SRC+= {{ model.name }}_cost/{{ model.name }}_cost_ext_cost_e_fun_jac_hess.c
{%- elif cost.cost_source_ext_cost_e != cost.cost_source_ext_cost_0 %}
OCP_SRC+= {{ model.name }}_cost/{{ cost.cost_source_ext_cost_e }}
{%- endif %}
{%- endif %}
OCP_SRC+= acados_solver_{{ model.name }}.c
OCP_OBJ := $(OCP_SRC:.c=.o)
# for sim solver
SIM_SRC= acados_sim_solver_{{ model.name }}.c
SIM_OBJ := $(SIM_SRC:.c=.o)
# for target example
EX_SRC= main_{{ model.name }}.c
EX_OBJ := $(EX_SRC:.c=.o)
EX_EXE := $(EX_SRC:.c=)
# for target example_sim
EX_SIM_SRC= main_sim_{{ model.name }}.c
EX_SIM_OBJ := $(EX_SIM_SRC:.c=.o)
EX_SIM_EXE := $(EX_SIM_SRC:.c=)
# combine model, sim and ocp object files
OBJ=
OBJ+= $(MODEL_OBJ)
{%- if solver_options.integrator_type != "DISCRETE" %}
OBJ+= $(SIM_OBJ)
{%- endif %}
OBJ+= $(OCP_OBJ)
EXTERNAL_DIR=
EXTERNAL_LIB=
{%- if model_external_shared_lib_dir and model_external_shared_lib_name %}
EXTERNAL_DIR+= {{ model_external_shared_lib_dir }}
EXTERNAL_LIB+= {{ model_external_shared_lib_name }}
{%- endif %}
INCLUDE_PATH = {{ acados_include_path }}
LIB_PATH = {{ acados_lib_path }}
# preprocessor flags for make's implicit rules
{%- if qp_solver == "FULL_CONDENSING_QPOASES" %}
CPPFLAGS += -DACADOS_WITH_QPOASES
{%- endif %}
{%- if qp_solver == "PARTIAL_CONDENSING_OSQP" %}
CPPFLAGS += -DACADOS_WITH_OSQP
{%- endif %}
{%- if qp_solver == "PARTIAL_CONDENSING_QPDUNES" %}
CPPFLAGS += -DACADOS_WITH_QPDUNES
{%- endif %}
CPPFLAGS+= -I$(INCLUDE_PATH)
CPPFLAGS+= -I$(INCLUDE_PATH)/acados
CPPFLAGS+= -I$(INCLUDE_PATH)/blasfeo/include
CPPFLAGS+= -I$(INCLUDE_PATH)/hpipm/include
{%- if qp_solver == "FULL_CONDENSING_QPOASES" %}
CPPFLAGS+= -I $(INCLUDE_PATH)/qpOASES_e/
{%- endif %}
{# c-compiler flags #}
# define the c-compiler flags for make's implicit rules
CFLAGS = -fPIC -std=c99 {{ openmp_flag }} #-fno-diagnostics-show-line-numbers -g
# # Debugging
# CFLAGS += -g3
# linker flags
LDFLAGS+= -L$(LIB_PATH)
# link to libraries
LDLIBS+= -lacados
LDLIBS+= -lhpipm
LDLIBS+= -lblasfeo
LDLIBS+= -lm
LDLIBS+= {{ link_libs }}
# libraries
LIBACADOS_SOLVER=libacados_solver_{{ model.name }}.so
LIBACADOS_OCP_SOLVER=libacados_ocp_solver_{{ model.name }}.so
LIBACADOS_SIM_SOLVER=lib$(SIM_SRC:.c=.so)
# virtual targets
.PHONY : all clean
#all: clean example_sim example shared_lib
{% if solver_options.integrator_type == "DISCRETE" -%}
all: clean example
shared_lib: ocp_shared_lib
{%- else %}
all: clean example_sim example
shared_lib: bundled_shared_lib ocp_shared_lib sim_shared_lib
{%- endif %}
# some linker targets
example: $(EX_OBJ) $(OBJ)
$(CC) $^ -o $(EX_EXE) $(LDFLAGS) $(LDLIBS)
example_sim: $(EX_SIM_OBJ) $(MODEL_OBJ) $(SIM_OBJ)
$(CC) $^ -o $(EX_SIM_EXE) $(LDFLAGS) $(LDLIBS)
{% if solver_options.integrator_type != "DISCRETE" -%}
bundled_shared_lib: $(OBJ)
$(CC) -shared $^ -o $(LIBACADOS_SOLVER) $(LDFLAGS) $(LDLIBS)
{%- endif %}
ocp_shared_lib: $(OCP_OBJ) $(MODEL_OBJ)
$(CC) -shared $^ -o $(LIBACADOS_OCP_SOLVER) $(LDFLAGS) $(LDLIBS) \
-L$(EXTERNAL_DIR) -l$(EXTERNAL_LIB)
sim_shared_lib: $(SIM_OBJ) $(MODEL_OBJ)
$(CC) -shared $^ -o $(LIBACADOS_SIM_SOLVER) $(LDFLAGS) $(LDLIBS)
# Cython targets
ocp_cython_c: ocp_shared_lib
cython \
-o acados_ocp_solver_pyx.c \
-I $(INCLUDE_PATH)/../interfaces/acados_template/acados_template \
$(INCLUDE_PATH)/../interfaces/acados_template/acados_template/acados_ocp_solver_pyx.pyx \
-I {{ code_export_directory }} \
ocp_cython_o: ocp_cython_c
$(CC) $(ACADOS_FLAGS) -c -O2 \
-fPIC \
-o acados_ocp_solver_pyx.o \
-I /usr/include/python3.8 \
-I $(INCLUDE_PATH)/blasfeo/include/ \
-I $(INCLUDE_PATH)/hpipm/include/ \
-I $(INCLUDE_PATH) \
-I {{ cython_include_dirs }} \
acados_ocp_solver_pyx.c \
ocp_cython: ocp_cython_o
$(CC) $(ACADOS_FLAGS) -shared \
-o acados_ocp_solver_pyx.so \
-Wl,-rpath=$(LIB_PATH) \
acados_ocp_solver_pyx.o \
$(abspath .)/libacados_ocp_solver_{{ model.name }}.so \
$(LDFLAGS) $(LDLIBS)
{%- if os and os == "pc" %}
clean:
del \Q *.o 2>nul
del \Q *.so 2>nul
del \Q main_{{ model.name }} 2>nul
clean_ocp_shared_lib:
del \Q libacados_ocp_solver_{{ model.name }}.so 2>nul
del \Q acados_solver_{{ model.name }}.o 2>nul
clean_ocp_cython:
del \Q libacados_ocp_solver_{{ model.name }}.so 2>nul
del \Q acados_solver_{{ model.name }}.o 2>nul
del \Q acados_ocp_solver_pyx.so 2>nul
del \Q acados_ocp_solver_pyx.o 2>nul
{%- else %}
clean:
$(RM) $(OBJ) $(EX_OBJ) $(EX_SIM_OBJ)
$(RM) $(LIBACADOS_SOLVER) $(LIBACADOS_OCP_SOLVER) $(LIBACADOS_SIM_SOLVER)
$(RM) $(EX_EXE) $(EX_SIM_EXE)
clean_ocp_shared_lib:
$(RM) $(LIBACADOS_OCP_SOLVER)
$(RM) $(OCP_OBJ)
clean_ocp_cython:
$(RM) libacados_ocp_solver_{{ model.name }}.so
$(RM) acados_solver_{{ model.name }}.o
$(RM) acados_ocp_solver_pyx.so
$(RM) acados_ocp_solver_pyx.o
{%- endif %}

@ -0,0 +1,387 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
// standard
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// acados
#include "acados/utils/print.h"
#include "acados_c/ocp_nlp_interface.h"
#include "acados_solver_{{ model.name }}.h"
// mex
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
long long *l_ptr;
int status = 0;
// create solver
{{ model.name }}_solver_capsule *acados_ocp_capsule = {{ model.name }}_acados_create_capsule();
status = {{ model.name }}_acados_create(acados_ocp_capsule);
if (status)
{
mexPrintf("{{ model.name }}_acados_create() returned status %d.\n", status);
}
mexPrintf("{{ model.name }}_acados_create() -> success!\n");
// get pointers to nlp solver related objects
ocp_nlp_plan_t *nlp_plan = {{ model.name }}_acados_get_nlp_plan(acados_ocp_capsule);
ocp_nlp_config *nlp_config = {{ model.name }}_acados_get_nlp_config(acados_ocp_capsule);
ocp_nlp_dims *nlp_dims = {{ model.name }}_acados_get_nlp_dims(acados_ocp_capsule);
ocp_nlp_in *nlp_in = {{ model.name }}_acados_get_nlp_in(acados_ocp_capsule);
ocp_nlp_out *nlp_out = {{ model.name }}_acados_get_nlp_out(acados_ocp_capsule);
ocp_nlp_solver *nlp_solver = {{ model.name }}_acados_get_nlp_solver(acados_ocp_capsule);
void *nlp_opts = {{ model.name }}_acados_get_nlp_opts(acados_ocp_capsule);
// mexPrintf("acados: got pointer to objectes!\n");
// field names of output struct
#define FIELDS_OCP 9
#define FIELDS_EXT_FUN 25
#define MAX_FIELDS 25
char *fieldnames[MAX_FIELDS];
for (int i = 0; i < MAX_FIELDS; i++)
{
fieldnames[i] = (char*) mxMalloc(50);
}
memcpy(fieldnames[0],"config",sizeof("config"));
memcpy(fieldnames[1],"dims",sizeof("dims"));
memcpy(fieldnames[2],"opts",sizeof("opts"));
memcpy(fieldnames[3],"in",sizeof("in"));
memcpy(fieldnames[4],"out",sizeof("out"));
memcpy(fieldnames[5],"solver",sizeof("solver"));
memcpy(fieldnames[6],"sens_out",sizeof("sens_out"));
memcpy(fieldnames[7],"plan",sizeof("plan"));
memcpy(fieldnames[8],"capsule",sizeof("capsule"));
// create output struct - C_ocp
plhs[0] = mxCreateStructMatrix(1, 1, 9, (const char **) fieldnames);
// MEX: config, dims, opts, in, out, solver, sens_out, plan
// plan
mxArray *plan_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(plan_mat);
l_ptr[0] = (long long) nlp_plan;
mxSetField(plhs[0], 0, "plan", plan_mat);
// config
mxArray *config_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(config_mat);
l_ptr[0] = (long long) nlp_config;
mxSetField(plhs[0], 0, "config", config_mat);
// dims
mxArray *dims_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(dims_mat);
l_ptr[0] = (long long) nlp_dims;
mxSetField(plhs[0], 0, "dims", dims_mat);
// opts
mxArray *opts_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(opts_mat);
l_ptr[0] = (long long) nlp_opts;
mxSetField(plhs[0], 0, "opts", opts_mat);
// in
mxArray *in_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(in_mat);
l_ptr[0] = (long long) nlp_in;
mxSetField(plhs[0], 0, "in", in_mat);
// out
mxArray *out_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(out_mat);
l_ptr[0] = (long long) nlp_out;
mxSetField(plhs[0], 0, "out", out_mat);
// solver
mxArray *solver_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(solver_mat);
l_ptr[0] = (long long) nlp_solver;
mxSetField(plhs[0], 0, "solver", solver_mat);
// TODO: sens_out not actually implemented in templates..
// sens_out
mxArray *sens_out_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(sens_out_mat);
l_ptr[0] = (long long) 1;
mxSetField(plhs[0], 0, "sens_out", sens_out_mat);
// capsule
mxArray *capsule_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(capsule_mat);
l_ptr[0] = (long long) acados_ocp_capsule;
mxSetField(plhs[0], 0, "capsule", capsule_mat);
/* store external function pointers */
// dyn
memcpy(fieldnames[0],"expl_ode_fun",sizeof("expl_ode_fun"));
memcpy(fieldnames[1],"forw_vde",sizeof("forw_vde"));
memcpy(fieldnames[2],"hess_vde",sizeof("hess_vde"));
memcpy(fieldnames[3],"impl_dae_fun",sizeof("impl_dae_fun"));
memcpy(fieldnames[4],"impl_dae_fun_jac_x_xdot_z",sizeof("impl_dae_fun_jac_x_xdot_z"));
memcpy(fieldnames[5],"impl_dae_jac_x_xdot_u_z",sizeof("impl_dae_jac_x_xdot_u_z"));
memcpy(fieldnames[6],"impl_dae_hess",sizeof("impl_dae_hess"));
memcpy(fieldnames[7],"gnsf_phi_fun",sizeof("gnsf_phi_fun"));
memcpy(fieldnames[8],"gnsf_phi_fun_jac_y",sizeof("gnsf_phi_fun_jac_y"));
memcpy(fieldnames[9],"gnsf_phi_jac_y_uhat",sizeof("gnsf_phi_jac_y_uhat"));
memcpy(fieldnames[10],"gnsf_f_lo_jac_x1_x1dot_u_z",sizeof("gnsf_f_lo_jac_x1_x1dot_u_z"));
memcpy(fieldnames[11],"gnsf_get_matrices_fun",sizeof("gnsf_get_matrices_fun"));
memcpy(fieldnames[12],"disc_phi_fun",sizeof("disc_phi_fun"));
memcpy(fieldnames[13],"disc_phi_fun_jac",sizeof("disc_phi_fun_jac"));
memcpy(fieldnames[14],"disc_phi_fun_jac_hess",sizeof("disc_phi_fun_jac_hess"));
// cost
memcpy(fieldnames[15],"cost_y_fun",sizeof("cost_y_fun"));
memcpy(fieldnames[16],"cost_y_fun_jac_ut_xt",sizeof("cost_y_fun_jac_ut_xt"));
memcpy(fieldnames[17],"cost_y_hess",sizeof("cost_y_hess"));
memcpy(fieldnames[18],"ext_cost_fun",sizeof("ext_cost_fun"));
memcpy(fieldnames[19],"ext_cost_fun_jac",sizeof("ext_cost_fun_jac"));
memcpy(fieldnames[20],"ext_cost_fun_jac_hess",sizeof("ext_cost_fun_jac_hess"));
// constraints
memcpy(fieldnames[21],"phi_constraint",sizeof("phi_constraint"));
memcpy(fieldnames[22],"nl_constr_h_fun_jac",sizeof("nl_constr_h_fun_jac"));
memcpy(fieldnames[23],"nl_constr_h_fun",sizeof("nl_constr_h_fun"));
memcpy(fieldnames[24],"nl_constr_h_fun_jac_hess",sizeof("nl_constr_h_fun_jac_hess"));
// create output struct - C_ocp_ext_fun
plhs[1] = mxCreateStructMatrix(1, 1, FIELDS_EXT_FUN, (const char **) fieldnames);
for (int i = 0; i < FIELDS_EXT_FUN; i++)
{
mxFree( fieldnames[i] );
}
/* dynamics */
mxArray *expl_ode_fun_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *forw_vde_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *hess_vde_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *impl_dae_fun_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *impl_dae_fun_jac_x_xdot_z_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *impl_dae_jac_x_xdot_u_z_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *impl_dae_hess_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *gnsf_phi_fun_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *gnsf_phi_fun_jac_y_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *gnsf_phi_jac_y_uhat_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *gnsf_f_lo_jac_x1_x1dot_u_z_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *gnsf_get_matrices_fun_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *disc_phi_fun_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *disc_phi_fun_jac_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *disc_phi_fun_jac_hess_mat = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
{% if solver_options.integrator_type == "ERK" %}
{# TODO: remove _casadi from these names.. #}
l_ptr = mxGetData(forw_vde_mat);
l_ptr[0] = (long long) acados_ocp_capsule->forw_vde_casadi;
l_ptr = mxGetData(expl_ode_fun_mat);
l_ptr[0] = (long long) acados_ocp_capsule->expl_ode_fun;
{% if solver_options.hessian_approx == "EXACT" %}
l_ptr = mxGetData(hess_vde_mat);
l_ptr[0] = (long long) acados_ocp_capsule->hess_vde_casadi;
{%- endif %}
{% elif solver_options.integrator_type == "IRK" %}
l_ptr = mxGetData(impl_dae_fun_mat);
l_ptr[0] = (long long) acados_ocp_capsule->impl_dae_fun;
l_ptr = mxGetData(impl_dae_fun_jac_x_xdot_z_mat);
l_ptr[0] = (long long) acados_ocp_capsule->impl_dae_fun_jac_x_xdot_z;
l_ptr = mxGetData(impl_dae_jac_x_xdot_u_z_mat);
l_ptr[0] = (long long) acados_ocp_capsule->impl_dae_jac_x_xdot_u_z;
{% if solver_options.hessian_approx == "EXACT" %}
l_ptr = mxGetData(impl_dae_hess_mat);
l_ptr[0] = (long long) acados_ocp_capsule->impl_dae_hess;
{%- endif %}
{% elif solver_options.integrator_type == "GNSF" %}
{% if model.gnsf.purely_linear != 1 %}
l_ptr = mxGetData(gnsf_phi_fun_mat);
l_ptr[0] = (long long) acados_ocp_capsule->gnsf_phi_fun;
l_ptr = mxGetData(gnsf_phi_fun_jac_y_mat);
l_ptr[0] = (long long) acados_ocp_capsule->gnsf_phi_fun_jac_y;
l_ptr = mxGetData(gnsf_phi_jac_y_uhat_mat);
l_ptr[0] = (long long) acados_ocp_capsule->gnsf_phi_jac_y_uhat;
{% if model.gnsf.nontrivial_f_LO == 1 %}
l_ptr = mxGetData(gnsf_f_lo_jac_x1_x1dot_u_z_mat);
l_ptr[0] = (long long) acados_ocp_capsule->gnsf_f_lo_jac_x1_x1dot_u_z;
{%- endif %}
{%- endif %}
l_ptr = mxGetData(gnsf_get_matrices_fun_mat);
l_ptr[0] = (long long) acados_ocp_capsule->gnsf_get_matrices_fun;
{% elif solver_options.integrator_type == "DISCRETE" %}
l_ptr = mxGetData(disc_phi_fun_mat);
l_ptr[0] = (long long) acados_ocp_capsule->discr_dyn_phi_fun;
l_ptr = mxGetData(disc_phi_fun_jac_mat);
l_ptr[0] = (long long) acados_ocp_capsule->discr_dyn_phi_fun_jac_ut_xt;
{% if solver_options.hessian_approx == "EXACT" %}
l_ptr = mxGetData(disc_phi_fun_jac_hess_mat);
l_ptr[0] = (long long) acados_ocp_capsule->discr_dyn_phi_fun_jac_ut_xt_hess;
{%- endif %}
{%- endif %}
mxSetField(plhs[1], 0, "expl_ode_fun", expl_ode_fun_mat);
mxSetField(plhs[1], 0, "forw_vde", forw_vde_mat);
mxSetField(plhs[1], 0, "hess_vde", hess_vde_mat);
mxSetField(plhs[1], 0, "gnsf_phi_fun", gnsf_phi_fun_mat);
mxSetField(plhs[1], 0, "gnsf_phi_fun_jac_y", gnsf_phi_fun_jac_y_mat);
mxSetField(plhs[1], 0, "gnsf_phi_jac_y_uhat", gnsf_phi_jac_y_uhat_mat);
mxSetField(plhs[1], 0, "gnsf_f_lo_jac_x1_x1dot_u_z", gnsf_f_lo_jac_x1_x1dot_u_z_mat);
mxSetField(plhs[1], 0, "gnsf_get_matrices_fun", gnsf_get_matrices_fun_mat);
mxSetField(plhs[1], 0, "impl_dae_fun", impl_dae_fun_mat);
mxSetField(plhs[1], 0, "impl_dae_fun_jac_x_xdot_z", impl_dae_fun_jac_x_xdot_z_mat);
mxSetField(plhs[1], 0, "impl_dae_jac_x_xdot_u_z", impl_dae_jac_x_xdot_u_z_mat);
mxSetField(plhs[1], 0, "impl_dae_hess", impl_dae_hess_mat);
mxSetField(plhs[1], 0, "disc_phi_fun", disc_phi_fun_mat);
mxSetField(plhs[1], 0, "disc_phi_fun_jac", disc_phi_fun_jac_mat);
mxSetField(plhs[1], 0, "disc_phi_fun_jac_hess", disc_phi_fun_jac_hess_mat);
/* constaints */
mxArray *phi_constraint_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(phi_constraint_mat);
{%- if constraints.constr_type == "BGP" %}
l_ptr[0] = (long long) acados_ocp_capsule->phi_constraint;
{% endif %}
{% if constraints.constr_type_e == "BGP" %}
l_ptr[1] = (long long) &acados_ocp_capsule->phi_e_constraint;
{% endif %}
mxSetField(plhs[1], 0, "phi_constraint", phi_constraint_mat);
mxArray *nl_constr_h_fun_jac_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(nl_constr_h_fun_jac_mat);
{% if constraints.constr_type == "BGH" and dims.nh > 0 %}
l_ptr[0] = (long long) acados_ocp_capsule->nl_constr_h_fun_jac;
{% endif %}
{% if constraints.constr_type_e == "BGH" and dims.nh_e > 0 %}
l_ptr[1] = (long long) &acados_ocp_capsule->nl_constr_h_e_fun_jac;
{%- endif %}
mxSetField(plhs[1], 0, "nl_constr_h_fun_jac", nl_constr_h_fun_jac_mat);
mxArray *nl_constr_h_fun_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(nl_constr_h_fun_mat);
{% if constraints.constr_type == "BGH" and dims.nh > 0 %}
l_ptr[0] = (long long) acados_ocp_capsule->nl_constr_h_fun;
{% endif %}
{% if constraints.constr_type_e == "BGH" and dims.nh_e > 0 %}
l_ptr[1] = (long long) &acados_ocp_capsule->nl_constr_h_e_fun;
{%- endif %}
mxSetField(plhs[1], 0, "nl_constr_h_fun", nl_constr_h_fun_mat);
mxArray *nl_constr_h_fun_jac_hess_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(nl_constr_h_fun_jac_hess_mat);
{% if constraints.constr_type == "BGH" and dims.nh > 0 and solver_options.hessian_approx == "EXACT" %}
l_ptr[0] = (long long) acados_ocp_capsule->nl_constr_h_fun_jac_hess;
{% endif %}
{% if constraints.constr_type_e == "BGH" and dims.nh_e > 0 and solver_options.hessian_approx == "EXACT" %}
l_ptr[1] = (long long) &acados_ocp_capsule->nl_constr_h_e_fun_jac_hess;
{%- endif %}
mxSetField(plhs[1], 0, "nl_constr_h_fun_jac_hess", nl_constr_h_fun_jac_hess_mat);
/* cost */
mxArray *cost_y_fun_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(cost_y_fun_mat);
{% if cost.cost_type == "NONLINEAR_LS" %}
l_ptr[0] = (long long) acados_ocp_capsule->cost_y_fun;
{% endif %}
{% if cost.cost_type_e == "NONLINEAR_LS" %}
l_ptr[1] = (long long) &acados_ocp_capsule->cost_y_e_fun;
{%- endif %}
mxSetField(plhs[1], 0, "cost_y_fun", cost_y_fun_mat);
mxArray *cost_y_fun_jac_ut_xt_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(cost_y_fun_jac_ut_xt_mat);
{% if cost.cost_type == "NONLINEAR_LS" %}
l_ptr[0] = (long long) acados_ocp_capsule->cost_y_fun_jac_ut_xt;
{% endif %}
{% if cost.cost_type_e == "NONLINEAR_LS" %}
l_ptr[1] = (long long) &acados_ocp_capsule->cost_y_e_fun_jac_ut_xt;
{%- endif %}
mxSetField(plhs[1], 0, "cost_y_fun_jac_ut_xt", cost_y_fun_jac_ut_xt_mat);
mxArray *cost_y_hess_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(cost_y_hess_mat);
{% if cost.cost_type == "NONLINEAR_LS" %}
l_ptr[0] = (long long) acados_ocp_capsule->cost_y_hess;
{% endif %}
{% if cost.cost_type_e == "NONLINEAR_LS" %}
l_ptr[1] = (long long) &acados_ocp_capsule->cost_y_e_hess;
{%- endif %}
mxSetField(plhs[1], 0, "cost_y_hess", cost_y_hess_mat);
mxArray *ext_cost_fun_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(ext_cost_fun_mat);
{% if cost.cost_type == "EXTERNAL" %}
l_ptr[0] = (long long) acados_ocp_capsule->ext_cost_fun;
{% endif -%}
{% if cost.cost_type_e == "EXTERNAL" %}
l_ptr[1] = (long long) &acados_ocp_capsule->ext_cost_e_fun;
{%- endif %}
mxSetField(plhs[1], 0, "ext_cost_fun", ext_cost_fun_mat);
mxArray *ext_cost_fun_jac_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(ext_cost_fun_jac_mat);
{% if cost.cost_type == "EXTERNAL" %}
l_ptr[0] = (long long) acados_ocp_capsule->ext_cost_fun_jac;
{% endif -%}
{% if cost.cost_type_e == "EXTERNAL" %}
l_ptr[1] = (long long) &acados_ocp_capsule->ext_cost_e_fun_jac;
{%- endif %}
mxSetField(plhs[1], 0, "ext_cost_fun_jac", ext_cost_fun_jac_mat);
mxArray *ext_cost_fun_jac_hess_mat = mxCreateNumericMatrix(1, 2, mxINT64_CLASS, mxREAL);
l_ptr = mxGetData(ext_cost_fun_jac_hess_mat);
{% if cost.cost_type == "EXTERNAL" %}
l_ptr[0] = (long long) acados_ocp_capsule->ext_cost_fun_jac_hess;
{% endif -%}
{% if cost.cost_type_e == "EXTERNAL" %}
l_ptr[1] = (long long) &acados_ocp_capsule->ext_cost_e_fun_jac_hess;
{%- endif %}
mxSetField(plhs[1], 0, "ext_cost_fun_jac_hess", ext_cost_fun_jac_hess_mat);
return;
}

@ -0,0 +1,70 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
// system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// acados
#include "acados_solver_{{ model.name }}.h"
// mex
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
int status = 0;
long long *ptr;
// mexPrintf("\nin mex_acados_free\n");
const mxArray *C_ocp = prhs[0];
// capsule
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "capsule" ) );
{{ model.name }}_solver_capsule *capsule = ({{ model.name }}_solver_capsule *) ptr[0];
status = {{ model.name }}_acados_free(capsule);
if (status)
{
mexPrintf("{{ model.name }}_acados_free() returned status %d.\n", status);
}
status = {{ model.name }}_acados_free_capsule(capsule);
if (status)
{
mexPrintf("{{ model.name }}_acados_free_capsule() returned status %d.\n", status);
}
return;
}

@ -0,0 +1,570 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
// standard
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// acados
#include "acados/utils/print.h"
#include "acados_c/ocp_nlp_interface.h"
#include "acados_solver_{{ model.name }}.h"
// mex
#include "mex.h"
#include "mex_macros.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
long long *ptr;
int acados_size;
mxArray *mex_field;
char fun_name[20] = "ocp_set";
char buffer [500]; // for error messages
/* RHS */
int min_nrhs = 6;
char *ext_fun_type = mxArrayToString( prhs[0] );
char *ext_fun_type_e = mxArrayToString( prhs[1] );
// C ocp
const mxArray *C_ocp = prhs[2];
// capsule
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "capsule" ) );
{{ model.name }}_solver_capsule *capsule = ({{ model.name }}_solver_capsule *) ptr[0];
// plan
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "plan" ) );
ocp_nlp_plan_t *plan = (ocp_nlp_plan_t *) ptr[0];
// config
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "config" ) );
ocp_nlp_config *config = (ocp_nlp_config *) ptr[0];
// dims
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "dims" ) );
ocp_nlp_dims *dims = (ocp_nlp_dims *) ptr[0];
// opts
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "opts" ) );
void *opts = (void *) ptr[0];
// in
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "in" ) );
ocp_nlp_in *in = (ocp_nlp_in *) ptr[0];
// out
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "out" ) );
ocp_nlp_out *out = (ocp_nlp_out *) ptr[0];
// solver
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "solver" ) );
ocp_nlp_solver *solver = (ocp_nlp_solver *) ptr[0];
const mxArray *C_ext_fun_pointers = prhs[3];
// field
char *field = mxArrayToString( prhs[4] );
// value
double *value = mxGetPr( prhs[5] );
// for checks
int matlab_size = (int) mxGetNumberOfElements( prhs[5] );
int nrow = (int) mxGetM( prhs[5] );
int ncol = (int) mxGetN( prhs[5] );
int N = dims->N;
int nu = dims->nu[0];
int nx = dims->nx[0];
// stage
int s0, se;
if (nrhs==min_nrhs)
{
s0 = 0;
se = N;
}
else if (nrhs==min_nrhs+1)
{
s0 = mxGetScalar( prhs[6] );
if (s0 > N)
{
sprintf(buffer, "ocp_set: N < specified stage = %d\n", s0);
mexErrMsgTxt(buffer);
}
se = s0 + 1;
}
else
{
sprintf(buffer, "ocp_set: wrong nrhs: %d\n", nrhs);
mexErrMsgTxt(buffer);
}
/* Set value */
// constraints
if (!strcmp(field, "constr_x0"))
{
acados_size = nx;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, 0, "lbx", value);
ocp_nlp_constraints_model_set(config, dims, in, 0, "ubx", value);
}
else if (!strcmp(field, "constr_C"))
{
for (int ii=s0; ii<se; ii++)
{
int ng = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "ug");
MEX_DIM_CHECK_MAT(fun_name, "constr_C", nrow, ncol, ng, nx);
ocp_nlp_constraints_model_set(config, dims, in, ii, "C", value);
}
}
else if (!strcmp(field, "constr_lbx"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "lbx");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "lbx", value);
}
}
else if (!strcmp(field, "constr_ubx"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "ubx");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "ubx", value);
}
}
else if (!strcmp(field, "constr_lbu"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "lbu");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "lbu", value);
}
}
else if (!strcmp(field, "constr_ubu"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "ubu");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "ubu", value);
}
}
else if (!strcmp(field, "constr_D"))
{
for (int ii=s0; ii<se; ii++)
{
int ng = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "ug");
MEX_DIM_CHECK_MAT(fun_name, "constr_D", nrow, ncol, ng, nu);
ocp_nlp_constraints_model_set(config, dims, in, ii, "D", value);
}
}
else if (!strcmp(field, "constr_lg"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "lg");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "lg", value);
}
}
else if (!strcmp(field, "constr_ug"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "ug");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "ug", value);
}
}
else if (!strcmp(field, "constr_lh"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "lh");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "lh", value);
}
}
else if (!strcmp(field, "constr_uh"))
{
for (int ii=s0; ii<se; ii++)
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "uh");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_constraints_model_set(config, dims, in, ii, "uh", value);
}
}
// cost:
else if (!strcmp(field, "cost_y_ref"))
{
for (int ii=s0; ii<se; ii++)
{
if ((plan->nlp_cost[ii] == LINEAR_LS) || (plan->nlp_cost[ii] == NONLINEAR_LS))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "y_ref");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_cost_model_set(config, dims, in, ii, "y_ref", value);
}
else
{
MEX_FIELD_NOT_SUPPORTED_FOR_COST_STAGE(fun_name, field, plan->nlp_cost[ii], ii);
}
}
}
else if (!strcmp(field, "cost_y_ref_e"))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, N, "y_ref");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_cost_model_set(config, dims, in, N, "y_ref", value);
}
else if (!strcmp(field, "cost_Vu"))
{
for (int ii=s0; ii<se; ii++)
{
if ((plan->nlp_cost[ii] == LINEAR_LS) || (plan->nlp_cost[ii] == NONLINEAR_LS))
{
int ny = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "y_ref");
int nu = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "u");
acados_size = ny * nu;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_cost_model_set(config, dims, in, ii, "Vu", value);
}
else
{
MEX_FIELD_NOT_SUPPORTED_FOR_COST_STAGE(fun_name, field, plan->nlp_cost[ii], ii);
}
}
}
else if (!strcmp(field, "cost_Vx"))
{
for (int ii=s0; ii<se; ii++)
{
if ((plan->nlp_cost[ii] == LINEAR_LS) || (plan->nlp_cost[ii] == NONLINEAR_LS))
{
int ny = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "y_ref");
int nx = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "x");
acados_size = ny * nx;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_cost_model_set(config, dims, in, ii, "Vx", value);
}
else
{
MEX_FIELD_NOT_SUPPORTED_FOR_COST_STAGE(fun_name, field, plan->nlp_cost[ii], ii);
}
}
}
else if (!strcmp(field, "cost_W"))
{
for (int ii=s0; ii<se; ii++)
{
if ((plan->nlp_cost[ii] == LINEAR_LS) || (plan->nlp_cost[ii] == NONLINEAR_LS))
{
int ny = ocp_nlp_dims_get_from_attr(config, dims, out, s0, "y_ref");
acados_size = ny * ny;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
ocp_nlp_cost_model_set(config, dims, in, ii, "W", value);
}
else
{
MEX_FIELD_NOT_SUPPORTED_FOR_COST_STAGE(fun_name, field, plan->nlp_cost[ii], ii);
}
}
}
else if (!strcmp(field, "cost_Z"))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, s0, "cost_Z");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=s0; ii<se; ii++)
{
ocp_nlp_cost_model_set(config, dims, in, ii, "Z", value);
}
}
else if (!strcmp(field, "cost_Zl"))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, s0, "Zl");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=s0; ii<se; ii++)
{
ocp_nlp_cost_model_set(config, dims, in, ii, "Zl", value);
}
}
else if (!strcmp(field, "cost_Zu"))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, s0, "Zu");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=s0; ii<se; ii++)
{
ocp_nlp_cost_model_set(config, dims, in, ii, "Zu", value);
}
}
else if (!strcmp(field, "cost_z"))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, s0, "cost_z");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=s0; ii<se; ii++)
{
ocp_nlp_cost_model_set(config, dims, in, ii, "z", value);
}
}
else if (!strcmp(field, "cost_zl"))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, s0, "zl");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=s0; ii<se; ii++)
{
ocp_nlp_cost_model_set(config, dims, in, ii, "zl", value);
}
}
else if (!strcmp(field, "cost_zu"))
{
acados_size = ocp_nlp_dims_get_from_attr(config, dims, out, s0, "zu");
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=s0; ii<se; ii++)
{
ocp_nlp_cost_model_set(config, dims, in, ii, "zu", value);
}
}
// constraints TODO
// // NOTE(oj): how is it with Jbx, Jbu, idxb can they be changed?!
// else if (!strcmp(field, "constr_lbx"))
// {
// // bounds at 0 are a special case.
// if (s0==0)
// {
// sprintf(buffer, "%s cannot set %s for stage 0", fun_name, field);
// mexErrMsgTxt(buffer);
// }
// }
// initializations
else if (!strcmp(field, "init_x"))
{
if (nrhs!=min_nrhs)
MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field)
acados_size = (N+1) * nx;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=0; ii<=N; ii++)
{
ocp_nlp_out_set(config, dims, out, ii, "x", value+ii*nx);
}
}
else if (!strcmp(field, "init_u"))
{
if (nrhs!=min_nrhs)
MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field)
acados_size = N*nu;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=0; ii<N; ii++)
{
ocp_nlp_out_set(config, dims, out, ii, "u", value+ii*nu);
}
}
else if (!strcmp(field, "init_z"))
{
sim_solver_plan_t sim_plan = plan->sim_solver_plan[0];
sim_solver_t type = sim_plan.sim_solver;
if (type == IRK)
{
int nz = ocp_nlp_dims_get_from_attr(config, dims, out, 0, "z");
if (nrhs!=min_nrhs)
MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field)
acados_size = N*nz;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=0; ii<N; ii++)
{
ocp_nlp_set(config, solver, ii, "z_guess", value+ii*nz);
}
}
else
{
MEX_FIELD_ONLY_SUPPORTED_FOR_SOLVER(fun_name, "init_z", "irk")
}
}
else if (!strcmp(field, "init_xdot"))
{
sim_solver_plan_t sim_plan = plan->sim_solver_plan[0];
sim_solver_t type = sim_plan.sim_solver;
if (type == IRK)
{
int nx = ocp_nlp_dims_get_from_attr(config, dims, out, 0, "x");
if (nrhs!=min_nrhs)
MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field)
acados_size = N*nx;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=0; ii<N; ii++)
{
ocp_nlp_set(config, solver, ii, "xdot_guess", value+ii*nx);
}
}
else
{
MEX_FIELD_ONLY_SUPPORTED_FOR_SOLVER(fun_name, "init_z", "irk")
}
}
else if (!strcmp(field, "init_gnsf_phi"))
{
sim_solver_plan_t sim_plan = plan->sim_solver_plan[0];
sim_solver_t type = sim_plan.sim_solver;
if (type == GNSF)
{
int nout = ocp_nlp_dims_get_from_attr(config, dims, out, 0, "init_gnsf_phi");
if (nrhs!=min_nrhs)
MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field)
acados_size = N*nout;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=0; ii<N; ii++)
{
ocp_nlp_set(config, solver, ii, "gnsf_phi_guess", value+ii*nx);
}
}
else
{
MEX_FIELD_ONLY_SUPPORTED_FOR_SOLVER(fun_name, "init_gnsf_phi", "irk_gnsf")
}
}
else if (!strcmp(field, "init_pi"))
{
if (nrhs!=min_nrhs)
MEX_SETTER_NO_STAGE_SUPPORT(fun_name, field)
acados_size = N*nx;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
for (int ii=0; ii<N; ii++)
{
ocp_nlp_out_set(config, dims, out, ii, "pi", value+ii*nx);
}
}
else if (!strcmp(field, "init_lam"))
{
for (int ii=s0; ii<se; ii++)
{
int nlam = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "lam");
MEX_DIM_CHECK_VEC(fun_name, "lam", nrow*ncol, nlam);
ocp_nlp_out_set(config, dims, out, ii, "lam", value);
}
}
else if (!strcmp(field, "init_t"))
{
for (int ii=s0; ii<se; ii++)
{
int nt = ocp_nlp_dims_get_from_attr(config, dims, out, ii, "t");
MEX_DIM_CHECK_VEC(fun_name, "t", nrow*ncol, nt);
ocp_nlp_out_set(config, dims, out, ii, "t", value);
}
}
else if (!strcmp(field, "p"))
{
if (nrhs==min_nrhs) // all stages
{
for (int ii=0; ii<=N; ii++)
{
{{ model.name }}_acados_update_params(capsule, ii, value, matlab_size);
}
}
else if (nrhs==min_nrhs+1) // one stage
{
int stage = mxGetScalar( prhs[6] );
{{ model.name }}_acados_update_params(capsule, stage, value, matlab_size);
}
}
else if (!strcmp(field, "nlp_solver_max_iter"))
{
acados_size = 1;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
int nlp_solver_max_iter = (int) value[0];
ocp_nlp_solver_opts_set(config, opts, "max_iter", &nlp_solver_max_iter);
}
else if (!strcmp(field, "rti_phase"))
{
acados_size = 1;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
int rti_phase = (int) value[0];
if (plan->nlp_solver == SQP && rti_phase != 0)
{
MEX_FIELD_ONLY_SUPPORTED_FOR_SOLVER(fun_name, field, "sqp_rti")
}
ocp_nlp_solver_opts_set(config, opts, "rti_phase", &rti_phase);
}
else if (!strcmp(field, "qp_warm_start"))
{
acados_size = 1;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
int qp_warm_start = (int) value[0];
ocp_nlp_solver_opts_set(config, opts, "qp_warm_start", &qp_warm_start);
}
else if (!strcmp(field, "warm_start_first_qp"))
{
acados_size = 1;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
int warm_start_first_qp = (int) value[0];
ocp_nlp_solver_opts_set(config, opts, "warm_start_first_qp", &warm_start_first_qp);
}
else if (!strcmp(field, "print_level"))
{
acados_size = 1;
MEX_DIM_CHECK_VEC(fun_name, field, matlab_size, acados_size);
int print_level = (int) value[0];
ocp_nlp_solver_opts_set(config, opts, "print_level", &print_level);
}
else
{
MEX_FIELD_NOT_SUPPORTED_SUGGEST(fun_name, field, "p, constr_x0,\
constr_lbx, constr_ubx, constr_C, constr_D, constr_lg, constr_ug, constr_lh, constr_uh\
constr_lbu, constr_ubu, cost_y_ref[_e],\
cost_Vu, cost_Vx, cost_Vz, cost_W, cost_Z, cost_Zl, cost_Zu, cost_z,\
cost_zl, cost_zu, init_x, init_u, init_z, init_xdot, init_gnsf_phi,\
init_pi, nlp_solver_max_iter, qp_warm_start, warm_start_first_qp, print_level");
}
return;
}

@ -0,0 +1,59 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
// system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// acados
#include "acados_solver_{{ model.name }}.h"
// mex
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// C_ocp
long long *ptr;
const mxArray *C_ocp = prhs[0];
// capsule
ptr = (long long *) mxGetData( mxGetField( C_ocp, 0, "capsule" ) );
{{ model.name }}_solver_capsule *capsule = ({{ model.name }}_solver_capsule *) ptr[0];
// solve
{{ model.name }}_acados_solve(capsule);
}

@ -0,0 +1,508 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
{%- if solver_options.hessian_approx %}
{%- set hessian_approx = solver_options.hessian_approx %}
{%- elif solver_options.sens_hess %}
{%- set hessian_approx = "EXACT" %}
{%- else %}
{%- set hessian_approx = "GAUSS_NEWTON" %}
{%- endif %}
// standard
#include <stdio.h>
#include <stdlib.h>
// acados
#include "acados_c/external_function_interface.h"
#include "acados_c/sim_interface.h"
#include "acados_c/external_function_interface.h"
#include "acados/sim/sim_common.h"
#include "acados/utils/external_function_generic.h"
#include "acados/utils/print.h"
// example specific
#include "{{ model.name }}_model/{{ model.name }}_model.h"
#include "acados_sim_solver_{{ model.name }}.h"
// ** solver data **
sim_solver_capsule * {{ model.name }}_acados_sim_solver_create_capsule()
{
void* capsule_mem = malloc(sizeof(sim_solver_capsule));
sim_solver_capsule *capsule = (sim_solver_capsule *) capsule_mem;
return capsule;
}
int {{ model.name }}_acados_sim_solver_free_capsule(sim_solver_capsule * capsule)
{
free(capsule);
return 0;
}
int {{ model.name }}_acados_sim_create(sim_solver_capsule * capsule)
{
// initialize
const int nx = {{ model.name | upper }}_NX;
const int nu = {{ model.name | upper }}_NU;
const int nz = {{ model.name | upper }}_NZ;
const int np = {{ model.name | upper }}_NP;
bool tmp_bool;
{#// double Tsim = {{ solver_options.tf / dims.N }};#}
double Tsim = {{ solver_options.Tsim }};
{% if solver_options.integrator_type == "IRK" %}
capsule->sim_impl_dae_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
capsule->sim_impl_dae_fun_jac_x_xdot_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
capsule->sim_impl_dae_jac_x_xdot_u_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
// external functions (implicit model)
capsule->sim_impl_dae_fun->casadi_fun = &{{ model.name }}_impl_dae_fun;
capsule->sim_impl_dae_fun->casadi_work = &{{ model.name }}_impl_dae_fun_work;
capsule->sim_impl_dae_fun->casadi_sparsity_in = &{{ model.name }}_impl_dae_fun_sparsity_in;
capsule->sim_impl_dae_fun->casadi_sparsity_out = &{{ model.name }}_impl_dae_fun_sparsity_out;
capsule->sim_impl_dae_fun->casadi_n_in = &{{ model.name }}_impl_dae_fun_n_in;
capsule->sim_impl_dae_fun->casadi_n_out = &{{ model.name }}_impl_dae_fun_n_out;
external_function_param_casadi_create(capsule->sim_impl_dae_fun, np);
capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_fun = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z;
capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_work = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_work;
capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_sparsity_in = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_sparsity_in;
capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_sparsity_out = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_sparsity_out;
capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_n_in = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_n_in;
capsule->sim_impl_dae_fun_jac_x_xdot_z->casadi_n_out = &{{ model.name }}_impl_dae_fun_jac_x_xdot_z_n_out;
external_function_param_casadi_create(capsule->sim_impl_dae_fun_jac_x_xdot_z, np);
// external_function_param_casadi impl_dae_jac_x_xdot_u_z;
capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_fun = &{{ model.name }}_impl_dae_jac_x_xdot_u_z;
capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_work = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_work;
capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_sparsity_in = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_sparsity_in;
capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_sparsity_out = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_sparsity_out;
capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_n_in = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_n_in;
capsule->sim_impl_dae_jac_x_xdot_u_z->casadi_n_out = &{{ model.name }}_impl_dae_jac_x_xdot_u_z_n_out;
external_function_param_casadi_create(capsule->sim_impl_dae_jac_x_xdot_u_z, np);
{%- if hessian_approx == "EXACT" %}
capsule->sim_impl_dae_hess = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
// external_function_param_casadi impl_dae_jac_x_xdot_u_z;
capsule->sim_impl_dae_hess->casadi_fun = &{{ model.name }}_impl_dae_hess;
capsule->sim_impl_dae_hess->casadi_work = &{{ model.name }}_impl_dae_hess_work;
capsule->sim_impl_dae_hess->casadi_sparsity_in = &{{ model.name }}_impl_dae_hess_sparsity_in;
capsule->sim_impl_dae_hess->casadi_sparsity_out = &{{ model.name }}_impl_dae_hess_sparsity_out;
capsule->sim_impl_dae_hess->casadi_n_in = &{{ model.name }}_impl_dae_hess_n_in;
capsule->sim_impl_dae_hess->casadi_n_out = &{{ model.name }}_impl_dae_hess_n_out;
external_function_param_casadi_create(capsule->sim_impl_dae_hess, np);
{%- endif %}
{% elif solver_options.integrator_type == "ERK" %}
// explicit ode
capsule->sim_forw_vde_casadi = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
capsule->sim_expl_ode_fun_casadi = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
capsule->sim_forw_vde_casadi->casadi_fun = &{{ model.name }}_expl_vde_forw;
capsule->sim_forw_vde_casadi->casadi_n_in = &{{ model.name }}_expl_vde_forw_n_in;
capsule->sim_forw_vde_casadi->casadi_n_out = &{{ model.name }}_expl_vde_forw_n_out;
capsule->sim_forw_vde_casadi->casadi_sparsity_in = &{{ model.name }}_expl_vde_forw_sparsity_in;
capsule->sim_forw_vde_casadi->casadi_sparsity_out = &{{ model.name }}_expl_vde_forw_sparsity_out;
capsule->sim_forw_vde_casadi->casadi_work = &{{ model.name }}_expl_vde_forw_work;
external_function_param_casadi_create(capsule->sim_forw_vde_casadi, np);
capsule->sim_expl_ode_fun_casadi->casadi_fun = &{{ model.name }}_expl_ode_fun;
capsule->sim_expl_ode_fun_casadi->casadi_n_in = &{{ model.name }}_expl_ode_fun_n_in;
capsule->sim_expl_ode_fun_casadi->casadi_n_out = &{{ model.name }}_expl_ode_fun_n_out;
capsule->sim_expl_ode_fun_casadi->casadi_sparsity_in = &{{ model.name }}_expl_ode_fun_sparsity_in;
capsule->sim_expl_ode_fun_casadi->casadi_sparsity_out = &{{ model.name }}_expl_ode_fun_sparsity_out;
capsule->sim_expl_ode_fun_casadi->casadi_work = &{{ model.name }}_expl_ode_fun_work;
external_function_param_casadi_create(capsule->sim_expl_ode_fun_casadi, np);
{%- if hessian_approx == "EXACT" %}
capsule->sim_expl_ode_hess = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
// external_function_param_casadi impl_dae_jac_x_xdot_u_z;
capsule->sim_expl_ode_hess->casadi_fun = &{{ model.name }}_expl_ode_hess;
capsule->sim_expl_ode_hess->casadi_work = &{{ model.name }}_expl_ode_hess_work;
capsule->sim_expl_ode_hess->casadi_sparsity_in = &{{ model.name }}_expl_ode_hess_sparsity_in;
capsule->sim_expl_ode_hess->casadi_sparsity_out = &{{ model.name }}_expl_ode_hess_sparsity_out;
capsule->sim_expl_ode_hess->casadi_n_in = &{{ model.name }}_expl_ode_hess_n_in;
capsule->sim_expl_ode_hess->casadi_n_out = &{{ model.name }}_expl_ode_hess_n_out;
external_function_param_casadi_create(capsule->sim_expl_ode_hess, np);
{%- endif %}
{% elif solver_options.integrator_type == "GNSF" -%}
{% if model.gnsf.purely_linear != 1 %}
capsule->sim_gnsf_phi_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
capsule->sim_gnsf_phi_fun_jac_y = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
capsule->sim_gnsf_phi_jac_y_uhat = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
{% if model.gnsf.nontrivial_f_LO == 1 %}
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
{%- endif %}
{%- endif %}
capsule->sim_gnsf_get_matrices_fun = (external_function_param_casadi *) malloc(sizeof(external_function_param_casadi));
{% if model.gnsf.purely_linear != 1 %}
capsule->sim_gnsf_phi_fun->casadi_fun = &{{ model.name }}_gnsf_phi_fun;
capsule->sim_gnsf_phi_fun->casadi_n_in = &{{ model.name }}_gnsf_phi_fun_n_in;
capsule->sim_gnsf_phi_fun->casadi_n_out = &{{ model.name }}_gnsf_phi_fun_n_out;
capsule->sim_gnsf_phi_fun->casadi_sparsity_in = &{{ model.name }}_gnsf_phi_fun_sparsity_in;
capsule->sim_gnsf_phi_fun->casadi_sparsity_out = &{{ model.name }}_gnsf_phi_fun_sparsity_out;
capsule->sim_gnsf_phi_fun->casadi_work = &{{ model.name }}_gnsf_phi_fun_work;
external_function_param_casadi_create(capsule->sim_gnsf_phi_fun, np);
capsule->sim_gnsf_phi_fun_jac_y->casadi_fun = &{{ model.name }}_gnsf_phi_fun_jac_y;
capsule->sim_gnsf_phi_fun_jac_y->casadi_n_in = &{{ model.name }}_gnsf_phi_fun_jac_y_n_in;
capsule->sim_gnsf_phi_fun_jac_y->casadi_n_out = &{{ model.name }}_gnsf_phi_fun_jac_y_n_out;
capsule->sim_gnsf_phi_fun_jac_y->casadi_sparsity_in = &{{ model.name }}_gnsf_phi_fun_jac_y_sparsity_in;
capsule->sim_gnsf_phi_fun_jac_y->casadi_sparsity_out = &{{ model.name }}_gnsf_phi_fun_jac_y_sparsity_out;
capsule->sim_gnsf_phi_fun_jac_y->casadi_work = &{{ model.name }}_gnsf_phi_fun_jac_y_work;
external_function_param_casadi_create(capsule->sim_gnsf_phi_fun_jac_y, np);
capsule->sim_gnsf_phi_jac_y_uhat->casadi_fun = &{{ model.name }}_gnsf_phi_jac_y_uhat;
capsule->sim_gnsf_phi_jac_y_uhat->casadi_n_in = &{{ model.name }}_gnsf_phi_jac_y_uhat_n_in;
capsule->sim_gnsf_phi_jac_y_uhat->casadi_n_out = &{{ model.name }}_gnsf_phi_jac_y_uhat_n_out;
capsule->sim_gnsf_phi_jac_y_uhat->casadi_sparsity_in = &{{ model.name }}_gnsf_phi_jac_y_uhat_sparsity_in;
capsule->sim_gnsf_phi_jac_y_uhat->casadi_sparsity_out = &{{ model.name }}_gnsf_phi_jac_y_uhat_sparsity_out;
capsule->sim_gnsf_phi_jac_y_uhat->casadi_work = &{{ model.name }}_gnsf_phi_jac_y_uhat_work;
external_function_param_casadi_create(capsule->sim_gnsf_phi_jac_y_uhat, np);
{% if model.gnsf.nontrivial_f_LO == 1 %}
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_fun = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz;
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_n_in = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_n_in;
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_n_out = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_n_out;
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_sparsity_in = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_sparsity_in;
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_sparsity_out = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_sparsity_out;
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z->casadi_work = &{{ model.name }}_gnsf_f_lo_fun_jac_x1k1uz_work;
external_function_param_casadi_create(capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z, np);
{%- endif %}
{%- endif %}
capsule->sim_gnsf_get_matrices_fun->casadi_fun = &{{ model.name }}_gnsf_get_matrices_fun;
capsule->sim_gnsf_get_matrices_fun->casadi_n_in = &{{ model.name }}_gnsf_get_matrices_fun_n_in;
capsule->sim_gnsf_get_matrices_fun->casadi_n_out = &{{ model.name }}_gnsf_get_matrices_fun_n_out;
capsule->sim_gnsf_get_matrices_fun->casadi_sparsity_in = &{{ model.name }}_gnsf_get_matrices_fun_sparsity_in;
capsule->sim_gnsf_get_matrices_fun->casadi_sparsity_out = &{{ model.name }}_gnsf_get_matrices_fun_sparsity_out;
capsule->sim_gnsf_get_matrices_fun->casadi_work = &{{ model.name }}_gnsf_get_matrices_fun_work;
external_function_param_casadi_create(capsule->sim_gnsf_get_matrices_fun, np);
{% endif %}
// sim plan & config
sim_solver_plan_t plan;
plan.sim_solver = {{ solver_options.integrator_type }};
// create correct config based on plan
sim_config * {{ model.name }}_sim_config = sim_config_create(plan);
capsule->acados_sim_config = {{ model.name }}_sim_config;
// sim dims
void *{{ model.name }}_sim_dims = sim_dims_create({{ model.name }}_sim_config);
capsule->acados_sim_dims = {{ model.name }}_sim_dims;
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "nx", &nx);
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "nu", &nu);
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "nz", &nz);
{% if solver_options.integrator_type == "GNSF" %}
int gnsf_nx1 = {{ dims.gnsf_nx1 }};
int gnsf_nz1 = {{ dims.gnsf_nz1 }};
int gnsf_nout = {{ dims.gnsf_nout }};
int gnsf_ny = {{ dims.gnsf_ny }};
int gnsf_nuhat = {{ dims.gnsf_nuhat }};
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "nx1", &gnsf_nx1);
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "nz1", &gnsf_nz1);
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "nout", &gnsf_nout);
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "ny", &gnsf_ny);
sim_dims_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims, "nuhat", &gnsf_nuhat);
{% endif %}
// sim opts
sim_opts *{{ model.name }}_sim_opts = sim_opts_create({{ model.name }}_sim_config, {{ model.name }}_sim_dims);
capsule->acados_sim_opts = {{ model.name }}_sim_opts;
int tmp_int = {{ solver_options.sim_method_newton_iter }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "newton_iter", &tmp_int);
sim_collocation_type collocation_type = {{ solver_options.collocation_type }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "collocation_type", &collocation_type);
{% if problem_class == "SIM" %}
tmp_int = {{ solver_options.sim_method_num_stages }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "num_stages", &tmp_int);
tmp_int = {{ solver_options.sim_method_num_steps }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "num_steps", &tmp_int);
// options that are not available to AcadosOcpSolver
// (in OCP they will be determined by other options, like exact_hessian)
tmp_bool = {{ solver_options.sens_forw }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "sens_forw", &tmp_bool);
tmp_bool = {{ solver_options.sens_adj }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "sens_adj", &tmp_bool);
tmp_bool = {{ solver_options.sens_algebraic }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "sens_algebraic", &tmp_bool);
tmp_bool = {{ solver_options.sens_hess }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "sens_hess", &tmp_bool);
tmp_bool = {{ solver_options.output_z }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "output_z", &tmp_bool);
{% else %} {# num_stages and num_steps of first shooting interval are used #}
tmp_int = {{ solver_options.sim_method_num_stages[0] }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "num_stages", &tmp_int);
tmp_int = {{ solver_options.sim_method_num_steps[0] }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "num_steps", &tmp_int);
tmp_bool = {{ solver_options.sim_method_jac_reuse[0] }};
sim_opts_set({{ model.name }}_sim_config, {{ model.name }}_sim_opts, "jac_reuse", &tmp_bool);
{% endif %}
// sim in / out
sim_in *{{ model.name }}_sim_in = sim_in_create({{ model.name }}_sim_config, {{ model.name }}_sim_dims);
capsule->acados_sim_in = {{ model.name }}_sim_in;
sim_out *{{ model.name }}_sim_out = sim_out_create({{ model.name }}_sim_config, {{ model.name }}_sim_dims);
capsule->acados_sim_out = {{ model.name }}_sim_out;
sim_in_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims,
{{ model.name }}_sim_in, "T", &Tsim);
// model functions
{%- if solver_options.integrator_type == "IRK" %}
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"impl_ode_fun", capsule->sim_impl_dae_fun);
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"impl_ode_fun_jac_x_xdot", capsule->sim_impl_dae_fun_jac_x_xdot_z);
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"impl_ode_jac_x_xdot_u", capsule->sim_impl_dae_jac_x_xdot_u_z);
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"impl_dae_hess", capsule->sim_impl_dae_hess);
{%- endif %}
{%- elif solver_options.integrator_type == "ERK" %}
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"expl_vde_for", capsule->sim_forw_vde_casadi);
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"expl_ode_fun", capsule->sim_expl_ode_fun_casadi);
{%- if hessian_approx == "EXACT" %}
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"expl_ode_hess", capsule->sim_expl_ode_hess);
{%- endif %}
{%- elif solver_options.integrator_type == "GNSF" %}
{% if model.gnsf.purely_linear != 1 %}
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"phi_fun", capsule->sim_gnsf_phi_fun);
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"phi_fun_jac_y", capsule->sim_gnsf_phi_fun_jac_y);
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"phi_jac_y_uhat", capsule->sim_gnsf_phi_jac_y_uhat);
{% if model.gnsf.nontrivial_f_LO == 1 %}
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"f_lo_jac_x1_x1dot_u_z", capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z);
{%- endif %}
{%- endif %}
{{ model.name }}_sim_config->model_set({{ model.name }}_sim_in->model,
"gnsf_get_matrices_fun", capsule->sim_gnsf_get_matrices_fun);
{%- endif %}
// sim solver
sim_solver *{{ model.name }}_sim_solver = sim_solver_create({{ model.name }}_sim_config,
{{ model.name }}_sim_dims, {{ model.name }}_sim_opts);
capsule->acados_sim_solver = {{ model.name }}_sim_solver;
{% if dims.np > 0 %}
/* initialize parameter values */
double* p = calloc(np, sizeof(double));
{% for item in parameter_values %}
{%- if item != 0 %}
p[{{ loop.index0 }}] = {{ item }};
{%- endif %}
{%- endfor %}
{{ model.name }}_acados_sim_update_params(capsule, p, np);
free(p);
{% endif %}{# if dims.np #}
/* initialize input */
// x
double x0[{{ dims.nx }}];
for (int ii = 0; ii < {{ dims.nx }}; ii++)
x0[ii] = 0.0;
sim_in_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims,
{{ model.name }}_sim_in, "x", x0);
// u
double u0[{{ dims.nu }}];
for (int ii = 0; ii < {{ dims.nu }}; ii++)
u0[ii] = 0.0;
sim_in_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims,
{{ model.name }}_sim_in, "u", u0);
// S_forw
double S_forw[{{ dims.nx * (dims.nx + dims.nu) }}];
for (int ii = 0; ii < {{ dims.nx * (dims.nx + dims.nu) }}; ii++)
S_forw[ii] = 0.0;
for (int ii = 0; ii < {{ dims.nx }}; ii++)
S_forw[ii + ii * {{ dims.nx }} ] = 1.0;
sim_in_set({{ model.name }}_sim_config, {{ model.name }}_sim_dims,
{{ model.name }}_sim_in, "S_forw", S_forw);
int status = sim_precompute({{ model.name }}_sim_solver, {{ model.name }}_sim_in, {{ model.name }}_sim_out);
return status;
}
int {{ model.name }}_acados_sim_solve(sim_solver_capsule *capsule)
{
// integrate dynamics using acados sim_solver
int status = sim_solve(capsule->acados_sim_solver,
capsule->acados_sim_in, capsule->acados_sim_out);
if (status != 0)
printf("error in {{ model.name }}_acados_sim_solve()! Exiting.\n");
return status;
}
int {{ model.name }}_acados_sim_free(sim_solver_capsule *capsule)
{
// free memory
sim_solver_destroy(capsule->acados_sim_solver);
sim_in_destroy(capsule->acados_sim_in);
sim_out_destroy(capsule->acados_sim_out);
sim_opts_destroy(capsule->acados_sim_opts);
sim_dims_destroy(capsule->acados_sim_dims);
sim_config_destroy(capsule->acados_sim_config);
// free external function
{%- if solver_options.integrator_type == "IRK" %}
external_function_param_casadi_free(capsule->sim_impl_dae_fun);
external_function_param_casadi_free(capsule->sim_impl_dae_fun_jac_x_xdot_z);
external_function_param_casadi_free(capsule->sim_impl_dae_jac_x_xdot_u_z);
{%- if hessian_approx == "EXACT" %}
external_function_param_casadi_free(capsule->sim_impl_dae_hess);
{%- endif %}
{%- elif solver_options.integrator_type == "ERK" %}
external_function_param_casadi_free(capsule->sim_forw_vde_casadi);
external_function_param_casadi_free(capsule->sim_expl_ode_fun_casadi);
{%- if hessian_approx == "EXACT" %}
external_function_param_casadi_free(capsule->sim_expl_ode_hess);
{%- endif %}
{%- elif solver_options.integrator_type == "GNSF" %}
{% if model.gnsf.purely_linear != 1 %}
external_function_param_casadi_free(capsule->sim_gnsf_phi_fun);
external_function_param_casadi_free(capsule->sim_gnsf_phi_fun_jac_y);
external_function_param_casadi_free(capsule->sim_gnsf_phi_jac_y_uhat);
{% if model.gnsf.nontrivial_f_LO == 1 %}
external_function_param_casadi_free(capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z);
{%- endif %}
{%- endif %}
external_function_param_casadi_free(capsule->sim_gnsf_get_matrices_fun);
{% endif %}
return 0;
}
int {{ model.name }}_acados_sim_update_params(sim_solver_capsule *capsule, double *p, int np)
{
int status = 0;
int casadi_np = {{ model.name | upper }}_NP;
if (casadi_np != np) {
printf("{{ model.name }}_acados_sim_update_params: trying to set %i parameters for external functions."
" External function has %i parameters. Exiting.\n", np, casadi_np);
exit(1);
}
{%- if solver_options.integrator_type == "ERK" %}
capsule->sim_forw_vde_casadi[0].set_param(capsule->sim_forw_vde_casadi, p);
capsule->sim_expl_ode_fun_casadi[0].set_param(capsule->sim_expl_ode_fun_casadi, p);
{%- if hessian_approx == "EXACT" %}
capsule->sim_expl_ode_hess[0].set_param(capsule->sim_expl_ode_hess, p);
{%- endif %}
{%- elif solver_options.integrator_type == "IRK" %}
capsule->sim_impl_dae_fun[0].set_param(capsule->sim_impl_dae_fun, p);
capsule->sim_impl_dae_fun_jac_x_xdot_z[0].set_param(capsule->sim_impl_dae_fun_jac_x_xdot_z, p);
capsule->sim_impl_dae_jac_x_xdot_u_z[0].set_param(capsule->sim_impl_dae_jac_x_xdot_u_z, p);
{%- if hessian_approx == "EXACT" %}
capsule->sim_impl_dae_hess[0].set_param(capsule->sim_impl_dae_hess, p);
{%- endif %}
{%- elif solver_options.integrator_type == "GNSF" %}
{% if model.gnsf.purely_linear != 1 %}
capsule->sim_gnsf_phi_fun[0].set_param(capsule->sim_gnsf_phi_fun, p);
capsule->sim_gnsf_phi_fun_jac_y[0].set_param(capsule->sim_gnsf_phi_fun_jac_y, p);
capsule->sim_gnsf_phi_jac_y_uhat[0].set_param(capsule->sim_gnsf_phi_jac_y_uhat, p);
{% if model.gnsf.nontrivial_f_LO == 1 %}
capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z[0].set_param(capsule->sim_gnsf_f_lo_jac_x1_x1dot_u_z, p);
{%- endif %}
{%- endif %}
capsule->sim_gnsf_get_matrices_fun[0].set_param(capsule->sim_gnsf_get_matrices_fun, p);
{% endif %}
return status;
}
/* getters pointers to C objects*/
sim_config * {{ model.name }}_acados_get_sim_config(sim_solver_capsule *capsule)
{
return capsule->acados_sim_config;
};
sim_in * {{ model.name }}_acados_get_sim_in(sim_solver_capsule *capsule)
{
return capsule->acados_sim_in;
};
sim_out * {{ model.name }}_acados_get_sim_out(sim_solver_capsule *capsule)
{
return capsule->acados_sim_out;
};
void * {{ model.name }}_acados_get_sim_dims(sim_solver_capsule *capsule)
{
return capsule->acados_sim_dims;
};
sim_opts * {{ model.name }}_acados_get_sim_opts(sim_solver_capsule *capsule)
{
return capsule->acados_sim_opts;
};
sim_solver * {{ model.name }}_acados_get_sim_solver(sim_solver_capsule *capsule)
{
return capsule->acados_sim_solver;
};

@ -0,0 +1,103 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
#ifndef ACADOS_SIM_{{ model.name }}_H_
#define ACADOS_SIM_{{ model.name }}_H_
#include "acados_c/sim_interface.h"
#include "acados_c/external_function_interface.h"
#define {{ model.name | upper }}_NX {{ dims.nx }}
#define {{ model.name | upper }}_NZ {{ dims.nz }}
#define {{ model.name | upper }}_NU {{ dims.nu }}
#define {{ model.name | upper }}_NP {{ dims.np }}
#ifdef __cplusplus
extern "C" {
#endif
// ** capsule for solver data **
typedef struct sim_solver_capsule
{
// acados objects
sim_in *acados_sim_in;
sim_out *acados_sim_out;
sim_solver *acados_sim_solver;
sim_opts *acados_sim_opts;
sim_config *acados_sim_config;
void *acados_sim_dims;
/* external functions */
// ERK
external_function_param_casadi * sim_forw_vde_casadi;
external_function_param_casadi * sim_expl_ode_fun_casadi;
external_function_param_casadi * sim_expl_ode_hess;
// IRK
external_function_param_casadi * sim_impl_dae_fun;
external_function_param_casadi * sim_impl_dae_fun_jac_x_xdot_z;
external_function_param_casadi * sim_impl_dae_jac_x_xdot_u_z;
external_function_param_casadi * sim_impl_dae_hess;
// GNSF
external_function_param_casadi * sim_gnsf_phi_fun;
external_function_param_casadi * sim_gnsf_phi_fun_jac_y;
external_function_param_casadi * sim_gnsf_phi_jac_y_uhat;
external_function_param_casadi * sim_gnsf_f_lo_jac_x1_x1dot_u_z;
external_function_param_casadi * sim_gnsf_get_matrices_fun;
} sim_solver_capsule;
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_sim_create(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_sim_solve(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_sim_free(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_sim_update_params(sim_solver_capsule *capsule, double *value, int np);
ACADOS_SYMBOL_EXPORT sim_config * {{ model.name }}_acados_get_sim_config(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT sim_in * {{ model.name }}_acados_get_sim_in(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT sim_out * {{ model.name }}_acados_get_sim_out(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT void * {{ model.name }}_acados_get_sim_dims(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT sim_opts * {{ model.name }}_acados_get_sim_opts(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT sim_solver * {{ model.name }}_acados_get_sim_solver(sim_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT sim_solver_capsule * {{ model.name }}_acados_sim_solver_create_capsule(void);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_sim_solver_free_capsule(sim_solver_capsule *capsule);
#ifdef __cplusplus
}
#endif
#endif // ACADOS_SIM_{{ model.name }}_H_

@ -0,0 +1,233 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
#define S_FUNCTION_NAME acados_sim_solver_sfunction_{{ model.name }}
#define S_FUNCTION_LEVEL 2
#define MDL_START
// acados
// #include "acados/utils/print.h"
#include "acados_c/ocp_nlp_interface.h"
#include "acados_c/external_function_interface.h"
// example specific
#include "{{ model.name }}_model/{{ model.name }}_model.h"
#include "acados_sim_solver_{{ model.name }}.h"
#include "simstruc.h"
#define SAMPLINGTIME {{ solver_options.Tsim }}
static void mdlInitializeSizes (SimStruct *S)
{
// specify the number of continuous and discrete states
ssSetNumContStates(S, 0);
ssSetNumDiscStates(S, 0);
{# compute number of input ports #}
{%- set n_inputs = 1 %} {# x0 #}
{%- if dims.nu > 0 %} {# u0 -#}
{%- set n_inputs = n_inputs + 1 -%}
{%- endif %}
{%- if dims.np > 0 %} {# parameters #}
{%- set n_inputs = n_inputs + 1 -%}
{%- endif %}
// specify the number of input ports
if ( !ssSetNumInputPorts(S, {{ n_inputs }}) )
return;
// specify the number of output ports
if ( !ssSetNumOutputPorts(S, 1) )
return;
// specify dimension information for the input ports
{%- set i_input = 0 %}
// x0
ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nx }});
{%- if dims.nu > 0 %}
{%- set i_input = i_input + 1 %}
// u0
ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.nu }});
{%- endif %}
{%- if dims.np > 0 %}
{%- set i_input = i_input + 1 %}
// parameters
ssSetInputPortVectorDimension(S, {{ i_input }}, {{ dims.np }});
{%- endif %}
// specify dimension information for the output ports
ssSetOutputPortVectorDimension(S, 0, {{ dims.nx }} ); // xnext
// specify the direct feedthrough status
// should be set to 1 for all inputs used in mdlOutputs
{%- for i in range(end=n_inputs) %}
ssSetInputPortDirectFeedThrough(S, {{ i }}, 1);
{%- endfor %}
// one sample time
ssSetNumSampleTimes(S, 1);
}
#if defined(MATLAB_MEX_FILE)
#define MDL_SET_INPUT_PORT_DIMENSION_INFO
#define MDL_SET_OUTPUT_PORT_DIMENSION_INFO
static void mdlSetInputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
{
if ( !ssSetInputPortDimensionInfo(S, port, dimsInfo) )
return;
}
static void mdlSetOutputPortDimensionInfo(SimStruct *S, int_T port, const DimsInfo_T *dimsInfo)
{
if ( !ssSetOutputPortDimensionInfo(S, port, dimsInfo) )
return;
}
#endif /* MATLAB_MEX_FILE */
static void mdlInitializeSampleTimes(SimStruct *S)
{
ssSetSampleTime(S, 0, SAMPLINGTIME);
ssSetOffsetTime(S, 0, 0.0);
}
static void mdlStart(SimStruct *S)
{
sim_solver_capsule *capsule = {{ model.name }}_acados_sim_solver_create_capsule();
{{ model.name }}_acados_sim_create(capsule);
ssSetUserData(S, (void*)capsule);
}
static void mdlOutputs(SimStruct *S, int_T tid)
{
sim_solver_capsule *capsule = ssGetUserData(S);
sim_config *acados_sim_config = {{ model.name }}_acados_get_sim_config(capsule);
sim_in *acados_sim_in = {{ model.name }}_acados_get_sim_in(capsule);
sim_out *acados_sim_out = {{ model.name }}_acados_get_sim_out(capsule);
void *acados_sim_dims = {{ model.name }}_acados_get_sim_dims(capsule);
// sim_opts * {{ model.name }}_acados_get_sim_opts(capsule);
// sim_solver * {{ model.name }}_acados_get_sim_solver(capsule);
InputRealPtrsType in_sign;
{% set input_sizes = [dims.nx, dims.nu, dims.np] %}
// local buffer
{%- set buffer_size = input_sizes | sort | last %}
real_t buffer[{{ buffer_size }}];
/* go through inputs */
{%- set i_input = 0 %}
// initial condition
in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }});
for (int i = 0; i < {{ dims.nx }}; i++)
buffer[i] = (double)(*in_sign[i]);
sim_in_set(acados_sim_config, acados_sim_dims,
acados_sim_in, "x", buffer);
// ssPrintf("\nin acados sim:\n");
// for (int i = 0; i < {{ dims.nx }}; i++) ssPrintf("x0[%d] = %f\n", i, buffer[i]);
// ssPrintf("\n");
{% if dims.nu > 0 %}
// control input - u
{%- set i_input = i_input + 1 %}
in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }});
for (int i = 0; i < {{ dims.nu }}; i++)
buffer[i] = (double)(*in_sign[i]);
sim_in_set(acados_sim_config, acados_sim_dims,
acados_sim_in, "u", buffer);
{%- endif %}
{% if dims.np > 0 %}
// parameters
{%- set i_input = i_input + 1 %}
in_sign = ssGetInputPortRealSignalPtrs(S, {{ i_input }});
for (int i = 0; i < {{ dims.np }}; i++)
buffer[i] = (double)(*in_sign[i]);
// update value of parameters
{{ model.name }}_acados_sim_update_params(capsule, buffer, {{ dims.np }});
{%- endif %}
/* call solver */
int acados_status = {{ model.name }}_acados_sim_solve(capsule);
/* set outputs */
real_t *out_x = ssGetOutputPortRealSignal(S, 0);
// get simulated state
sim_out_get(acados_sim_config, acados_sim_dims, acados_sim_out,
"xn", (void *) out_x);
// ssPrintf("\nacados sim solve: returned %d\n", acados_status);
// for (int i = 0; i < {{ dims.nx }}; i++) ssPrintf("x_sim[%d] = %f\n", i, out_x[i]);
// ssPrintf("\n");
}
static void mdlTerminate(SimStruct *S)
{
sim_solver_capsule *capsule = ssGetUserData(S);
{{ model.name }}_acados_sim_free(capsule);
{{ model.name }}_acados_sim_solver_free_capsule(capsule);
}
#ifdef MATLAB_MEX_FILE
#include "simulink.c"
#else
#include "cg_sfun.h"
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,217 @@
/*
* Copyright 2019 Gianluca Frison, Dimitris Kouzoupis, Robin Verschueren,
* Andrea Zanelli, Niels van Duijkeren, Jonathan Frey, Tommaso Sartor,
* Branimir Novoselnik, Rien Quirynen, Rezart Qelibari, Dang Doan,
* Jonas Koenemann, Yutao Chen, Tobias Schöls, Jonas Schlagenhauf, Moritz Diehl
*
* This file is part of acados.
*
* The 2-Clause BSD License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.;
*/
#ifndef ACADOS_SOLVER_{{ model.name }}_H_
#define ACADOS_SOLVER_{{ model.name }}_H_
#include "acados/utils/types.h"
#include "acados_c/ocp_nlp_interface.h"
#include "acados_c/external_function_interface.h"
#define {{ model.name | upper }}_NX {{ dims.nx }}
#define {{ model.name | upper }}_NZ {{ dims.nz }}
#define {{ model.name | upper }}_NU {{ dims.nu }}
#define {{ model.name | upper }}_NP {{ dims.np }}
#define {{ model.name | upper }}_NBX {{ dims.nbx }}
#define {{ model.name | upper }}_NBX0 {{ dims.nbx_0 }}
#define {{ model.name | upper }}_NBU {{ dims.nbu }}
#define {{ model.name | upper }}_NSBX {{ dims.nsbx }}
#define {{ model.name | upper }}_NSBU {{ dims.nsbu }}
#define {{ model.name | upper }}_NSH {{ dims.nsh }}
#define {{ model.name | upper }}_NSG {{ dims.nsg }}
#define {{ model.name | upper }}_NSPHI {{ dims.nsphi }}
#define {{ model.name | upper }}_NSHN {{ dims.nsh_e }}
#define {{ model.name | upper }}_NSGN {{ dims.nsg_e }}
#define {{ model.name | upper }}_NSPHIN {{ dims.nsphi_e }}
#define {{ model.name | upper }}_NSBXN {{ dims.nsbx_e }}
#define {{ model.name | upper }}_NS {{ dims.ns }}
#define {{ model.name | upper }}_NSN {{ dims.ns_e }}
#define {{ model.name | upper }}_NG {{ dims.ng }}
#define {{ model.name | upper }}_NBXN {{ dims.nbx_e }}
#define {{ model.name | upper }}_NGN {{ dims.ng_e }}
#define {{ model.name | upper }}_NY0 {{ dims.ny_0 }}
#define {{ model.name | upper }}_NY {{ dims.ny }}
#define {{ model.name | upper }}_NYN {{ dims.ny_e }}
#define {{ model.name | upper }}_N {{ dims.N }}
#define {{ model.name | upper }}_NH {{ dims.nh }}
#define {{ model.name | upper }}_NPHI {{ dims.nphi }}
#define {{ model.name | upper }}_NHN {{ dims.nh_e }}
#define {{ model.name | upper }}_NPHIN {{ dims.nphi_e }}
#define {{ model.name | upper }}_NR {{ dims.nr }}
#ifdef __cplusplus
extern "C" {
#endif
// ** capsule for solver data **
typedef struct {{ model.name }}_solver_capsule
{
// acados objects
ocp_nlp_in *nlp_in;
ocp_nlp_out *nlp_out;
ocp_nlp_out *sens_out;
ocp_nlp_solver *nlp_solver;
void *nlp_opts;
ocp_nlp_plan_t *nlp_solver_plan;
ocp_nlp_config *nlp_config;
ocp_nlp_dims *nlp_dims;
// number of expected runtime parameters
unsigned int nlp_np;
/* external functions */
// dynamics
{% if solver_options.integrator_type == "ERK" %}
external_function_param_casadi *forw_vde_casadi;
external_function_param_casadi *expl_ode_fun;
{% if solver_options.hessian_approx == "EXACT" %}
external_function_param_casadi *hess_vde_casadi;
{%- endif %}
{% elif solver_options.integrator_type == "IRK" %}
external_function_param_casadi *impl_dae_fun;
external_function_param_casadi *impl_dae_fun_jac_x_xdot_z;
external_function_param_casadi *impl_dae_jac_x_xdot_u_z;
{% if solver_options.hessian_approx == "EXACT" %}
external_function_param_casadi *impl_dae_hess;
{%- endif %}
{% elif solver_options.integrator_type == "LIFTED_IRK" %}
external_function_param_casadi *impl_dae_fun;
external_function_param_casadi *impl_dae_fun_jac_x_xdot_u;
{% elif solver_options.integrator_type == "GNSF" %}
external_function_param_casadi *gnsf_phi_fun;
external_function_param_casadi *gnsf_phi_fun_jac_y;
external_function_param_casadi *gnsf_phi_jac_y_uhat;
external_function_param_casadi *gnsf_f_lo_jac_x1_x1dot_u_z;
external_function_param_casadi *gnsf_get_matrices_fun;
{% elif solver_options.integrator_type == "DISCRETE" %}
external_function_param_{{ model.dyn_ext_fun_type }} *discr_dyn_phi_fun;
external_function_param_{{ model.dyn_ext_fun_type }} *discr_dyn_phi_fun_jac_ut_xt;
{%- if solver_options.hessian_approx == "EXACT" %}
external_function_param_{{ model.dyn_ext_fun_type }} *discr_dyn_phi_fun_jac_ut_xt_hess;
{%- endif %}
{%- endif %}
// cost
{% if cost.cost_type == "NONLINEAR_LS" %}
external_function_param_casadi *cost_y_fun;
external_function_param_casadi *cost_y_fun_jac_ut_xt;
external_function_param_casadi *cost_y_hess;
{%- elif cost.cost_type == "EXTERNAL" %}
external_function_param_{{ cost.cost_ext_fun_type }} *ext_cost_fun;
external_function_param_{{ cost.cost_ext_fun_type }} *ext_cost_fun_jac;
external_function_param_{{ cost.cost_ext_fun_type }} *ext_cost_fun_jac_hess;
{% endif %}
{% if cost.cost_type_0 == "NONLINEAR_LS" %}
external_function_param_casadi cost_y_0_fun;
external_function_param_casadi cost_y_0_fun_jac_ut_xt;
external_function_param_casadi cost_y_0_hess;
{% elif cost.cost_type_0 == "EXTERNAL" %}
external_function_param_{{ cost.cost_ext_fun_type_0 }} ext_cost_0_fun;
external_function_param_{{ cost.cost_ext_fun_type_0 }} ext_cost_0_fun_jac;
external_function_param_{{ cost.cost_ext_fun_type_0 }} ext_cost_0_fun_jac_hess;
{%- endif %}
{% if cost.cost_type_e == "NONLINEAR_LS" %}
external_function_param_casadi cost_y_e_fun;
external_function_param_casadi cost_y_e_fun_jac_ut_xt;
external_function_param_casadi cost_y_e_hess;
{% elif cost.cost_type_e == "EXTERNAL" %}
external_function_param_{{ cost.cost_ext_fun_type_e }} ext_cost_e_fun;
external_function_param_{{ cost.cost_ext_fun_type_e }} ext_cost_e_fun_jac;
external_function_param_{{ cost.cost_ext_fun_type_e }} ext_cost_e_fun_jac_hess;
{%- endif %}
// constraints
{%- if constraints.constr_type == "BGP" %}
external_function_param_casadi *phi_constraint;
{% elif constraints.constr_type == "BGH" and dims.nh > 0 %}
external_function_param_casadi *nl_constr_h_fun_jac;
external_function_param_casadi *nl_constr_h_fun;
external_function_param_casadi *nl_constr_h_fun_jac_hess;
{%- endif %}
{% if constraints.constr_type_e == "BGP" %}
external_function_param_casadi phi_e_constraint;
{% elif constraints.constr_type_e == "BGH" and dims.nh_e > 0 %}
external_function_param_casadi nl_constr_h_e_fun_jac;
external_function_param_casadi nl_constr_h_e_fun;
external_function_param_casadi nl_constr_h_e_fun_jac_hess;
{%- endif %}
} {{ model.name }}_solver_capsule;
ACADOS_SYMBOL_EXPORT {{ model.name }}_solver_capsule * {{ model.name }}_acados_create_capsule(void);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_free_capsule({{ model.name }}_solver_capsule *capsule);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_create({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_reset({{ model.name }}_solver_capsule* capsule);
/**
* Generic version of {{ model.name }}_acados_create which allows to use a different number of shooting intervals than
* the number used for code generation. If new_time_steps=NULL and n_time_steps matches the number used for code
* generation, the time-steps from code generation is used.
*/
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_create_with_discretization({{ model.name }}_solver_capsule * capsule, int n_time_steps, double* new_time_steps);
/**
* Update the time step vector. Number N must be identical to the currently set number of shooting nodes in the
* nlp_solver_plan. Returns 0 if no error occurred and a otherwise a value other than 0.
*/
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_update_time_steps({{ model.name }}_solver_capsule * capsule, int N, double* new_time_steps);
/**
* This function is used for updating an already initialized solver with a different number of qp_cond_N.
*/
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_update_qp_solver_cond_N({{ model.name }}_solver_capsule * capsule, int qp_solver_cond_N);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_update_params({{ model.name }}_solver_capsule * capsule, int stage, double *value, int np);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_solve({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT int {{ model.name }}_acados_free({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT void {{ model.name }}_acados_print_stats({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT ocp_nlp_in *{{ model.name }}_acados_get_nlp_in({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT ocp_nlp_out *{{ model.name }}_acados_get_nlp_out({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT ocp_nlp_out *{{ model.name }}_acados_get_sens_out({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT ocp_nlp_solver *{{ model.name }}_acados_get_nlp_solver({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT ocp_nlp_config *{{ model.name }}_acados_get_nlp_config({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT void *{{ model.name }}_acados_get_nlp_opts({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT ocp_nlp_dims *{{ model.name }}_acados_get_nlp_dims({{ model.name }}_solver_capsule * capsule);
ACADOS_SYMBOL_EXPORT ocp_nlp_plan_t *{{ model.name }}_acados_get_nlp_plan({{ model.name }}_solver_capsule * capsule);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif // ACADOS_SOLVER_{{ model.name }}_H_

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save