CollisionDetector
CollisionDetector notices when an actuator meets something it was not expecting.6 minute read
CollisionDetector notices when an actuator meets something it was not
expecting. It compares the torque the controller asked for against the torque
the machine actually developed, and flags a discrepancy that persists.
The trick is that the commanded torque is delayed to match the measurement’s own lag before the two are compared, so the difference stays flat during ordinary motion and the threshold can be tight.
flowchart LR
i1(["torqueReference"]) --> B["CollisionDetector"]
i2(["torqueActual"]) --> B
i3(["reset"]) --> B
i4(["disable"]) --> B
p1(["enable"]) --> B
B --> o1(["torqueError"])
B --> o2(["isEnabled"])
B --> s1(["collisionDetector — the detection settings and results"])
B --> s2(["collisionReferenceFilter — the delay matching"])
The thresholds are not on this block. They live one level down, under
collisionDetector. SetcollisionDetector/tooHighandcollisionDetector/tooLowto your collision thresholds andcollisionDetector/timeWindowto how long the discrepancy must persist.
The detection result is also one level down, at
collisionDetector/noError. This block publishes onlytorqueError— readnoErrorfrom the sub-tree to know whether a collision was detected.
The block ships disabled.
enabledefaults to false. Nothing happens until you set it.
Signals
Inputs
| Path | Unit | Range | Description |
|---|---|---|---|
torqueReference |
torque unit | unbounded | The torque the controller is asking for. Delayed internally before the comparison. |
torqueActual |
torque unit | unbounded | The torque the machine actually developed — from a sensor or the drive. |
reset |
- | true or false | Clears the detection. Passed through to the detector below. The block clears it for you. |
disable |
- | true or false | Suspends detection. The error is still computed and published. |
Outputs
| Path | Unit | Description |
|---|---|---|
torqueError |
torque unit | The measured torque minus the delay-matched reference. This is the signal to trace when setting thresholds. |
isEnabled |
- | Detection is running. |
The detection flags themselves — isTooLow, isTooHigh, noError — are under
collisionDetector.
Parameters
| Path | Unit | Default | Range | Effect |
|---|---|---|---|---|
enable |
- | false | - | Turns detection on. The block does nothing until you set this. |
That is the only parameter at this level. Everything that shapes the detection is in the two sub-trees below:
| Path | Default | Effect |
|---|---|---|
collisionDetector/tooHigh |
0.05 | The upper collision threshold on torqueError. |
collisionDetector/tooLow |
-0.05 | The lower collision threshold. |
collisionDetector/high, …/low |
0.02, -0.02 | Warning levels, if you want an early indication. |
collisionDetector/timeWindow |
0.0 | How long the error must exceed a threshold before it is flagged. At 0 a single noisy sample trips it. |
collisionReferenceFilter/enable |
true | The delay matching. Leave this on — turning it off produces false collisions on every move. |
All are persistent and survive a controller restart.
Setup
-
Connect the controller’s torque command to
torqueReferenceand the measured torque totorqueActual. Both must be in the same units — nothing converts between them. -
Leave
enablefalse for now. -
Run the machine through its normal motion and trace
torqueError. It should stay small and flat. If it swings during acceleration, the two signals are not in the same units, or one is scaled differently. -
Note the largest excursion of
torqueErrorduring normal motion, including the fastest move and the hardest acceleration. -
Set
collisionDetector/tooHighandcollisionDetector/tooLowoutside that, with margin. -
Set
collisionDetector/timeWindow— go to Tuning. -
Set
enabletrue.Whatever acts on
collisionDetector/noErrorwill act the moment it goes false. If that is a stop, confirm the thresholds are wide enough for normal motion before you enable, or the machine will stop on its own first move. -
Push against the actuator by hand, gently, and confirm the detection comes up.
Tuning
- Trace
torqueErrorfor a full working cycle before setting any threshold. The whole design aims to keep this flat; if it is not flat, fix that first. - If
torqueErrorswings during acceleration, the delay matching is not suiting your drive. The internal delay is fixed at about 15 milliseconds at a 1 kHz task rate and is not adjustable. Widen the thresholds, or filtertorqueActualupstream so its lag is closer to that. - Set the collision thresholds from the largest normal excursion, with margin — typically twice it.
- Set
timeWindowlonger than the transient you want to ignore and shorter than the time you can afford to keep pushing. Ten to fifty milliseconds is a reasonable range. - Test with a real obstruction, not just by hand. A soft obstruction produces
a slower error rise and needs a longer
timeWindowto be tolerated, or a lower threshold to be caught. - Set the warning levels inside the collision thresholds if you want an early indication before stopping.
- Re-check
torqueErrorafter any change to the drive tuning or to the feedforward path — both change the lag this block is matching.
The flat section is what makes a tight threshold possible.
| Symptom | Cause | Action |
|---|---|---|
| Nothing is ever detected | enable defaults to false |
Set it true and check isEnabled |
| Nothing is detected even when enabled | The thresholds are on the sub-tree, not here | Set collisionDetector/tooHigh and …/tooLow |
| I cannot find the detection result | It is at collisionDetector/noError |
Read it from the sub-tree |
torqueError swings during every move |
The internal delay does not match your drive’s lag, or the two inputs are scaled differently | Check units first, then widen the thresholds |
torqueError is huge and grows with speed |
The two inputs are in different units | Fix the scaling upstream |
| False collisions on every move | The delay matching may be off — check collisionReferenceFilter/enable |
Turn it back on |
| False collisions on noise | collisionDetector/timeWindow is 0 |
Lengthen it |
| A real collision was missed | The thresholds are too wide, or timeWindow too long |
Trace torqueError during the collision and set from that |
| False collisions in torque mode | Detection cannot be suppressed from the tree in this version | Disable the block while in torque mode |
| A burst of error right after startup | The delay matching needs about 30 cycles to fill | Enable the block a moment after start |
| The flags will not clear | The detector below latches | Pulse reset |
| Everything is flagged at once | One of the inputs is not a valid number | Fix the upstream signal; this is the detector telling you so |
| I need this on several axes | Not possible — this block is single channel | Use one instance per axis |
A starting point, once you have traced torqueError:
enable = true
collisionDetector/tooHigh = <twice the largest normal excursion>
collisionDetector/tooLow = -<the same>
collisionDetector/timeWindow = 0.02
collisionReferenceFilter/enable = true
Limits and errors
| Limit | Set by | What happens | Reported |
|---|---|---|---|
| Detection thresholds | collisionDetector/tooHigh, …/tooLow |
The detector below flags a persistent discrepancy | collisionDetector/noError |
| Debounce | collisionDetector/timeWindow |
The error must exceed a threshold for this long. At the default of 0 a single sample trips it | Not reported |
| Delay matching | Fixed | The reference is delayed by about 15 milliseconds at a 1 kHz task rate. Not adjustable, and not matched to any particular drive | Not reported |
| Delay matching startup | Fixed | Takes about 30 cycles to fill after a start, during which torqueError reads high |
Not reported |
| Input units | Nothing | Not checked. The two torque inputs must already be in the same units | torqueError |
| Torque-mode suppression | Not reachable from the tree | The block can suppress detection while the drive is in torque mode, but only when driven from an application | Not reported |
| Detection output | Fixed | Not published at this level. Read it from the sub-tree | Not applicable |
enable |
Fixed at false | The block ships disabled | isEnabled |
| Values that are not numbers | Handled below | A bad input makes torqueError invalid, and the detector below raises every flag — the safe direction |
The detector’s flags |
| Reset | reset |
Clears the detection below. Cleared for you | Not reported |
| Channel count | Fixed | One actuator per instance, always | Not reported |
This block logs nothing, ever. Every condition above shows as a value on a trace, or not at all.
Verified against motorcortex-control3 3.30.0 (bc348fd).