Stop addressing an axis this tower does not have, and carry the live calibration
This commit is contained in:
parent
5b3662c529
commit
31da8012d7
|
|
@ -289,11 +289,22 @@ struct CalibAxisView {
|
|||
double r2 = 0;
|
||||
int n = 0;
|
||||
};
|
||||
// The degrees<->counts map an axis is actually using right now: from config.ini
|
||||
// at startup, replaced in memory by a fit or a homing derivation. Distinct from
|
||||
// CalibAxisView, which describes the last FIT and only exists once one has run.
|
||||
struct AxisMapView {
|
||||
double counts_per_deg = 0;
|
||||
double deg_at_center = 0;
|
||||
};
|
||||
|
||||
struct CalibResultView {
|
||||
bool has = false;
|
||||
bool has = false; // has a fit run THIS SESSION?
|
||||
long long ts_ms = 0;
|
||||
bool pitch_present = false;
|
||||
CalibAxisView yaw, pitch;
|
||||
// Always populated. "No fit this session" is not the same as "uncalibrated":
|
||||
// the working calibration usually comes from config.ini and predates the run.
|
||||
AxisMapView live_yaw, live_pitch;
|
||||
};
|
||||
|
||||
// Worst-case encoder tracking error from the last DIAG run, per axis, for the
|
||||
|
|
|
|||
|
|
@ -907,6 +907,9 @@ struct Application::Impl {
|
|||
// --- Activity strip + last calibration ---
|
||||
s.calib = last_calib_view;
|
||||
s.calib.pitch_present = s.gimbal.pitch_present || s.calib.pitch_present;
|
||||
// The map in force right now, whether or not anything was fitted today.
|
||||
s.calib.live_yaw = {cfg.geometry.yaw.counts_per_deg, cfg.geometry.yaw.deg_at_center};
|
||||
s.calib.live_pitch = {cfg.geometry.pitch.counts_per_deg, cfg.geometry.pitch.deg_at_center};
|
||||
s.diag = last_diag_view;
|
||||
s.test = last_test_view;
|
||||
fillActivity(s);
|
||||
|
|
@ -1040,7 +1043,11 @@ struct Application::Impl {
|
|||
} clear_homing{homing_active_};
|
||||
|
||||
motor->sendCommand("ENABLE Y");
|
||||
motor->sendCommand("ENABLE P");
|
||||
// Only address axes this tower actually has. A yaw-only rig answers
|
||||
// "ERR axis not present" to every pitch command, which arrives in the log
|
||||
// as a row of warnings at every startup - noise that trains an operator to
|
||||
// ignore exactly the channel that reports real faults.
|
||||
if (cfg.hardware.hasAxis("pitch")) motor->sendCommand("ENABLE P");
|
||||
// Tell the firmware where to anchor the homed midpoint and how much
|
||||
// clearance to keep from each endstop, BEFORE homing: finishHoming() uses
|
||||
// the centre count to re-origin, so a late send would apply to the next
|
||||
|
|
@ -1050,7 +1057,10 @@ struct Application::Impl {
|
|||
// Confirm the current landed BEFORE driving into anything. This is the
|
||||
// only check standing between a stale firmware and an endstop that cannot
|
||||
// survive full torque.
|
||||
if (yaw_current_.ok || pitch_current_.ok) {
|
||||
// Only when a reduction is actually depended on. An axis running at one
|
||||
// current for everything has nothing to lose if the command went astray,
|
||||
// and the check costs a DUMP round trip whose output floods the log.
|
||||
if (cfg.drivetrain.yaw.reducesForHoming() || cfg.drivetrain.pitch.reducesForHoming()) {
|
||||
if (auto dd = freshDump(std::chrono::seconds(3))) {
|
||||
if (!verifyCurrentAdoption(*dd)) return;
|
||||
} else {
|
||||
|
|
@ -1122,7 +1132,7 @@ struct Application::Impl {
|
|||
}
|
||||
// Production move speeds for subsequent MOVE commands.
|
||||
motor->sendCommand("SPEED Y 50000");
|
||||
motor->sendCommand("SPEED P 150000");
|
||||
if (cfg.hardware.hasAxis("pitch")) motor->sendCommand("SPEED P 150000");
|
||||
LOG_INFO << "Gimbal init finished";
|
||||
}
|
||||
|
||||
|
|
@ -1208,9 +1218,11 @@ struct Application::Impl {
|
|||
// clampTarget() keeps clear of each hard limit.
|
||||
void sendAnchorConfig() {
|
||||
motor->sendCommand("CENTER Y " + std::to_string(cfg.geometry.yaw.center_count));
|
||||
motor->sendCommand("CENTER P " + std::to_string(cfg.geometry.pitch.center_count));
|
||||
motor->sendCommand("MARGIN Y " + std::to_string(cfg.yaw_soft_margin_counts));
|
||||
motor->sendCommand("MARGIN P " + std::to_string(cfg.pitch_soft_margin_counts));
|
||||
if (cfg.hardware.hasAxis("pitch")) {
|
||||
motor->sendCommand("CENTER P " + std::to_string(cfg.geometry.pitch.center_count));
|
||||
motor->sendCommand("MARGIN P " + std::to_string(cfg.pitch_soft_margin_counts));
|
||||
}
|
||||
// Motor current belongs here too: it governs homing torque, so it has to
|
||||
// land before the search, not after it.
|
||||
auto sendCurrent = [&](char axis, const TmcCurrentPlan& p) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue