Linear Second Order Actuator — Robotics/Actuators And Drivetrain
Robotics/Actuators_And_Drivetrain/Linear_Second_Order_Actuator · 1 input / 1 output port(s) at insert · exports to Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text
Description#
The block's own DESCRIPTION_HTML, rendered verbatim — the same text the config dialog's info panel and the library navigator show. Fix a wrong sentence in the block's .cpp (R-D9), never here.
Linear Second-Order Actuator
Robotics / Actuators and Drivetrain
The classic fin or servo actuator model: the actual position x follows the demanded position u as a second-order linear system with natural frequency ωn and damping ratio ζ,
- x'' = ωn²·(u − x) − 2ζωn·x', i.e. the transfer function ωn² / (s² + 2ζωns + ωn²) with a configurable initial position and velocity.
With the state [x; x'] that is the state space A = [0, 1; −ωn², −2ζωn], B = [0; ωn²], C = [1 0], D = 0, which the block carries as a real state space: model reduction can absorb it into a neighbouring plant and code export discretizes it by whichever method the model selects. The unit gain at DC means a held demand is reached exactly.
Ports
- Input – u, the demanded position (a fin deflection, say), a scalar [1,1], in whatever unit the initial position is given in.
- Output – x, the actual position, a scalar [1,1] in the same unit.
Parameters
- Natural Frequency (rad/s) – ωn, a scalar > 0. Defaults to 1, as Simulink's does.
- Damping Ratio – ζ, a scalar ≥ 0. Defaults to 0.3, which overshoots a step by about 37 %.
- Initial Position – x at t = 0, a scalar. Defaults to 0.
- Initial Velocity – x' at t = 0, a scalar. Defaults to 0.
- Sampling Time (s) – zero or less inherits the solver's rate; a positive value runs the block at that period.
Code export
All ten targets: Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog and PLC Structured Text. The block exports the discretized state space x[k+1] = Ad·x + Bd·u, y = Cd·x + Dd·u, with every coefficient folded to a constant at export time and the discretization following the model's method. Under ZOH that is exact for an input held across each sample. There is no tunable parameter object.
The three HDL targets are genuine synthesizable Q16.16: multiply-accumulate on those constants, with no division and nothing transcendental. A very fast actuator sampled slowly pushes the entries of Bd up towards ωn²·dt, so check them if ωn is in the hundreds.
Simulink bridge
Import and export, mapped to Aerospace Blockset's
aerolibactuator/Linear Second-Order Actuator: Natural Frequency
(rad/s) → wn_fin, Damping Ratio →
z_fin, Initial Position → fin_act_0 and
Initial Velocity → fin_act_vel – the block's whole
dialog. "Sampling Time (s)" does not cross: the Simulink block is
continuous and defines no SampleTime parameter at all, measured on
R2026a, and set_param on a parameter a block does not define is a
hard error.
Notes
- Stateful and linear: two continuous states, position and velocity. The output does not depend on the input at the same instant, so a feedback loop through the block is not an algebraic loop.
- No limits. Position, rate and demand are all unbounded here; the Nonlinear Second-Order Actuator is the same dynamics with the three saturations that make a real actuator.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Actuators_And_Drivetrain/Linear_Second_Order_Actuator |
| family | Robotics/Actuators_And_Drivetrain |
| solver environment class | ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_Linear_Second_Order_Actuator |
| source | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Actuators_And_Drivetrain/Linear_Second_Order_Actuator/ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_Linear_Second_Order_Actuator.cpp |
| header | src/ICoreBlocks/ICoreBlockLibrary/Blocks/Robotics/Actuators_And_Drivetrain/Linear_Second_Order_Actuator/ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_Linear_Second_Order_Actuator.h |
| default size on canvas | 120 × 80 px |
| ports at insert | 1 in, 1 out |
| code generators implemented | Python, MATLAB, Java, Rust, C, C++, VHDL, Verilog, SystemVerilog, PLC Structured Text |
Ports#
| # | Direction | Signal type | Description label |
|---|---|---|---|
| 1 | in | ICoreDouble | — |
| 2 | out | ICoreDouble | — |
Ports the constructor creates. A block whose port list changes with its configuration adds or removes ports at load time; the count above is the one a freshly inserted block has.
Configuration variables#
| Config variable | Default | Simulink parameter |
|---|---|---|
Natural Frequency (rad/s) | 1 | wn_fin |
Damping Ratio | 0.3 | z_fin |
Initial Position | 0 | fin_act_0 |
Initial Velocity | 0 | fin_act_vel |
Every block also carries Sampling Time (s) from ICoreBlockSolverEnvironment: zero or less inherits the solver's rate, a positive value runs the block at that period.
Simulink bridge#
| support | Support::Both |
| Simulink path | aerolibactuator/Linear Second-Order Actuator |
| port-count rule | PortsParam::None |
SampleTime parameter | no — the counterpart defines none; the rate stays on the ICore side |
| ICore config | Simulink parameter | Value translation |
|---|---|---|
Natural Frequency (rad/s) | wn_fin | passes through |
Damping Ratio | z_fin | passes through |
Initial Position | fin_act_0 | passes through |
Initial Velocity | fin_act_vel | passes through |
Caveat (shown to the user): aerolibactuator/Linear Second-Order Actuator is continuous and has NO SampleTime parameter (verified against the R2026a block dialog), so "Sampling Time (s)" does not cross
Catalog contract: src/ICoreBlocks/ICoreCoder/ICoreCommandSystem/SimulinkBridge/ICoreSimulinkBlockCatalog.h
Description vs code#
The lists agree. check_block_descriptions.py finds no disagreement between the description's Ports, Parameters, Code export and Simulink bridge lists and the code's.
The verdict above is
tools/docs/check_block_descriptions.py(P7.1), which compares LISTS. It cannot read a sentence: "stateless" on a block with a state, an initial-value semantic the recursion does not implement, a "not synthesizable" caveat the HDL banner contradicts. That is the agent audit (P7.3) on BLOCK_DESCRIPTION_AUDIT.md, and this tool's green is not a substitute for one.
File banner (developer view)#
The top comment of the block's .cpp — the maths, the realization and the export strategy, addressed to whoever changes it. It must not contradict the description above (P7.5).
Linear Second-Order Actuator — the Aerospace Blockset's fin/servo actuator, unlimited x'' = wn^2 (u - x) - 2 zeta wn x'
x = [position; velocity], u = demanded position, y = position:
A = [ 0 1 ] B = [ 0 ] C = [ 1 0 ] D = 0 [ -wn^2 -2 zeta wn ] [ wn^2 ]
⚠ MEASURED AGAINST R2026a BEFORE ANY OF IT WAS WRITTEN. The masked subsystem behind aerolibactuator/Linear Second-Order Actuator is one Second-Order Integrator with its limits OFF, fed by Sum3 = wn^2*(u - x) - 2*zeta*wn*x'; its two initial conditions are the dialog's fin_act_0 and fin_act_vel. The dialog has exactly four parameters and NO SampleTime.
Written to §4's state-space-first rule, the same way DC_Motor is: seeded in the constructor from the defaults, re-derived in loadBlockConfig(), both compute pairs taken FROM the state space, and the export reads the DISCRETIZED set -- so under ZOH it is exact for a held input, and under Tustin or FOH the emitted Cd/Dd follow the method rather than being assumed.
HDL is genuine Q16.16: the body is multiply-accumulate on export-time constants. At the rig's wn = 7.3 and dt = 0.01 every entry of Ad and Bd is below 1.
Sample results#
The same rig also ran:
| Stimulus | What it is | Output range |
|---|---|---|
impulse | Impulse: one sample of 1 at k = 5, 0 elsewhere (Repeating Sequence Stair) | -0.02498 … 0.06711 |
ramp | Ramp: slope 1 from t = 0 | 0 … 5.47 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -0.4345 … 0.6025 |
table | Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample | -0.1305 … 0.5733 |
Plotted: step — Step: 0 -> 1 at t = 1 s
Category dynamic · sample time 0.1 · 60 steps · commit fc85ac64df179e0aadfcbe797a2731524d14cbb9 · produced by docsSample --out <folder> --blocks Linear_Second_Order_Actuator Nonlinear_Second_Order_Actuator Wind_Shear_Model Discrete_Wind_Gust_Model Julian_Date_Conversion --steps 60 · data docs/generated/samples/Robotics__Actuators_And_Drivetrain__Linear_Second_Order_Actuator.json · the SVG is generated from those numbers by tools/docs/plot_svg.py, so it is a run and not a drawing (R-D10).