fwt_software/config/hardware.example.ini

260 lines
13 KiB
INI

; ===========================================================================
; hardware.ini - what this machine IS.
;
; Written once when the tower is assembled. Changing anything here means the
; hardware itself changed: a different board, a sensor fitted or removed, a
; cable moved to another port. Operational settings you tune to get better
; images - capture interval, camera profiles, scan grid, output paths - live in
; config.ini instead, and so does calibration, which is redone from time to time.
;
; WHERE THIS FILE GOES
; /etc/fire_gimbal_control/hardware.ini
;
; That is beside credentials.env, and it is deliberately OUTSIDE the directory
; deploy.sh rsyncs: a deploy cannot overwrite or delete what it never touches.
; The program looks, in order, at:
; --hardware <path> | $FGC_HARDWARE | /etc/... | beside config.ini
;
; Keys here override the same keys in config.ini, and any that are still set in
; both are named in a warning at startup so the stale copy can be deleted.
; ===========================================================================
; --- Which computer -------------------------------------------------------
[Board]
; Free-form, but keep it matching a directory under hardware/ so the setup kit
; for this board is easy to find.
model = lattepanda-3-delta
; PlatformIO env used to build the motor firmware for this board's MCU.
; lattepanda-3-delta / sigma -> leonardo (ATmega32U4, 5V logic)
; lattepanda-iota -> iota_rp2040 (RP2040, 3.3V logic)
firmware_env = leonardo
; --- What is fitted -------------------------------------------------------
; This is a DECLARATION, and its whole purpose is that startup can compare it
; with what it actually finds. The program already copes gracefully when a part
; is missing - the pitch axis, the IMU, the ambient sensor - which is correct for
; a rig built without them, and indistinguishable from a fault on a rig that has
; them. Saying what was assembled is what tells those two apart.
[Hardware]
; Axes this gimbal has. A yaw-only rig says: axes = yaw
axes = yaw, pitch
; Orientation sensor: a model name, or 'none'. Most of the fleet has none.
;
; Naming a model here is what ENABLES it - there is no second key to remember.
; [Features] enable_imu still exists for towers with no hardware.ini, but where
; this file declares a sensor the declaration wins, and a flag contradicting it
; is warned about and ignored.
imu = none
; Ambient temperature/humidity sensor: a model name, or 'none'. Same rule.
; sht41 on the host's own I2C bus ([Env] below)
; dht11 on the motor MCU, which reads it (the legacy towers; needs [Pins] dht)
env = sht41
; An enclosure fan the motor MCU runs from its DHT11: 'fan', or 'none' (default).
; The legacy towers: off to 25 C, +20/255 per degree, full from 37.75 C, and full
; whenever the sensor cannot be read. Needs env = dht11 and [Pins] fan_pwm.
;cooling = fan
; The [Camera.<name>] blocks expected to be present and found ("rgb, tir" with
; the thermal camera).
cameras = rgb
; How much bearing one picture covers, in degrees. Pan mode ('mode pan') cuts
; its span into as many pictures as this takes. 6 until the lens is measured.
pan_step_deg = 6
; Image saving: how this computer shares its 4 cores between saved frames.
; Measured with a 16 MP 12-bit frame (docs/raw12-pipeline-measurements.md): the
; IOTA (N150) keeps up with one waypoint every 0.7 s with 1 worker; the 3 Delta
; (N5105) needs 2 workers for that. jxl_threads is libjxl's threads per frame;
; 0 or absent = 4 / save_workers. save_queue_max is how many frames may wait
; or be saving before the scan holds at its waypoint (each raw frame ~24 MB).
; A thermal camera adds a frame per picture (0.6 MB): raise it by 2.
save_workers = 1
;jxl_threads = 0
save_queue_max = 4
;
; What happens when this does not match the rig:
; declared but absent -> warned about by name, and with [Features]
; strict_presence = 1 in config.ini the program refuses
; to start (exit 3). --degraded starts it anyway.
; found but undeclared -> warned about as a stale file. Never fatal.
; A tower with no hardware.ini at all is never reconciled, whatever
; strict_presence says: gaining this file must not change how a tower behaves.
[Thermal]
; The CPU guard: in summer the sun and the gimbal heat this computer until its
; CPU slows itself down. The guard spaces pictures out, then pauses them (gimbal
; parked, camera stream stopped) until it cools - it never stops the program and
; never touches picture quality. Every key may be left out; these are the
; defaults. See docs/thermal-throttling.md.
;enabled = true
; Slowed: pictures at least slow_factor times further apart (more if saving
; needs it: 1.5 x the save time per worker), from slow_c, or when the CPU
; throttles, or when saving is the bottleneck - the scan waited for it
; held_share_pct of the last minute, or held_slow_s in one go. Back to full pace
; once below slow_c - hysteresis_c, keeping up, and saving fast enough for it,
; for calm_s.
;slow_c = 85
;hysteresis_c = 5
;slow_factor = 2
;calm_s = 120
;held_share_pct = 25
;held_slow_s = 30
; Paused: at pause_c for pause_after_s, or saving still the bottleneck
; held_pause_s after slowing (or one wait that long). Resumes (slowed) after
; min_pause_s once at resume_c or below and nothing is left to save.
;pause_c = 92
;pause_after_s = 20
;held_pause_s = 120
;resume_c = 75
;min_pause_s = 300
; Throttling is also judged from the clock - below clock_low_pct of the chip's
; top speed while at least busy_high_pct busy - which catches the power-limit
; slow-downs the kernel does not count.
;clock_low_pct = 50
;busy_high_pct = 50
;sample_ms = 2000
; A fake /sys + /proc tree for a simulation (tools/thermal-sim/fake-temp.sh).
;sysfs_root = /
; --- Where to find it -----------------------------------------------------
; Device bindings. These follow the hardware, not the tower, so they belong here
; rather than in config.ini.
[Serial]
; The motor controller MCU. Prefer the stable by-id symlink over /dev/ttyACM0,
; which is assigned in enumeration order and moves when USB devices change.
; Leonardo : /dev/serial/by-id/usb-Arduino_LLC_Arduino_Leonardo-if00
device = /dev/serial/by-id/usb-Arduino_LLC_Arduino_Leonardo-if00
baud = 115200
[Pins]
; How the MCU is wired to each axis's TMC5160 driver board. The host never sends
; these: the FIRMWARE is built from them. firmware/tools/gen_wiring.py reads this
; section from the tower's own copy of this file when the firmware is built on
; the tower, and refuses pins the board cannot use. Change a wire, change this,
; rebuild and re-flash. `test hardware motor` compares it with what the running
; firmware reports, so a flash built from an older copy shows up there.
;
; The reference loom for each board, with the MCU-pin -> driver-pin table, is in
; hardware/<board>/pins.ini.
;
; Leonardo (Delta): SPI is fixed on the ICSP header, so only CS and EN are named.
; RP2040 (IOTA): also spi_sck / spi_mosi / spi_miso, from SPI0's pin groups -
; SCK {2,6,18,22} MOSI {3,7,19,23} MISO {0,4,16,20}
; Only axes listed in [Hardware] axes get pins.
yaw_cs = 8
yaw_en = 7
pitch_cs = 1
pitch_en = 0
; Parts on the MCU itself - the legacy towers (hardware/lattepanda-3-delta/
; pins-legacy.ini). Each only with its declaration above; the firmware is built
; with them only where they are declared, and is unchanged elsewhere.
;dht = 9 ; env = dht11
;fan_pwm = 10 ; cooling = fan; a PWM pin (Leonardo: 3 5 6 9 10 11 13)
;fan_tach = 11 ; optional; lets the host see a fan that has stopped
;spi_idle_cs = 2 ; another device on the drivers' SPI bus, held deselected
[IMU]
; Only read when [Hardware] imu is not 'none'. On the LattePanda 3 Delta the MTi
; is on the RS-232 header, which is a hardware UART: a stable /dev/ttyS* node,
; NOT a USB device and NOT /dev/ttyUSB0-3 (those are the modem).
device = /dev/ttyS0
[Env]
; Only read when [Hardware] env is not 'none'. This is the board's OWN native
; I2C bus, not the motor controller's serial link. The bus number varies by
; board - it is /dev/i2c-2 on the 3 Delta, not the /dev/i2c-1 default.
;
; Two traps when finding it: i2cdetect false-negatives on the SHT4x (probe with
; a real measurement instead), and an SMBus-only adapter can never work at all
; (i2cdetect -F N reports 'I2C = no').
i2c_device = /dev/i2c-2
i2c_addr = 0x44
; --- What it is made of ---------------------------------------------------
; The drivetrain, one block per axis. A different motor, gearbox or driver board
; changes these; nothing an operator tunes belongs here.
[Motor.yaw]
; Sense resistor fitted to THIS axis's TMC5160 board. It is what makes the
; milliamp figures below mean anything, which is why the host - not the firmware -
; converts them into GLOBALSCALER/IRUN register values and sends those.
r_sense_ohm = 0.075
; Milliamps RMS per phase. run_current_ma is normal motion; homing_current_ma
; applies ONLY while hunting for an endstop.
;
; The two differ when the stop cannot survive full torque. On the IOTA tower the
; endstop is a screw head meeting another screw head, and the high gear ratio let
; the motor shear one past the other - it ran 1.8 turns past the stop without the
; encoder ever falling behind. At 189 mA it homes against the same screw cleanly.
;
; The startup log prints what the registers ACTUALLY deliver, which is not
; always what you asked for; believe the log, not this file.
run_current_ma = 756
homing_current_ma = 200
; Mechanical angle between the hard endstops. A NAMEPLATE FACT: homing measures
; the travel in counts, and dividing by this yields [Motor] yaw_counts_per_deg in
; config.ini, offered for saving at the y/n prompt.
;
; Deliberately a different key, in a different file, from counts_per_deg itself:
; hardware.ini is merged OVER config.ini and wins, so sharing a key would
; silently discard every calibration the save path writes back.
;
; ROUGH until somebody measures it. Every bearing inherits its error
; proportionally, until 'gimbal heading setup' supersedes it with a landmark fit.
travel_deg = 340
; Production move speed, IN DEGREES PER SECOND - not VMAX.
;
; A register value is not portable: VMAX 30000 is 21.8 deg/s on the Delta fleet
; and 6.0 deg/s on the IOTA, because their gear ratios differ by 3.6x. Both were
; carrying the same literal, which is how two towers ended up sweeping at
; completely different speeds while their configs looked identical.
;
; The host converts through yaw_counts_per_deg and sends SPEED after each home,
; so this follows the calibration automatically. An axis whose scale is not
; trustworthy is left on the firmware's default and the reason is logged.
scan_speed_deg_s = 8.0
; The other two motions, also in deg/s. Both happen BEFORE the first home, so
; they cannot use the counts_per_deg that homing derives - they convert through
; the scale this file implies (steps_per_rev / travel_deg), which on the IOTA
; agrees with the measured one to 0.25%.
homing_speed_deg_s = 4.0
center_speed_deg_s = 6.0
; --- Told to the firmware, which holds none of it itself --------------------
; The config handshake (docs/configuration.md): the firmware asks with NEED and
; these answer it. A key missing here leaves that axis in NEEDCFG, refusing to
; move, with the missing name logged - deliberately, because a drivetrain value
; guessed by the firmware is the duplication this removes.
;
; Expected full mechanical travel, IN COUNTS. Measured, not derived: it is the
; only guard against a PHANTOM endstop - too little homing current and the motor
; stalls on ordinary friction, trips the same latch a real stop does, and the
; bogus limit is accepted.
steps_per_rev = 1210778
; |XACTUAL - XENC| that means "position untrustworthy". 1000 here: the
; free-running gap measured 199-229 counts on tower 121, so this is ~4x headroom.
; Re-measure whenever the homing CURRENT changes - the gap is coupled to it, and
; notably NOT to speed (229 counts at VMAX 6000, 199 at 30000). Lowering is the
; safe direction; raising it blunts the only stall signal the rig has.
enc_deviation = 1000
; TMC SW_MODE - physical endstop switches on REFL/REFR. Yaw on this rig homes by
; StallGuard with no switches (0); an axis with real switches sets the bits.
sw_mode = 0
; Is this axis's encoder aligned to XACTUAL and usable for hold and DIAG?
has_encoder = true
; Microsteps per encoder count (ENC_CONST). Leave it out for the default, 12.8.
; A drivetrain whose encoder differs must declare it: wrong by 2%, the counter
; and the encoder drift apart as the axis turns and homing takes that for a stop.
;enc_const = 12.5
[Camera.rgb]
; The serial of the physical camera fitted to this tower. A USB DEV_ id, or a
; GigE IP address.
id = DEV_1AB22C049CD1
; A thermal camera (TarisIR mini): its serial number, as the SDK's search finds
; it, and the network port it is cabled to (static address, no DHCP, MTU 1500;
; only used to say what is wrong when the camera is not found).
;[Camera.tir]
;driver = taris
;id = 2017744
;interface = enp1s0