Gearbox
Gearbox applies a transmission ratio in both directions, and applies it the right way round for each kind of signal: speeds and positions scale by the ratio, torques and forces scale by its reciprocal.6 minute read
Gearbox applies a transmission ratio in both directions, and applies it
the right way round for each kind of signal: speeds and positions scale by
the ratio, torques and forces scale by its reciprocal. That is what a real
gearbox does, and getting it wrong by hand is the usual way a drivetrain
conversion goes astray.
flowchart LR
i1(["inputLoadSide"]) --> B["Gearbox"]
i2(["inputMotorSide"]) --> B
p1(["nLoadSide"]) --> B
p2(["nMotorSide"]) --> B
B --> o1(["outputMotorSide"])
B --> o2(["outputLoadSide"])
B --> o3(["gain"])
Which channels are which is fixed when the controller is built, by position: the first group is kinematic (position, velocity), the rest are mechanic (torque, force). The split is not visible in the tree — you cannot read it back, so check with whoever configured the machine.
By default every channel is kinematic. The mechanic count defaults to zero, so unless it was set at build time nothing gets the reciprocal.
A tooth count of 0 is refused, safely. Write one and the block keeps the previous value rather than dividing by zero. It does not tell you it did.
Your instance may present its channels by name instead of as arrays, at
LoadToMotor/<name>/inputandMotorToLoad/<name>/output. Both forms behave identically; only the paths differ.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
inputLoadSide |
load-side unit | unbounded | Values on the load side, converted to the motor side. One per channel. |
inputMotorSide |
motor-side unit | unbounded | Values on the motor side, converted to the load side. |
On a named instance these appear as LoadToMotor/<name>/input and
MotorToLoad/<name>/input.
Outputs
| Path | Unit | Description |
|---|---|---|
outputMotorSide |
motor-side unit | inputLoadSide converted. Kinematic channels are multiplied by gain, mechanic channels divided by it. |
outputLoadSide |
load-side unit | inputMotorSide converted, the other way round. |
gain |
- | nLoadSide ÷ nMotorSide, recomputed every cycle. Read this to confirm the ratio you configured. |
Parameters
| Path | Unit | Default | Range | Effect |
|---|---|---|---|---|
nLoadSide |
teeth | 1 | non-zero | The tooth count on the load side. Need not be a whole number — write the ratio directly if you prefer, with nMotorSide at 1. A 0 is refused and the previous value kept. |
nMotorSide |
teeth | 1 | non-zero | The tooth count on the motor side. Same treatment. |
Both are persistent and survive a controller restart. No parameters exist below this block.
A reduction of 10 to 1 — the motor turning ten times per output turn — is
nLoadSide = 1, nMotorSide = 10, giving a gain of 0.1. A load-side speed of
1 then becomes a motor-side speed of 0.1… which is backwards for a reduction,
so check gain against a known speed before trusting the sense.
Setup
- Establish which of your channels are kinematic and which are mechanic. This was fixed when the controller was built and cannot be read back.
- Set
nLoadSideandnMotorSidefrom the drivetrain. - Read
gainback and confirm it is the ratio you expect. - Put a known value on
inputLoadSidefor a kinematic channel and confirmoutputMotorSideis that value timesgain. - Do the same for a mechanic channel and confirm it is divided instead. If it is multiplied, that channel is on the wrong side of the split and the controller needs rebuilding.
- Send a value through both directions and confirm it returns unchanged.
Tuning
- There is nothing dynamic to tune. Both parameters take effect on the next cycle.
- Get the two tooth counts from the drivetrain drawing, not from a measured ratio — the exact integers avoid rounding in long-running position integrations.
- Verify the direction of the ratio with a slow move before running anything
fast. A ratio inverted by mistake is a factor of
gainsquared out. - Verify the kinematic and mechanic split by checking a torque channel explicitly. This is the one thing this block does that a plain gain does not, and the one thing you cannot see in the tree.
- Confirm the round trip. Load to motor and back should return the input exactly.
- Nothing here depends on the task rate.
The two curves crossing at 1 is the whole point: at a ratio of one a gearbox does nothing to either kind of signal.
| Symptom | Cause | Action |
|---|---|---|
| A torque channel scaled the same way as a speed channel | That channel is on the kinematic side of the split | The split is fixed at build time — the controller needs rebuilding |
| Everything scaled the same way | The mechanic channel count is 0, which is the default | Same |
| The conversion is inverted | The two tooth counts are the wrong way round | Read gain back and check it against a known speed |
| A tooth count I wrote did not take | It was 0, which is refused | Write a non-zero value |
| A tooth count of 0 gave no warning | Expected: the block keeps the previous value silently | Read it back |
| Everything became invalid | A tooth count that is not a valid number passes the zero check and poisons gain |
Rewrite both counts |
| Every channel inverted | A tooth count is negative, which is accepted | Check both signs |
| The round trip does not return the input | Something changed the ratio between the two directions | Check nothing else writes the tooth counts |
| I cannot tell which channels are kinematic | The split is not published | Ask whoever configured the machine |
| The channel paths are names, not arrays | Your instance was built with named channels | Both forms behave identically |
| Two named channels move together | Two channels were given the same name at build time, which silently merges them | The controller needs rebuilding |
| I need to switch it off | Not possible — there is no enable | Set both tooth counts equal |
| I need a non-linear transmission | Wrong block | Use Lookup |
A starting point for a 10:1 reduction:
nLoadSide = 1
nMotorSide = 10
Then read gain back and confirm it is 0.1.
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
| Ratio | nLoadSide, nMotorSide |
gain = nLoadSide ÷ nMotorSide, recomputed every cycle |
gain |
| Kinematic channels | Fixed at build time | Multiplied by gain going to the motor side, divided coming back |
Not reported |
| Mechanic channels | Fixed at build time | Divided by gain going to the motor side, multiplied coming back |
Not reported |
| The kinematic/mechanic split | Fixed at build time | Not published. Cannot be read or changed from the tree | Not reported |
| A tooth count of 0 | Checked | Refused — the previous value is kept, so the block can never divide by zero | Not reported |
| A negative tooth count | Nothing | Accepted. Inverts every channel | gain reads negative |
| Values that are not numbers | Nothing | Not checked. They pass the zero test and poison every channel | Not reported |
| Round trip | Fixed | The two directions are exact inverses | Not reported |
| Channel order | Fixed at build time | The split is by position, so inserting a channel changes which side its neighbours fall on | Not reported |
| Enable | None | There is no enable, disable or isEnabled | Not applicable |
| Channel count | Fixed at build time | Cannot be changed from the tree | Not reported |
This block logs nothing during operation. It may log at startup if the tooth counts are zero. Every other condition above shows as a value on a trace, or not at all.
Verified against motorcortex-control3 3.30.0 (bc348fd).