DC Motor — Robotics/Actuators And Drivetrain
Robotics/Actuators_And_Drivetrain/DC_Motor · 2 input / 2 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.
DC Motor
Robotics / Actuators and Drivetrain
The brushed DC motor as a two-state linear plant, from its nameplate constants:
- L·di/dt = V − R·i − Ke·ω – the electrical loop.
- J·dω/dt = Kt·i − b·ω − τload – the mechanical one.
With the state x = [i; ω] and the input u = [V; τload] that is the state space A = [−R/L, −Ke/L; Kt/J, −b/J], B = [1/L, 0; 0, −1/J], C = [0 1; 1 0], D = 0 – which the block carries as a real state space rather than as a hand-written recursion, so model reduction can absorb it into a neighbouring plant and code export discretizes it by whichever method the model selects.
Ports
- V – terminal voltage in volts, a scalar [1,1]: the command, usually a controller output or a PWM duty times the bus voltage.
- tau_load – load torque in N·m, a scalar [1,1], opposing motion: a positive value slows the motor. Tie it to a Constant of 0 for the unloaded case.
- w – shaft speed in rad/s, a scalar [1,1].
- i – armature current in amperes, a scalar [1,1]: what a current loop closes on, and what says whether the motor is near its thermal limit.
Parameters
- Resistance (ohm) – armature resistance R, > 0.
- Inductance (H) – armature inductance L, > 0. It sets the fast electrical pole at −R/L; a very small L makes the plant stiff, which matters for the sampling rate and for fixed-point export (see Code export).
- Torque Constant (N.m/A) – Kt, the torque produced per ampere.
- Back-EMF Constant (V.s/rad) – Ke, the voltage generated per rad/s. In SI units an ideal motor has Ke = Kt; they are separate parameters here so a datasheet's own two numbers can be entered as given.
- Rotor Inertia (kg.m^2) – J, > 0, including whatever is bolted to the shaft.
- Viscous Damping (N.m.s) – b, ≥ 0: the speed-proportional loss. Coulomb friction is not part of a linear plant – put a Stribeck Friction or a Coulomb and Viscous Friction block in the load path for that.
- Initial Current (A) and Initial Speed (rad/s) – the state at t = 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 – so no generated core contains R, L, J or a matrix inverse, and the discretization follows the model's method (ZOH, FOH, Tustin, Matched, Impulse or either Euler) rather than a rule frozen into the generators. There is no tunable parameter object.
The three HDL targets are genuine synthesizable Q16.16: the emitted body is multiply-accumulate on those constants, with no division and nothing transcendental. Check the discretized coefficients if the motor is an aggressive one – a very small inductance drives 1/L, and with it the entries of Bd, up by orders of magnitude, and Q16.16 saturates beyond ±32768.
Simulink bridge
None. Simulink's motor blocks live in Simscape Electrical, which is
not installed on this machine, so there is no block whose parameters this one
could be mapped onto or verified against. A model that must cross can carry the
same plant as a State-Space block with the A/B/C/D above. The entry
reports the block with that reason rather than dropping it silently, and no
parity testbench is owed – the documented consequence of
Support::None. Code export verification still covers all ten
languages.
Notes
- It carries a real continuous state space, seeded in the constructor and re-derived whenever the configuration changes – so it is a first-class citizen of model reduction and of every discretization method, which a block that only wrote its own recursion would not be.
- States are (current, speed); ports are (speed, current). The output matrix is the permutation that reconciles the two, so the equations keep their natural order and the ports keep theirs.
- Linear only. No saturation of the voltage, no Coulomb friction, no cogging, and no thermal model: those are separate blocks in the path, which is what keeps this one mergeable.
- τload opposes motion – a positive load torque decelerates the motor. That is the sign convention in B, and it is the one worth checking first when a model runs backwards.
- The electrical pole is the fast one. At the shipped defaults it sits at −R/L = −2 rad/s against the mechanical −b/J = −10; with a real motor's millihenry inductance it is thousands, and the model's sampling rate has to respect it.
Code facts#
| Fact | Value |
|---|---|
| registered type | Robotics/Actuators_And_Drivetrain/DC_Motor |
| family | Robotics/Actuators_And_Drivetrain |
| solver environment class | ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_DC_Motor |
| source | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Actuators_And_Drivetrain/DC_Motor/ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_DC_Motor.cpp |
| header | src/ICoreSDK/ICoreBlockLibrary/Blocks/Robotics/Actuators_And_Drivetrain/DC_Motor/ICoreBlock_0_Robotics_1_Actuators_And_Drivetrain_2_DC_Motor.h |
| default size on canvas | 132 × 92 px |
| ports at insert | 2 in, 2 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 | V |
| 2 | in | ICoreDouble | tau_load |
| 3 | out | ICoreDouble | w |
| 4 | out | ICoreDouble | i |
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 |
|---|---|---|
Resistance (ohm) | 1 | — |
Inductance (H) | 0.5 | — |
Torque Constant (N.m/A) | 0.01 | — |
Back-EMF Constant (V.s/rad) | 0.01 | — |
Rotor Inertia (kg.m^2) | 0.01 | — |
Viscous Damping (N.m.s) | 0.1 | — |
Initial Current (A) | 0 | — |
Initial Speed (rad/s) | 0 | — |
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::None |
| Simulink path | — |
| port-count rule | PortsParam::None |
SampleTime parameter | yes |
Caveat (shown to the user): no Simulink equivalent available: motor models belong to Simscape Electrical, which is not installed on this machine, so there is nothing to map the nameplate constants onto and no reference to run a parity testbench against. A model that must cross can carry the same plant as a State-Space block with A = [-R/L, -Ke/L; Kt/J, -b/J], B = [1/L, 0; 0, -1/J], C = [0 1; 1 0], D = 0, states (current, speed)
Catalog contract: src/ICoreSDK/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).
DC Motor — the 2-state LTI plant every servo loop is tuned against L di/dt = V - R i - Ke w J dw/dt = Kt i - b w - tau_load
x = [i; w], u = [V; tau_load], y = [w; i]:
A = [ -R/L -Ke/L ] B = [ 1/L 0 ] C = [ 0 1 ] D = 0 [ Kt/J -b/J ] [ 0 -1/J ] [ 1 0 ]
⚠ WRITTEN TO §4's STATE-SPACE-FIRST RULE, which is the whole point of this row: the continuous set is seeded in the CONSTRUCTOR from the block's own defaults, re-derived in loadBlockConfig(), and both compute pairs are taken FROM it rather than written beside it. Two things follow, neither of them opt-in -- model reduction can absorb the motor into a neighbouring plant, and export discretizes by whatever method the MODEL selects instead of a forward Euler frozen into ten generators. Reference: Transfer Function, then State Space.
⚠ C IS A PERMUTATION, NOT THE IDENTITY. States are (current, speed) because that is the order the two equations above are written in; ports are (speed, current) because speed is what a loop closes on. C reconciles them so neither convention has to bend.
⚠ THE GENERATORS EMIT Cd AND Dd RATHER THAN ASSUMING THEM. Hardcoding y0 = x1, y1 = x0 and dropping D is exact under ZOH and WRONG under Tustin and FOH, which give this plant a nonzero Dd -- a core that would be right on one discretization method and silently wrong on two.
⚠ HDL is genuine synthesizable Q16.16, and that was MEASURED off the discretized set rather than inferred from linearity: at both the shipped defaults and the rig's parameters every entry of Ad and Bd lands well inside the format at dt = 0.01, so the body is multiply- accumulate on export-time constants. A very small inductance is what would break it.
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) | -3.895 … 0.003236 |
ramp | Ramp: slope 1 from t = 0 | -56.43 … 0 |
sine | Sine Wave: amplitude 1, 2 rad/s, no phase, no bias | -9.704 … 9.714 |
table | Repeating Sequence Stair: [-2 -1 -0.5 0 0.5 1 2 3], one entry per sample | -20.69 … 13.4 |
Plotted: step — Step: 0 -> 1 at t = 1 s
Category dynamic · sample time 0.1 · 60 steps · commit ccf005c8 · produced by docsSample --out <folder> --steps 60 · data docs/generated/samples/Robotics__Actuators_And_Drivetrain__DC_Motor.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).