DOB #
Brief #
dob is a disturbance (load torque) observer on the torque command. It estimates the torque the rigid body model cannot explain (load, friction, cutting force, cogging) and subtracts it from the torque command, so the drive cancels the disturbance before the velocity integrator has to. conf/template/filters.txt loads it (opt-in, link filters after link pmsm) between biquad0 and the torque controller, passing through (k 0) until set; conf/fanuc_a3-3000.txt links it with k 1 and the friction feedforward off. The wiring, by hand or as in the template:
dob0.in = pid0.torque_cmd(the template:biquad0.out)pmsm_ttc0.torque = dob0.outdob0.vel = vel1.vel, the velocity observer pid0 usesvel1.torque = dob0.out(andvel2.torque), so the velocity observers see the compensated torquedob0.jset to the total inertiaconf0.j + conf0.j_sys, aspid0uses it (j_mot + j_sys)dob0.enhas to be linked or set: unlinked it is 0 anddobonly passesinthrough
Component Explanation #
All work is done in rt.
- Model:
- Rigid body:
j * dw/dt = u + d, sod = j * dw/dt - u. wis the observer velocityvel(vel1, which already filters the encoder at its loop bandwidth);(w - last w) / periodis the acceleration caused by the torqueuof the step before, whereuis the previousout(the compensated command). An earlier version differenced the raw position twice: with an 8000 count encoder that left about 0.4 Nm rms ond_estatbw50 (upstream review), the observer velocity about a fifth of it.dis low passed atbwintod_est(bw0 = no filter). Default 20 Hz (upstream review): on the Y plant 50 Hz cuts the load step error by about a third (4.5 against 6.7 mrad for a 2 Nm step) at 2.5 times the estimate noise; set it per axis.
- Compensation:
out = in - k * d_est, withk * d_estclamped to+-maxwhenmax > 0. The template linksmaxto the torque limitconf0.max_force, so the compensation can never exceed what the drive may apply; a smaller value bounds the load share dob takes.k0 only estimates (d_estis still valid,out = in),k1 is full compensation.
- Enable and start:
- While
en <= 0orj <= 0(the default):out = in,d_est = 0, and the last position, velocity and torque keep following, so enabling (or settingj) starts clean. - After power up or enabling it waits one rt step for a previous velocity sample before estimating.
- Standstill hold (
hold, linked topid0.holdwithpid0.hold_en2):
- With stiction the estimate freezes at whatever the last move left (on a vertical axis gravity plus or minus the friction, so the standing current depends on the direction of the last move).
- While
holdis 1 (pid0 at rest, position error inside its hold window) the estimate stops and the compensation slews athold_rateso thatoutmoves tohold_o(the moving offsetconf0.o, about 0 on a horizontal axis).d_estfollows the compensation, so the estimate goes on from there when the hold ends. If the axis creeps out of the window the hold ends at once. maxmust leave room for the slew: on Z (o 4.59, f 2.7)max4 stopped it short, 8 did not.
- Results (commit message): in the simulation on the Y axis the load step error was 2.5 to 3 times lower at
bw50 to 100 Hz, 200 Hz oscillated. On the Y axis bench, with the friction feedforward off,bw50 halved the error.
jmust be set, or dob stays off. With no inertia the model would read the drive’s own torque command as disturbance (d=-u) andkwould cancel it.
Pins #
| Name | Description |
|---|---|
| in | input, Torque command (Nm), pid0.torque_cmd |
| out | output, Compensated torque command (Nm) |
| vel | input, Observer velocity (rad/s), vel1.vel |
| j | parameter, Total inertia (kgm^2, default 0 = dob off) |
| bw | parameter, Low pass of the estimate (Hz, default 20, 0 = none) |
| k | parameter, Compensation gain, 0 = estimate only, 1 = full (default 0) |
| max | parameter, Clamp on the compensation (Nm, default 0 = none), conf0.max_force |
| d_est | output, Estimated disturbance torque (Nm), 0 while disabled |
| en | input, Enable, 0 = pass-through |
| hold | input, Standstill hold, pid0.hold (with pid0.hold_en 2) |
| hold_o | parameter, Torque the hold moves out to (Nm), conf0.o |
| hold_rate | parameter, Slew rate of out to hold_o (Nm/s), default 20 |
References #
Source: .c File