Simulation - sim/: the unchanged robot firmware compiled into hexapod_sim.dll against PC stand-ins (Arduino, Servo, Wire + register-level MPU6050, RF24 with matching-config radio), a kinematic body model (support plane + planted-foot odometry) that also drives the simulated IMU, and a headless smoke test (sim_smoke). build.ps1 builds and tests. - Hexapod_Simulation_Unity/ folded in (history kept in a bundle outside the repo). Assets/HexapodSim loads the DLL, drives the existing leg rig, and offers joystick / keyboard / robot-serial input plus a test panel. Robot (all found or confirmed in the simulation) - Config.h geometry taken from the Unity model. - IK femur elevation sign, gait stance direction, body pose rotation direction, yaw lever arm. - Stance feet integrated from the current command; gait restarts at mid-stance; heading integrates the applied turn rate, only while walking. - Leg clearance and reach checks (Limits::feetFeasible); walk command and body pose scaled as a whole, pose scale rate-limited, planted feet guarded so the body never snaps or legs collide. - Robot-gyro self-leveling as an integrator. - Heading mode: steering relative to the body; S walks backward. - Standing height from the remote (STANCE_HEIGHT_RANGE_MM). Protocol v3 (reflash both boards) - CmdPacket gains body_height (22 bytes). Remote - Height slider (Nextion hHeight/nHeight, serial [ ]). - Fixed unspecified I2C read order in RemoteIMU. LEGACY/: owner's old Nextion HMI and remote hardware assets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
62 lines
2.1 KiB
C++
62 lines
2.1 KiB
C++
#pragma once
|
|
#include "UiTypes.h"
|
|
#include "Sticks.h"
|
|
#include "RemoteIMU.h"
|
|
#include "SmoothedValue.h"
|
|
#include "Config.h"
|
|
|
|
// Operator-facing state of the remote: every toggle the touchscreen can
|
|
// flip, the interlocks around them, and the smoothed setpoints. It does not
|
|
// know the wire format - PacketBuilder turns this into a CmdPacket.
|
|
class RemoteState {
|
|
public:
|
|
void begin();
|
|
|
|
// Applies one operator request. Sticks are needed for the arm interlock
|
|
// and calibration, the IMU for re-zeroing. Returns true if accepted;
|
|
// rejections leave an explanation in message().
|
|
bool handle(const UiEvent& e, Sticks& sticks, RemoteIMU& imu, uint32_t now_ms);
|
|
|
|
// Advances smoothers and link-loss handling. Call once per TX tick.
|
|
void update(float dt, bool link_ok, uint32_t now_ms);
|
|
|
|
bool armed() const { return armed_; }
|
|
bool standRequested() const { return stand_; }
|
|
bool gaitWave() const { return gait_wave_; }
|
|
bool modeB() const { return mode_b_; }
|
|
bool rstickXlate() const { return rstick_xlate_; }
|
|
bool remoteGyro() const { return remote_gyro_; }
|
|
bool robotGyro() const { return robot_gyro_; }
|
|
|
|
uint8_t speedTarget() const { return speed_target_; }
|
|
int16_t height() const { return height_; } // -1000..1000, 0 = default
|
|
uint8_t speedCurrent() const { return (uint8_t)lroundf(speed_.current); }
|
|
float remoteTiltBlend() const { return tilt_blend_.current; } // 0..1, fades on the gyro toggle
|
|
|
|
const char* message(uint32_t now_ms) const { return now_ms < message_until_ms_ ? message_ : ""; }
|
|
void setMessage(const char* msg, uint32_t now_ms);
|
|
|
|
void fillView(UiView& v, uint32_t now_ms) const;
|
|
|
|
private:
|
|
bool armed_ = false;
|
|
bool stand_ = false;
|
|
bool gait_wave_ = false;
|
|
bool mode_b_ = false;
|
|
bool rstick_xlate_ = false;
|
|
bool remote_gyro_ = false;
|
|
bool robot_gyro_ = false;
|
|
bool calibrating_ = false;
|
|
|
|
uint8_t speed_target_ = SPEED_SCALE_DEFAULT;
|
|
int16_t height_ = 0;
|
|
SmoothedValue speed_{SPEED_SCALE_RATE_PER_SEC};
|
|
SmoothedValue tilt_blend_{REMOTE_TILT_FADE_PER_SEC};
|
|
|
|
bool link_was_ok_ = false;
|
|
const char* message_ = "";
|
|
uint32_t message_until_ms_ = 0;
|
|
|
|
void disarm();
|
|
};
|