21. Frequently asked questions

21.1. Features of FORCESPRO

  • I have been using FORCES in the past. Why should I use FORCESPRO?

The development of the free version of FORCES by ETH (forces.ethz.ch) has been discontinued, and the code generation service is no longer available.

The professional version of FORCESPRO comes with professional support, additional interfaces, and a large performance increase.

  • Can FORCESPRO target dSpace hardware?

Yes, FORCESPRO can be seamlessly integrated in the dSpace design flow with the new Simulink interface. For more details see dSPACE deployment through Simulink Coder and dSPACE deployment through ConfigurationDesk.

  • Can I use FORCESPRO for non-multistage programs?

Yes, FORCESPRO supports the case \(N=1\), i.e. a general QCQP of the form

\begin{align*} \text{minimize} \quad & \frac{1}{2}z^{\top}Hz + f^{\top}z\\ \text{subject to} \quad & Dz = c \\ & \underline{z} \leq z \leq \bar{z} \\ & Az \leq b \\ & z^{\top}Qz + q^{\top}z \leq r \end{align*}

In order to use this feature, simply call stages=MultistageProblem(1) and fill in the matrices as described in Low-level interface.

  • I need to re-linearize the model of my plant each sampling time. Does FORCESPRO support this?

When re-linearizing non-linear dynamics, you obtain in each sampling time a different matrix \(A\), \(B\) and also a new affine part \(g\):

\[x_{k+1} = Ax_k + Bu_k + g\]

FORCESPRO supports changing these variables at run-time by defining them as parameters.

21.2. Issues during code generation

  • I get the following error message when generating code: `Error downloading URL. Your network connection may be down or your proxy settings improperly configured.`

Your current MATLAB configuration is not accepting our website’s SSL certificate. Please follow this link to add our certificate to Matlab’s list of certificates manually. You can download the embotech certificate using your browser.

  • I get the following error message when generating code: `Invalid MEX-file. The specified module could not be found.`

Please install the Visual Studio redistributable libraries from here.

  • I get the following error when generating code: `java.io.IOException: Server is not responding, it might not support the current protocol. Missing ServerHello.`

Some MATLAB versions and some Java installations give problems when communicating using HTTPS from MATLAB. Please edit the file callSoapService.m. Search for the line

url = URL(endpoint);

and replace it with

url = URL([], endpoint, sun.net.www.protocol.https.Handler)
  • I get the following error when generating code: `java.io.IOException: The issuer can not be found in the trusted CA list.`

Some MATLAB versions and some Java installations give problems when communicating using HTTPS from MATLAB. Please edit the file callSoapService.m. Search for the line

url = URL(endpoint);

and replace it with

url = URL([], endpoint, sun.net.www.protocol.https.Handler)
  • I get the following error when generating code: `javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?`

If you are using the enterprise version of FORCESPRO (separate server in your company network), had previously altered the file callSoapService.m to accept secure HTTP connections and the enterprise server is listening on an HTTP port, you receive this error. To fix: Please edit the file callSoapService.m. Search for the line

url = URL([], endpoint, sun.net.www.protocol.https.Handler)

and replace it by the default

url = URL(endpoint);
  • I get the following error when generating code:

Server was unable to process request. ---> There is no parameter that maps to c of stage 1

However, according to the multistage formulation, my \(D_1\) is empty in my problem, so \(c_1\) should also be empty.**

We recommend to reformulate the optimization variables for each stage so that \(D_1\) is not empty for performance reasons.

If this is not possible and \(D_1\) must remain empty, then the inter-stage equality constraint equations become

\[C_{i-1}z_{i-1} + D_{i}z_{i} = c_{i-1}\]

instead of

\[C_{i-1}z_{i-1} + D_{i}z_{i} = c_{i}\]
  • I get the following error message when using the MATLAB interface: `’Unable to cast object of type ‘csmatio.types.MLDouble’ to type ‘csmatio.types.MLStructure’.’`

Please check that you have your MEX compiler correctly set up. If the problem persists please send your MATLAB and platform settings to support@embotech.com.

  • The code generation process gets stuck displaying `Generating and compiling code…` and sometimes it returns an error after 10 minutes.

By default, the code is compiled will all optimizations turned on (-O3). When the size of your code is large, typically when you have a long prediction horizon, it can take a very long time to compile the code with all optimizations turned on. If this process takes too long the server times out and returns a compilation error. You can reduce the compilation time by changing the compiler optimization flags to -O0, -O1, or -O2. You can change this setting using the following flag set to the appropriate value.

codeoptions.optlevel = 2;

21.3. Issues when running the solver

  • When I run the solver in MATLAB I get the following error: `??? Error using ==> TestSolver freopen of stdout did not work.`

This is a printing error that occurs in some old versions of MATLAB because stdout is not defined inside MEX files. Supported versions of MATLAB should not produce this error. You can avoid this error by setting

codeoptions.printlevel = 0;
  • My solver is producing a segmentation fault.

When the solver has a large amount of parameters or the problem is relatively large, compiling with codeoptions.optlevel = 0; can produce a segmentation fault. Please try to increase the value of codeoptions.optlevel or submit a bug report to support@embotech.com.

  • ADMM does not converge for my problem.

Unlike interior-point methods, the convergence of ADMM depends on the problem scaling. If the matrices for the problem data have very high condition numbers and norms, ADMM can converge extremely slowly regardless of the algorithm parameters. In some cases, ADMM might not converge at all due to severe accumulation of numerical errors.

However, often the problem is choosing the right ADMM parameters \(\rho\) and \(\alpha\) to obtain fast convergence of the algorithm.

  • The solver outputs exitcode -7.

Exitcode -7 means that the solver could not proceed. A common cause is the problem being infeasible. FORCESPRO does not have infeasibility detection to speed up the solution time. However, one can use the function stages2qcqp to convert the FORCESPRO problem into a standard (QC)QP that can be given to other QP solvers like quadprog to check for infeasibility. See also Debugging a formulation.

  • I am generating code from 32-bit MATLAB. When I run the code it produces a segfault. What is the problem?

By default, the code is compiled will all optimizations turned on (-O3). We have observed that sometimes there are problems when linking on 32-bit versions of MATLAB. This problem does not occur when the compiler optimization flags are set to -O0, -O1, or -O2. You can change this setting using the following flag set to the appropriate value.

codeoptions.optlevel = 2;
  • I am getting exitflag -6, -8 or -10 when I run my solver

In this case it is a good idea to check that the nonlinear functions provided to the solver are well-defined and that they don’t produce NaNs or Infs. See section Calling the nonlinear functions from Matlab or Python for how to call the nonlinear functions along with their derivatives directly in MATLAB or Python. If the solver returns exitflag \(-6\), \(-8\) or \(-10\) in the first iteration one needs to check that

problem.x0

does not yield NaN or Inf when the nonlinear functions are evaluated on it. E.g. if one has generated a solver named FORCESsolver which does not use any real-time parameters, one needs to check that the following code does not produce an error

jj = 1;
for ss = 1:model.N
  z = problem.x0[jj:(jj+model.nvar)];
  c, jacc = FORCESsolver_dynamics(z, [], ss);
  ineq, jacineq = FORCESsolver_inequalities(z, [], ss);
  obj, gradobj = FORCESsolver_objective(z, [], ss);
  assert( any(isnan(c) | isinf(c), 'all'), ['Encountered NaNs or Infs in c at stage ', num2str(ss) ]);
  assert( any(isnan(jacc) | isinf(jacc), 'all'), ['Encountered NaNs or Infs in jacc at stage ', num2str(ss) ]);
  assert( any(isnan(ineq) | isinf(ineq), 'all'), ['Encountered NaNs or Infs in ineq at stage ', num2str(ss) ]);
  assert( any(isnan(jacineq) | isinf(jacineq), 'all'), ['Encountered NaNs or Infs in jacineq at stage ', num2str(ss) ]);
  assert( any(isnan(obj) | isinf(obj), 'all'), ['Encountered NaNs or Infs in obj at stage ', num2str(ss) ]);
  assert( any(isnan(gradobj) | isinf(gradobj), 'all'), ['Encountered NaNs or Infs in gradobj at stage ', num2str(ss) ]);
  jj = jj + model.nvar;
end
disp('Did not encounter any NaNs or Infs');

Note

See also Real-time SQP Solver: Robotic Arm Manipulator (MATLAB & Python) for an example of how to simulate the dynamics of the system directly in MATLAB and Python.

21.5. Code deployment

  • I get the following error message when deploying a solver on dSpace hardware: `OPUS MAKE: Don’t know how to make …`

    This is well-known deployment issue with compiled files. During building for target the compiler is looking for the source code of the solver. The resulting object file is added in the folder <solvername>_<target_ext> which is automatically generated by the compiler. Therefore, to use the object file you need to move it to that folder in order for the compiler to detect it and skip compilation. A possible workaround is to use the static library of the solver as specified in dSPACE deployment through Simulink Coder.

21.6. Other topics

  • How can I obtain information about the KKT conditions at the solution?

    The printlevel solver option allows the user to control how much information is printed by the solver. See here for more information on how to define solver options.

    When printlevel is set to 2 the solver outputs information related to the KKT conditions at every iteration. In particular:

    • res_eq is the maximum \(||C_{i-1}z_{i-1} + D_{i}z_{i}-c_i||_{\infty}\) for all \(i\),

    • If we rewrite all inequality constraints as \(Gz\leq g\) and \(s\) are slack variables for the same constraints, res_ineq is equal to \(||Gz - g + s||_{\infty}\),

    • If \(\lambda\) are the Lagrange multipliers for the inequality constraints, \(\mu\) is equal to \(\lambda^{\top}s\) divided by the number of constraints, i.e. the average complementary slackness.

  • What system information am I sharing by using FORCESPRO?

    When contacting the solver generation server, the FORCESPRO client sends the following system information:

    • Machine username

    • MAC address

    • Fingerprints

    The fingerprint is platform dependent. We create two fingerprints using different system information to create hashes and validate with either of them in order to have a more stable validation:

    • For Windows, each fingerprint uses a subset of the below information:

      • Mac addresses

      • CPU ID (register with machine support)

      • Volume Serial Number

      • Volume GUID

    • For MacOS, each fingerprint uses a subset of the below information:

      • Cputype and Cpusubtype

      • Network node hostname

      • Mac addresses

    • For Linux, each fingerprint uses a subset of the below information:

      • Network node hostname

      • /etc/machine-id

      • Mac addresses

      • Linux user uid

    The above information is hashed to create the fingerprint which means that it cannot be recovered by using the fingerprint.

  • Why am I being asked to update the FORCESPRO client software every now and then?

    We have a development policy of continuous deployment, which unfortunately means that we have to ask users to update their clients every time there is a substantial change in the code. To make this process easier and faster, FORCESPRO comes with a functionality that allows users to update their clients by simply typing the following in the MATLAB command prompt:

    >> updateClient