0

This is a bit of a convoluted problem that deals with a slightly open ended question. I realize that StackOverflow frowns on this practice, but as you will see, it is hard for me to break it down into smaller parts.

I have C++ code that is called using a CMEX S-Function (compiled using the legacy_code). I hand modified the wrapper file to make the S-Fn continuous in the minor time step. This is important because, when it was fixed in the minor step, I would see a staircase-like change in the function outputs instead of a smooth line. Since making it continuous, this problem has been solved.

Unfortunately, I later discovered that the Memory blocks between the input signals and the S-Function (that I was using to solve the algebraic loops) are fixed in the minor time step. I previously asked a question (here) about if there were any alternatives that were continuous, but it seems the question got buried.

So instead, I referred to this Mathworks documentation. They claim that the PWork vector can be used to keep values persistent in memory between successive invocations of the S-Function. I was able to use this vector to do this: 1. Store values of current time step for next step 2. In the next step, use the old values 3. After the calculations, update old values to current values 4. Repeat

In essence, I replicated the Memory block functionality internally. I thought I could now remove the Memory blocks and replace them with the Initial Condition block. Unfortunately, on doing this, the warning for algebraic loop appears. Now, my model sometimes solves and sometimes doesn't.

The two cases are shown below schematically:

enter image description here

S-Function and S-Function2 are the CMEX objects.

I think perhaps the CMEX function is dense to the algebraic loop diagnostics code, and Simulink is unable to realize that there actually isn't a real algebraic loop but only an artificial one?

My question is: Is there something that I can do to tell Simulink that there actually ISN'T an algebraic loop? Is there some kind of best practice for what to do in such cases?

*EDIT: Schematic was inaccurate and didn't properly represent my model. Updated it

Community
  • 1
  • 1
  • Check the documentation for direct feedthrough and `ssSetInputPortDirectFeedThrough`. I am not familiar with the topic, but turning it off deactivates the algebraic loop detection for this port. – Daniel Aug 19 '14 at 18:42
  • Hi Daniel. Thanks for responding. The documentation suggests that if we set the Direct Feedthrough to 0, but still use the signal in `mdlOutputs`, it can lead to unpredictable errors. I _did_ try this sometime back, and I got Segmentation Violation errors. –  Aug 19 '14 at 18:46
  • If your mdloutput uses input signals it simply does not solve the algebraic loop. An algebraic loop can only be solved by a block generating output before getting input. – Daniel Aug 19 '14 at 19:39
  • I agree. What you are saying is that if I turn off the Direct Feedthrough, Matlab will _believe_ that there is no Algebraic Loop, even though there might be one. However, this leads to _other_ (non algebraic loop) errors, that vary from case to case and are unpredictable, and in my case, doing so causes Segmentation Violation. –  Aug 19 '14 at 20:13
  • 1
    You shouldn't turn off direct feedthrough if your S-Function requires access to the input signals in mdlOutputs. Blocks that do not require direct feedthrough are expected to process inputs in mdlUpdate and update internal state as necessary. The mdlOutputs will then populate the output signals using this internal state. AFAIK, Simulink simply checks the direct feedthrough setting for S-Functions to detect algebraic loops. To solve the loop, insert memory blocks and unit delays as necessary (assuming the S-Function requires direct feedthrough). – Praetorian Aug 20 '14 at 00:27
  • 1
    There has to be more going on here than shown in your diagrams. Due to the integrator in the loop, neither of the above models have algebraic loops. Plus, the memory blocks are effectively doing nothing as the upper and lower signals initialize to the state of the integrator, and with the ones on the input ports you're just changing the value of the input signal at t=0. Neither of those things will cause, or solve, an algebraic loop. Also, saying "my model sometimes solves and sometimes doesn't" is a sure sign that something other than an algebraic loop is an issue with your model. – Phil Goddard Aug 20 '14 at 02:45
  • Ah dang it! You're absolutely right @PhilGoddard. I've updated the schematic to reflect the _real_ case. So, there _are_ some loops that go through the integrator block, and they DO get initialized to my `Integrator` block initial conditions (which are externally set using the `Constant` block. But there are some signals which are returned before the integrator block, as shown now. Also, the model worked pretty ok previously, but doesn't with these changes, so I'm inclined to believe that the problem is in how I handle the loop. Thanks for your help, you are doing god's work! –  Aug 20 '14 at 16:22
  • @Praetorian Thanks for your reply. I _did_ previously have the Memory blocks. Unfortunately, they are not updated in the minor step, as I explained in the question. Also, the documentation suggests that even the mdlUpdate function is called only in the major steps. I was thinking of using the mdlUpdate macro to update the old values to current-time-step values, but it seems that won't solve it either, since that is also only a major-step call. I've run out of ideas! –  Aug 20 '14 at 16:24

0 Answers0