Compare commits

...

2 Commits

3 changed files with 19 additions and 2 deletions

View File

@ -322,7 +322,7 @@ job. Details, payloads and safety rules: [docs/mqtt-api.md](docs/mqtt-api.md).
| Command | Does | | Command | Does |
|---|---| |---|---|
| `mode auto` / `mode manual` | sweep the scan grid / stop and take the gimbal by hand (it stays homed and powered) | | `mode auto` / `mode manual` | sweep the scan grid / stop the gimbal where it is and take it by hand (it stays homed and powered) |
| `mode pan <heading> <span> [<pitch>]` | watch one direction: `mode pan 90 30` covers 75°-105°, a picture every 6° | | `mode pan <heading> <span> [<pitch>]` | watch one direction: `mode pan 90 30` covers 75°-105°, a picture every 6° |
| `gimbal home` | find the endstops and centre - needed after every power-up | | `gimbal home` | find the endstops and centre - needed after every power-up |
| `gimbal move <yaw>[,<pitch>]` | point at a **true bearing** (0 = north) and an elevation, in degrees; without a pitch only yaw moves. A yaw-only tower ignores the pitch and refuses pitch-only commands | | `gimbal move <yaw>[,<pitch>]` | point at a **true bearing** (0 = north) and an elevation, in degrees; without a pitch only yaw moves. A yaw-only tower ignores the pitch and refuses pitch-only commands |

View File

@ -1849,6 +1849,7 @@ struct Application::Impl {
if (m == Mode::Manual) camera->stop(); if (m == Mode::Manual) camera->stop();
else camera->start(); else camera->start();
scheduler->setMode(m, pan); scheduler->setMode(m, pan);
if (m == Mode::Manual && was != Mode::Manual) stopScanMove();
if (m == Mode::Pan) { if (m == Mode::Pan) {
const auto& h = scheduler->panHeadingsNow(); const auto& h = scheduler->panHeadingsNow();
LOG_INFO << "mode pan: " << panText(pan) << " - " << h.size() LOG_INFO << "mode pan: " << panText(pan) << " - " << h.size()
@ -1861,6 +1862,22 @@ struct Application::Impl {
return true; return true;
} }
// Leaving a scan: stop the move it last sent, which the firmware would
// otherwise finish - a slow return to the first waypoint can take many
// seconds the operator spends waiting for the gimbal to answer. The firmware
// ramps the axis down and holds where it comes to rest (it does not resume
// the move), and the next MOVE or jog supersedes a stop still ramping down.
// Sent whether or not telemetry shows motion, since a MOVE sent this tick
// is not in it yet. Never during a homing, which a STOP ends in ERROR.
void stopScanMove() {
const MotorTelemetry t = motor->telemetry();
if (t.yaw.state == AxisState::Homing ||
(t.pitch_present && t.pitch.state == AxisState::Homing))
return;
if (anyLeftoverMove()) LOG_INFO << "stopping the gimbal where it is";
motor->sendCommand("STOP ALL");
}
// A pan the gimbal can actually do: its pitch inside the homed window (not // A pan the gimbal can actually do: its pitch inside the homed window (not
// clamped to it - that would image an elevation nobody asked for), and at // clamped to it - that would image an elevation nobody asked for), and at
// least one of its headings inside the reachable yaw arc. // least one of its headings inside the reachable yaw arc.

View File

@ -35,7 +35,7 @@ const std::vector<HelpSection>& helpCatalog() {
"Pitch defaults to 0 (level); a yaw-only tower ignores it. Key p pans", "Pitch defaults to 0 (level); a yaw-only tower ignores it. Key p pans",
"30 deg around the current aim.", "30 deg around the current aim.",
"Example: mode pan 90 30"}}, "Example: mode pan 90 30"}},
{"mode manual", "Stop scanning; aim by hand (key m). Cancels a running procedure.", {}}, {"mode manual", "Stop scanning, and the gimbal where it is; aim by hand (key m). Cancels a running procedure.", {}},
}}, }},
{"Capture", "Images and cameras. Manual mode, homed gimbal.", { {"Capture", "Images and cameras. Manual mode, homed gimbal.", {
{"snapshot", "Take one image now (key Space).", { {"snapshot", "Take one image now (key Space).", {