From e3858a17bdd3d34b71b21583c527061fa3c92e93 Mon Sep 17 00:00:00 2001 From: Jack Bogatz Date: Wed, 6 May 2026 11:38:02 -0400 Subject: [PATCH 1/4] 3second test with tvc with after engine --- src/Main.cpp | 5 ----- src/Mode.cpp | 25 +++++++++---------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/src/Main.cpp b/src/Main.cpp index 5b9180a..727150a 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -171,11 +171,6 @@ int main() float pulse = 1500 + ((MissionConstants::kValveClosedAngle - 90) / 90.0) * 1000; int ticks = (pulse / MissionConstants::SERVO_PERIOD) * MissionConstants::MAX_TICKS; servo_driver->set_all_pwm(0, ticks); - // servo_driver->set_pwm(MissionConstants::kNitrogenServoPin, 0, ticks); - // servo_driver->set_pwm(MissionConstants::kPurgeServoPin, 0, ticks); - // servo_driver->set_pwm(MissionConstants::kMainEthanolServoPin, 0, ticks); - // servo_driver->set_pwm(MissionConstants::kMainNitrousServoPin, 0, ticks); - // servo_driver->set_pwm(MissionConstants::kNitrousFillServoPin, 0, ticks); #endif IMU imu; diff --git a/src/Mode.cpp b/src/Mode.cpp index 62742d4..685d70f 100644 --- a/src/Mode.cpp +++ b/src/Mode.cpp @@ -733,7 +733,6 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat double seconds_since_start = currentTime - startTime; navigation.UpdateNavigation(); - controller.UpdateTestTVC(seconds_since_start); // Sequence timing (matching original hotfire.ino logic) if (seconds_since_start >= 0.5 && seconds_since_start < 0.8) { @@ -797,26 +796,20 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat valveControl.CloseValve(ValveControl::ASIOxygen); fifthPartDone = true; } + controller.UpdateTestTVC(seconds_since_start); } else if (seconds_since_start >= 3.0 && seconds_since_start < 4.0) { - // Turn off spark plug and asi oxygen - if (!sixthPartDone) - { - // Uncomment for debugging - std::cout << "Time: " << seconds_since_start << "\n"; - sixthPartDone = true; - } + // Uncomment for debugging + controller.UpdateTestTVC(seconds_since_start); + std::cout << "Time: " << seconds_since_start << "\n"; } + else if (seconds_since_start >= 4.0 && seconds_since_start < 5.0) { - // Turn off spark plug and asi oxygen - if (!seventhPartDone) - { - // Uncomment for debugging - std::cout << "Time: " << seconds_since_start << "\n"; - seventhPartDone = true; - } + // Uncomment for debugging + controller.UpdateTestTVC(seconds_since_start); + std::cout << "Time: " << seconds_since_start << "\n" } else if (seconds_since_start >= 5.0 && seconds_since_start < 5.2) { @@ -825,6 +818,7 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat { // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; + controller.tvc.Stop(); valveControl.CloseValve(ValveControl::ASIEthanol); valveControl.CloseValve(ValveControl::MainEthanol); eigthPartDone = true; @@ -885,7 +879,6 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat ninthPartDone = false; tenthPartDone = false; eleventhPartDone = false; - controller.tvc.Stop(); return Mode::HotfireIdle; } } From 5bd8005ffb2ffefed4cdc0df39a4004244552205 Mon Sep 17 00:00:00 2001 From: Jack Bogatz Date: Wed, 6 May 2026 11:39:29 -0400 Subject: [PATCH 2/4] 3second test with tvc with after engine --- src/Mode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Mode.cpp b/src/Mode.cpp index 685d70f..ed3d0b6 100644 --- a/src/Mode.cpp +++ b/src/Mode.cpp @@ -809,7 +809,7 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat { // Uncomment for debugging controller.UpdateTestTVC(seconds_since_start); - std::cout << "Time: " << seconds_since_start << "\n" + std::cout << "Time: " << seconds_since_start << "\n"; } else if (seconds_since_start >= 5.0 && seconds_since_start < 5.2) { From 000744c6ff982640b0dc2ddfd1105e7eee11c148 Mon Sep 17 00:00:00 2001 From: Jack Bogatz Date: Wed, 6 May 2026 12:21:54 -0400 Subject: [PATCH 3/4] 9 --- include/MissionConstants.hpp | 4 ++-- src/Mode.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/MissionConstants.hpp b/include/MissionConstants.hpp index 826ea19..ff7c0f2 100644 --- a/include/MissionConstants.hpp +++ b/include/MissionConstants.hpp @@ -205,7 +205,7 @@ namespace MissionConstants const int kNitrogenLinePTPin = ADS1BASE + 0; // First ADS1115 A0 const int kEthanolTankPTPin = ADS1BASE + 1; // First ADS1115 A1 const int kNitrousTankLinePTPin = ADS1BASE + 2; // First ADS1115 A2 - const int kNitrousLinePTPin = ADS1BASE + 3; // First ADS1115 A2 + const int kNitrousLinePTPin = ADS3BASE + 0; // Third ADS1115 A0 // NOT USED AT THE MOMENT const int kOxygenLinePTPin = ADS2BASE + 2; // Second ADS1115 A2 @@ -213,7 +213,7 @@ namespace MissionConstants const int kFuelOutletPTPin = ADS3BASE + 0; // Third ADS1115 A0 // Load Cell Pin (Analog) - const int kLoadCellPin = ADS2BASE + 1; // Second ADS1115 A1 + const int kLoadCellPin = ADS1BASE + 3; // First ADS1115 A4 const int kChamberPressurePTPin = ADS2BASE + 0; // Second ADS1115 A0 // Valve Servo Angles diff --git a/src/Mode.cpp b/src/Mode.cpp index ed3d0b6..2cccdc3 100644 --- a/src/Mode.cpp +++ b/src/Mode.cpp @@ -727,7 +727,7 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat startTime = currentTime; Telemetry::GetInstance().Log("Starting 3 Second Hotfire sequence"); // Open purge valve - valveControl.OpenValve(ValveControl::Purge); + // valveControl.OpenValve(ValveControl::Purge); sequenceStarted = true; } @@ -742,7 +742,7 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; - valveControl.CloseValve(ValveControl::Purge); + // valveControl.CloseValve(ValveControl::Purge); valveControl.OpenValve(ValveControl::ASIOxygen); sparkPlug.TurnOn(); firstPartDone = true; From c5026af50c464471eab918fbc93e47e7f9ee5b4c Mon Sep 17 00:00:00 2001 From: Jack Bogatz Date: Wed, 6 May 2026 23:00:39 -0400 Subject: [PATCH 4/4] Mpre documentation --- Brewfile | 41 +++ LIQUID_PROPULSION_PORT.md | 548 ------------------------------- LIQUID_PROPULSION_QUICK_START.md | 87 ----- README.md | 70 +++- hardware/README.md | 32 ++ include/MissionConstants.hpp | 2 + k_matrix.csv | 21 -- src/Mode.cpp | 40 +-- src/README.md | 1 - 9 files changed, 149 insertions(+), 693 deletions(-) create mode 100644 Brewfile delete mode 100644 LIQUID_PROPULSION_PORT.md delete mode 100644 LIQUID_PROPULSION_QUICK_START.md delete mode 100644 k_matrix.csv diff --git a/Brewfile b/Brewfile new file mode 100644 index 0000000..f591bd9 --- /dev/null +++ b/Brewfile @@ -0,0 +1,41 @@ +tap "mongodb/brew" +brew "libtiff" +brew "webp" +brew "allegro" +brew "jpeg-xl" +brew "aom" +brew "python@3.12" +brew "azure-cli" +brew "eigen" +brew "gcc" +brew "suite-sparse" +brew "ceres-solver" +brew "hdf5" +brew "cmake" +brew "unbound" +brew "gnutls" +brew "leptonica" +brew "python@3.13" +brew "tesseract" +brew "ffmpeg" +brew "llvm" +brew "maven" +brew "mongodb-atlas-cli" +brew "ninja" +brew "numpy" +brew "qt" +brew "vtk" +brew "opencv" +brew "pandoc" +brew "pdfly" +brew "poppler" +brew "postgresql@16" +brew "qt@5" +brew "pyqt@5" +brew "python@3.11" +brew "screen" +brew "tmux" +brew "tree" +brew "zsh" +brew "mongodb/brew/mongodb-community@8.0" +cask "basictex" diff --git a/LIQUID_PROPULSION_PORT.md b/LIQUID_PROPULSION_PORT.md deleted file mode 100644 index ef4aaba..0000000 --- a/LIQUID_PROPULSION_PORT.md +++ /dev/null @@ -1,548 +0,0 @@ -# Liquid Propulsion Port Documentation - -## Overview - -This document describes the port of liquid propulsion functionality from the Arduino-based `hotfire.ino` codebase into the ferda solid propulsion codebase. The port maintains backwards compatibility with existing solid propulsion functionality while adding new states and hardware abstractions for liquid propulsion operations. - -## What Was Done - -### 1. Hardware Abstraction Layer - -Created four new hardware classes following the existing ferda pattern (hardware/hardware_simulation/hardware_test): - -#### ValveControl (`include/ValveControl.hpp`) -- Manages 7 valves: 4 servos (Nitrogen, Purge, Main Ethanol, Main Nitrous) and 3 solenoids (ASI Ethanol, ASI Oxygen, Nitrogen Bleed) -- Provides `OpenValve()` and `CloseValve()` methods with state tracking -- Handles different control logic for servos vs. solenoids (servos use PWM, solenoids use GPIO) -- **Files created:** - - `include/ValveControl.hpp` - - `hardware/ValveControl.cpp` (uses pigpio) - - `hardware_simulation/ValveControl.cpp` (simulation stubs) - - `hardware_test/ValveControl.cpp` (test stubs) - -#### SparkPlug (`include/SparkPlug.hpp`) -- Controls spark ignition system -- Manages relay control (GPIO) and PWM output for RPM signal -- **Files created:** - - `include/SparkPlug.hpp` - - `hardware/SparkPlug.cpp` - - `hardware_simulation/SparkPlug.cpp` - - `hardware_test/SparkPlug.cpp` - -#### PressureTransducer (`include/PressureTransducer.hpp`) -- Reads 7 pressure transducers with different ranges: - - High-pressure sensors (0-1000 PSI): Nitrogen Line, Ethanol Tank, Nitrous Line, Fuel Inlet, Fuel Outlet, Chamber Pressure - - Low-pressure sensor (0-200 PSI): Oxygen Line -- Provides `ReadPSI()` and `ReadPSI2()` methods matching original Arduino API -- **Files created:** - - `include/PressureTransducer.hpp` - - `hardware/PressureTransducer.cpp` (⚠️ **ADC reading not implemented - see "What Still Needs to be Done"**) - - `hardware_simulation/PressureTransducer.cpp` - - `hardware_test/PressureTransducer.cpp` - -#### LoadCell (`include/LoadCell.hpp`) -- Reads load cell sensor for thrust measurement -- Converts to pounds (lbs) matching original implementation -- **Files created:** - - `include/LoadCell.hpp` - - `hardware/LoadCell.cpp` (⚠️ **ADC reading not implemented - see "What Still Needs to be Done"**) - - `hardware_simulation/LoadCell.cpp` - - `hardware_test/LoadCell.cpp` - -### 2. Configuration - -#### MissionConstants.hpp Updates -Added pin configuration constants for all liquid propulsion hardware: -- Servo pins: `kNitrogenServoPin`, `kPurgeServoPin`, `kMainEthanolServoPin`, `kMainNitrousServoPin` -- Solenoid pins: `kASIEthanolPin`, `kASIOxygenPin`, `kNitrogenBleedPin` -- Spark pins: `kSparkPin`, `kRPMPin` -- PT sensor pins: `kNitrogenLinePTPin`, `kEthanolTankPTPin`, `kNitrousLinePTPin`, `kOxygenLinePTPin`, `kFuelInletPTPin`, `kFuelOutletPTPin`, `kChamberPressurePTPin` -- Load cell pin: `kLoadCellPin` -- Valve angles: `kValveClosedAngle` (179°), `kValveOpenAngle` (91°) - -**⚠️ IMPORTANT:** All pin numbers are currently set to `0` as placeholders. These must be updated with actual hardware pin assignments before use. - -### 3. State Machine Extensions - -#### New States Added to `Mode::Phase` enum: -- `HotfireIdle` - Waiting state for liquid propulsion operations, handles valve/spark commands -- `ASITest` - Executes ASI test sequence (matches original timing: 300ms oxygen+spark, 2s ethanol, then shutdown) -- `WaterFlow` - Executes water flow test sequence (matches original timing: 2s nitrous, 3s ethanol, then shutdown) - -#### State Implementation (`src/Mode.cpp`) -- `UpdateHotfireIdle()` - Handles all valve and spark commands via RF, can transition to test sequences -- `UpdateASITest()` - Implements ASI test sequence with proper timing -- `UpdateWaterFlow()` - Implements water flow sequence with proper timing -- All sequences include abort handling and proper cleanup - -### 4. RF Command System - -Extended `RF::Command` enum with liquid propulsion commands: -- Valve commands: `ValveNitrogenOpen/Close`, `ValvePurgeOpen/Close`, `ValveMainEthanolOpen/Close`, `ValveMainNitrousOpen/Close`, `ValveASIEthanolOpen/Close`, `ValveASIOxygenOpen/Close`, `ValveNitrogenBleedOpen/Close` -- Spark commands: `SparkOn`, `SparkOff` -- Sequence commands: `ASITest`, `WaterFlow` -- State transition: `HotfireIdle` - -**Command String Format:** Maintains compatibility with original Arduino code: -- `"VALVE: nitrogen open"` → `ValveNitrogenOpen` -- `"SPARK: on"` → `SparkOn` -- `"asitest"` → `ASITest` -- `"waterflow"` → `WaterFlow` - -### 5. Telemetry Integration - -#### New Telemetry Method (`src/Telemetry.cpp`) -- `RfSendLiquidPropulsionData()` - Sends PT and load cell data in JSON format -- Data structure matches original binary packet (8 float values) -- Automatically called during liquid propulsion states at ~10ms intervals - -#### Telemetry Data Format: -```json -{ - "data_type": "liquid_telem", - "payload": [ - nitrogen_line_psi, // 0-1000 PSI - ethanol_tank_psi, // 0-1000 PSI - nitrous_line_psi, // 0-1000 PSI - oxygen_line_psi, // 0-200 PSI - fuel_inlet_psi, // 0-1000 PSI - fuel_outlet_psi, // 0-1000 PSI - chamber_pressure_psi, // 0-1000 PSI - load_cell_lbs // Thrust in pounds - ] -} -``` - -### 6. Main Program Integration - -#### Hardware Initialization (`src/Main.cpp`) -- Creates instances of all liquid propulsion hardware classes -- Initializes hardware via `Mode::SetLiquidPropulsionHardware()` -- GPIO pin setup for all servos, solenoids, and spark control -- Servos initialized to closed position (179°) -- Solenoids initialized to closed state (HIGH for normally-closed, LOW for normally-open) -- Spark initialized to OFF state - -## Architecture Decisions - -### 1. Hardware Abstraction Pattern -**Decision:** Followed existing ferda pattern with separate implementations for hardware/simulation/test. - -**Rationale:** -- Maintains consistency with existing codebase -- Enables testing without hardware -- Supports software-in-the-loop simulation - -**Implementation:** -- All hardware classes have three implementations matching existing pattern -- Simulation and test versions provide stubs/logging - -### 2. Optional Hardware Initialization -**Decision:** Liquid propulsion hardware is optional and only initialized in `Main.cpp`, passed to `Mode` via setter method. - -**Rationale:** -- Maintains backwards compatibility with solid propulsion -- Hardware only used when in liquid propulsion states -- Allows code to compile and run for solid propulsion missions - -**Implementation:** -- `Mode` class stores hardware as optional pointers (default to `nullptr`) -- `SetLiquidPropulsionHardware()` method sets hardware instances -- All hardware access checks for `nullptr` before use - -### 3. State-Based Command Handling -**Decision:** Valve and spark commands are handled within `HotfireIdle` state rather than globally. - -**Rationale:** -- Commands are context-specific to liquid propulsion operations -- Keeps command handling organized and state-aware -- Prevents accidental valve operations during solid propulsion - -**Implementation:** -- Commands processed in `UpdateHotfireIdle()` -- Commands ignored in other states (safe default) - -### 4. Timing Preservation -**Decision:** Maintained exact timing from original `hotfire.ino` sequences. - -**Rationale:** -- Original sequences were tested and validated -- Timing is critical for safe hotfire operations -- Reduces risk of introducing timing bugs - -**Implementation:** -- ASITest: 300ms delay before ethanol, 2000ms ethanol duration, 300ms shutdown delay -- WaterFlow: 2000ms nitrous, 3000ms ethanol, then shutdown -- Uses `currentTime` tracking with static start times - -### 5. Command String Compatibility -**Decision:** Maintained original command string format from Arduino code. - -**Rationale:** -- Ground control software may already use these strings -- Reduces need for ground control updates -- Maintains operational familiarity - -## Challenges and Solutions - -### Challenge 1: Arduino to Raspberry Pi Hardware Differences - -**Problem:** -- Original code used Arduino `Servo.h` library and `analogRead()` -- Raspberry Pi doesn't have native analog inputs or Arduino servo library -- Need to use pigpio for GPIO/servo control and external ADC for analog reading - -**Solution:** -- **Servos:** Used `gpioServo()` from pigpio which takes pulse width in microseconds (1000-2000μs for 0-180°) - - Conversion: `pulseWidth = 1000 + (angle * 1000 / 180)` -- **Solenoids:** Used `gpioWrite()` for digital control (matching original HIGH/LOW logic) -- **ADC:** Created placeholder functions with TODO comments - actual ADC implementation needed (see "What Still Needs to be Done") - -**Files Affected:** -- `hardware/ValveControl.cpp` - Servo control conversion -- `hardware/SparkPlug.cpp` - PWM control using `gpioPWM()` -- `hardware/PressureTransducer.cpp` - ADC placeholder -- `hardware/LoadCell.cpp` - ADC placeholder - -### Challenge 2: State Machine Integration - -**Problem:** -- Original code was a simple `loop()` with command checking -- Ferda uses a state machine pattern -- Need to integrate liquid propulsion operations without breaking existing states - -**Solution:** -- Created new states specifically for liquid propulsion -- Made hardware optional (pointers default to `nullptr`) -- State transitions only occur from appropriate states (e.g., `Idle` → `HotfireIdle`) -- All existing solid propulsion states remain unchanged - -**Files Affected:** -- `include/Mode.hpp` - Added new states and hardware pointers -- `src/Mode.cpp` - Implemented new state update functions -- `src/Main.cpp` - Hardware initialization - -### Challenge 3: Telemetry Data Format - -**Problem:** -- Original code sent binary packets with header/footer -- Ferda uses JSON for telemetry -- Need to maintain data compatibility while using JSON format - -**Solution:** -- Created separate telemetry method `RfSendLiquidPropulsionData()` -- Sends JSON with same data structure (8 float values) -- Maintains same sensor order and units as original -- Can be extended to send binary format if needed - -**Files Affected:** -- `include/Telemetry.hpp` - Added new method declaration -- `src/Telemetry.cpp` - Implemented JSON telemetry method -- `src/Mode.cpp` - Calls telemetry method during liquid states - -### Challenge 4: Pin Configuration Management - -**Problem:** -- Original code had pin numbers scattered throughout -- Need centralized configuration for maintainability -- Pin numbers need to be easily changeable - -**Solution:** -- Added all pin constants to `MissionConstants.hpp` -- All hardware classes reference constants instead of hardcoded values -- Single location for pin configuration -- Currently set to `0` as placeholders with clear documentation - -**Files Affected:** -- `include/MissionConstants.hpp` - Added all pin constants -- All hardware implementation files - Use constants - -### Challenge 5: Servo Angle Logic - -**Problem:** -- Original code used `Servo.write(angle)` where angle is in degrees -- pigpio `gpioServo()` uses pulse width in microseconds -- Need to convert correctly - -**Solution:** -- Standard servo pulse width: 1000μs (0°) to 2000μs (180°) -- Formula: `pulseWidth = 1000 + (angle * 1000 / 180)` -- Verified against existing TVC servo implementation in codebase -- Maintained original angles: 91° (open) and 179° (closed) - -**Files Affected:** -- `hardware/ValveControl.cpp` - Servo control implementation - -## What Still Needs to be Done - -### 1. ADC Hardware Implementation ⚠️ **CRITICAL** - -**Status:** Placeholder code exists, actual ADC reading not implemented - -**Files Requiring Implementation:** -- `hardware/PressureTransducer.cpp` - `ReadSensor()` method (line ~16) -- `hardware/LoadCell.cpp` - `ReadSensor()` method (line ~8) - -**What's Needed:** -The original Arduino code used `analogRead(pin)` which reads 0-1023 (10-bit ADC). Raspberry Pi doesn't have native analog inputs, so you'll need: - -1. **External ADC Hardware:** - - Common options: MCP3008 (SPI), ADS1115 (I2C), or similar - - Determine which ADC you're using and how it's connected - -2. **ADC Reading Implementation:** - - Replace the placeholder `uint16_t rawVal = 0;` with actual ADC reading - - Example for MCP3008 via SPI: - ```cpp - // Pseudo-code - implement based on your ADC - uint16_t rawVal = readADC(pin); // Read from SPI/I2C ADC - ``` - -3. **Voltage Conversion:** - - The existing code correctly converts raw ADC value to voltage: - ```cpp - float rawVolt = (float)rawVal / 204.6; // 1023 / 5.0 = 204.6 - ``` - - This assumes 10-bit ADC (0-1023) mapping to 0-5V - - Adjust if using different ADC resolution - -4. **Pin Mapping:** - - Map `MissionConstants` pin numbers to actual ADC channels - - Update pin constants in `MissionConstants.hpp` with ADC channel numbers - -**Testing:** -- Verify ADC readings match expected voltage ranges -- Calibrate sensor readings against known pressures/forces -- Test all 7 PT sensors and load cell - -### 2. Pin Number Configuration ⚠️ **REQUIRED** - -**Status:** All pins set to `0` as placeholders - -**File:** `include/MissionConstants.hpp` - -**What's Needed:** -Update all pin constants with actual hardware assignments: - -```cpp -// Example - replace with your actual pin numbers -const int kNitrogenServoPin = 6; // GPIO pin for nitrogen servo -const int kPurgeServoPin = 13; // GPIO pin for purge servo -// ... etc for all pins -``` - -**Considerations:** -- GPIO pins on Raspberry Pi (BCM numbering) -- ADC channel numbers (if using external ADC) -- Ensure no pin conflicts with existing solid propulsion hardware -- Document pin assignments for future reference - -### 3. Servo Calibration (If Needed) - -**Status:** Using original angles (91° open, 179° closed) - -**What's Needed:** -- Verify servo angles match your hardware -- Some servos may need calibration/adjustment -- Test valve open/close positions -- Adjust `kValveOpenAngle` and `kValveClosedAngle` if needed - -**Files:** -- `include/MissionConstants.hpp` - Valve angle constants -- `hardware/ValveControl.cpp` - Servo control - -### 4. Solenoid Logic Verification - -**Status:** Implemented based on original code comments - -**What's Needed:** -- Verify solenoid logic matches your hardware -- Original code had comments like "want to flip these" - verify actual behavior -- Test normally-open vs normally-closed valve behavior -- Confirm HIGH/LOW logic for each solenoid type - -**Files:** -- `hardware/ValveControl.cpp` - Solenoid control (lines ~50-70) - -### 5. Integration Testing - -**Status:** Code compiles, but not tested on hardware - -**What's Needed:** -1. **Unit Testing:** - - Test each hardware class individually - - Verify valve open/close operations - - Test spark control - - Verify sensor reading (once ADC implemented) - -2. **State Machine Testing:** - - Test state transitions (Idle → HotfireIdle → ASITest/WaterFlow) - - Verify command handling in HotfireIdle - - Test abort functionality - -3. **Sequence Testing:** - - Test ASITest sequence timing - - Test WaterFlow sequence timing - - Verify proper valve sequencing - - Test abort during sequences - -4. **Telemetry Testing:** - - Verify sensor data transmission - - Check data format matches ground control expectations - - Test telemetry rate/performance - -5. **End-to-End Testing:** - - Full hotfire sequence with actual hardware - - Verify all valves operate correctly - - Verify sensor readings are accurate - - Test ground control communication - -### 6. Documentation Updates - -**Status:** This document created, but may need updates - -**What's Needed:** -- Update main README.md if liquid propulsion becomes standard -- Document pin assignments in a hardware configuration file -- Create operator's manual for liquid propulsion states -- Document any deviations from original hotfire.ino behavior - -## Usage Guide - -### Entering Liquid Propulsion Mode - -1. **Start in Idle State:** - - System starts in `Calibration` state - - Transition to `Idle` via `Idle` command - -2. **Enter HotfireIdle:** - - Send RF command: `"HotfireIdle"` - - System transitions to `HotfireIdle` state - - Hardware is now ready for liquid propulsion operations - -### Manual Valve Control - -While in `HotfireIdle`, send commands via RF: -- `"VALVE: nitrogen open"` / `"VALVE: nitrogen close"` -- `"VALVE: purge open"` / `"VALVE: purge close"` -- `"VALVE: main ethanol open"` / `"VALVE: main ethanol close"` -- `"VALVE: main nitrous open"` / `"VALVE: main nitrous close"` -- `"VALVE: ASI ethanol open"` / `"VALVE: ASI ethanol close"` -- `"VALVE: ASI oxygen open"` / `"VALVE: ASI oxygen close"` -- `"VALVE: nitrogen bleed open"` / `"VALVE: nitrogen bleed close"` - -### Spark Control - -While in `HotfireIdle`: -- `"SPARK: on"` - Turns on spark ignition -- `"SPARK: off"` - Turns off spark ignition - -### Running Test Sequences - -While in `HotfireIdle`: -- `"asitest"` - Runs ASI test sequence (automated) -- `"waterflow"` - Runs water flow sequence (automated) - -Sequences automatically return to `HotfireIdle` when complete. - -### Abort - -At any time, send `"ABORT"` command to immediately exit (closes all valves, turns off spark). - -### Returning to Solid Propulsion - -From `HotfireIdle`, send `"Idle"` to return to `Idle` state (solid propulsion mode). - -## Code Structure Reference - -### New Files Created - -``` -include/ - ├── ValveControl.hpp - ├── SparkPlug.hpp - ├── PressureTransducer.hpp - └── LoadCell.hpp - -hardware/ - ├── ValveControl.cpp - ├── SparkPlug.cpp - ├── PressureTransducer.cpp - └── LoadCell.cpp - -hardware_simulation/ - ├── ValveControl.cpp - ├── SparkPlug.cpp - ├── PressureTransducer.cpp - └── LoadCell.cpp - -hardware_test/ - ├── ValveControl.cpp - ├── SparkPlug.cpp - ├── PressureTransducer.cpp - └── LoadCell.cpp -``` - -### Modified Files - -``` -include/ - ├── Mode.hpp - Added new states, hardware pointers - ├── RF.hpp - Added new commands - ├── Telemetry.hpp - Added liquid propulsion telemetry - └── MissionConstants.hpp - Added pin constants - -src/ - ├── Mode.cpp - Implemented new states - ├── Telemetry.cpp - Added telemetry method - └── Main.cpp - Hardware initialization -``` - -## Known Limitations - -1. **ADC Not Implemented:** Pressure transducers and load cell won't read actual values until ADC code is added -2. **Pin Numbers Placeholder:** All pins set to 0 - must be configured before use -3. **No Error Handling:** ADC failures or hardware errors not currently handled -4. **Telemetry Format:** Uses JSON instead of original binary format (can be changed if needed) -5. **No Calibration:** Sensor calibration not implemented (may need offset/gain adjustments) - -## Future Enhancements (Optional) - -1. **Sensor Calibration:** Add calibration routines for PT sensors and load cell -2. **Error Handling:** Add robust error handling for hardware failures -3. **Safety Interlocks:** Add safety checks (e.g., prevent certain valve combinations) -4. **Data Logging:** Enhanced logging of valve operations and sensor data -5. **Binary Telemetry:** Option to send binary format matching original -6. **State Persistence:** Save/restore valve states across power cycles -7. **Advanced Sequences:** Additional pre-programmed sequences beyond ASITest/WaterFlow - -## Contact and Support - -For questions about this port: -- Review this documentation first -- Check code comments in implementation files -- Refer to original `hotfire.ino` for behavioral reference -- Test in simulation/test mode before hardware deployment - -## Appendix: Original Code Mapping - -| Original (hotfire.ino) | New (ferda) | Notes | -|------------------------|-------------|-------| -| `Servo NitrogenServo` | `ValveControl::Nitrogen` | Servo control via pigpio | -| `digitalWrite(asiEthanolPin, LOW)` | `ValveControl::OpenValve(ASIEthanol)` | Solenoid control | -| `analogRead(pin)` | `PressureTransducer::ReadSensor()` | ⚠️ Needs ADC implementation | -| `ReadSensor()` | `PressureTransducer::ReadPSI()` | 0-200 PSI range | -| `ReadSensor2()` | `PressureTransducer::ReadPSI2()` | 0-1000 PSI range | -| `ReadLoadCell()` | `LoadCell::ReadLBS()` | Thrust in pounds | -| `loop()` commands | `Mode::UpdateHotfireIdle()` | State-based handling | -| `asiTest()` | `Mode::UpdateASITest()` | Sequence state | -| `waterFlow()` | `Mode::UpdateWaterFlow()` | Sequence state | -| `SendData()` | `Telemetry::RfSendLiquidPropulsionData()` | JSON format | - ---- - -**Document Version:** 1.2 -**Last Updated:** 12/10/2025 -**Author:** Port implementation and documentation organized by Benjamin Deutsch -**Reviewed By:** Kemuel Bermudez-Cotto - diff --git a/LIQUID_PROPULSION_QUICK_START.md b/LIQUID_PROPULSION_QUICK_START.md deleted file mode 100644 index 20ab83f..0000000 --- a/LIQUID_PROPULSION_QUICK_START.md +++ /dev/null @@ -1,87 +0,0 @@ -# Liquid Propulsion Quick Start Guide - -## Quick Reference - -### State Transitions -``` -Calibration → (Idle) → Idle → (HotfireIdle) → HotfireIdle - ↓ - (asitest) → ASITest → HotfireIdle - (waterflow) → WaterFlow → HotfireIdle -``` - -### Essential Commands - -**State Control:** -- `"HotfireIdle"` - Enter liquid propulsion mode -- `"Idle"` - Return to solid propulsion mode -- `"ABORT"` - Emergency stop (closes all valves, turns off spark) - -**Valve Control (while in HotfireIdle):** -- `"VALVE: [valve name] open"` / `"VALVE: [valve name] close"` - - Available valves: `nitrogen`, `purge`, `main ethanol`, `main nitrous`, `ASI ethanol`, `ASI oxygen`, `nitrogen bleed` - -**Spark Control:** -- `"SPARK: on"` / `"SPARK: off"` - -**Test Sequences:** -- `"asitest"` - ASI test sequence -- `"waterflow"` - Water flow sequence - -## Before First Use - -### 1. Configure Pin Numbers -Edit `include/MissionConstants.hpp` and set all pin constants: -```cpp -const int kNitrogenServoPin = 6; // Your actual GPIO pin -// ... set all other pins -``` - -### 2. Implement ADC Reading -Edit `hardware/PressureTransducer.cpp` and `hardware/LoadCell.cpp`: -- Replace `uint16_t rawVal = 0;` with actual ADC reading code -- See `LIQUID_PROPULSION_PORT.md` for details - -### 3. Test Hardware -1. Build in Debug mode: `cmake -Bbuild -DCMAKE_BUILD_TYPE=Debug .` -2. Test valve operations individually -3. Verify sensor readings (after ADC implementation) - -## Typical Operation Flow - -1. **Startup:** System begins in `Calibration` state -2. **Go to Idle:** Send `"Idle"` command -3. **Enter Liquid Mode:** Send `"GoHotfireIdle"` command -4. **Manual Control:** Send valve/spark commands as needed -5. **Or Run Sequence:** Send `"asitest"` or `"waterflow"` -6. **Return to Idle:** Send `"Idle"` when done - -## Troubleshooting - -**Valves not responding:** -- Check pin numbers in `MissionConstants.hpp` -- Verify GPIO initialization in `Main.cpp` -- Check hardware connections - -**Sensors reading zero:** -- ADC implementation required (see "What Still Needs to be Done" in main doc) -- Verify ADC hardware connections -- Check pin assignments - -**Commands not working:** -- Must be in `HotfireIdle` state for valve/spark commands -- Check RF communication -- Verify command string format (case-sensitive) - -## File Locations - -- **Main Documentation:** `LIQUID_PROPULSION_PORT.md` -- **Pin Configuration:** `include/MissionConstants.hpp` -- **Hardware Classes:** `include/*.hpp` and `hardware/*.cpp` -- **State Logic:** `src/Mode.cpp` -- **Command Parsing:** `include/RF.hpp` and `hardware/RF.cpp` - -## Need More Details? - -See `LIQUID_PROPULSION_PORT.md` for comprehensive documentation. - diff --git a/README.md b/README.md index d601582..14f3ce0 100644 --- a/README.md +++ b/README.md @@ -6,20 +6,13 @@ All source code utilizes [Hungarian Notation](https://www.cse.iitk.ac.in/users/d Create features in branches originating from the `dev` branch. When a feature is complete, make a pull request to merge it into `dev`. -## Liquid Propulsion Support - -This codebase now supports both solid and liquid propulsion systems. For detailed documentation on the liquid propulsion port, see: - -- **[Liquid Propulsion Port Documentation](LIQUID_PROPULSION_PORT.md)** - Comprehensive guide covering architecture, implementation, and remaining work -- **[Liquid Propulsion Quick Start](LIQUID_PROPULSION_QUICK_START.md)** - Quick reference for operators - ## Table of Contents 1. [How to Run](#how-to-run) - [How to Run On Linux (Raspberry Pi)](#how-to-run-on-linux-raspberry-pi) - - [How to Run On Mac](#how-to-run-Mac) - - [How to Run On Windows](#how-to-run-Windows) + - [How to Run On Mac](#how-to-run-on-mac) + - [How to Run On Windows](#how-to-run-on-windows) 2. [Building the Source Code](#building-the-source-code) 3. [Hardware Configuration](#hardware-configuration) - [Xbee Port Setup](#xbee-port-setup) @@ -50,9 +43,16 @@ This codebase now supports both solid and liquid propulsion systems. For detaile 13. Run `sudo cmake --workflow --preset install` 14. Build the repo (ensure you're in either debug, simulation, or release mode depending on your need). 15. Create a logs folder inside repo directory with `mkdir logs` -15. Run the executable that gets created in the `build/` folder. (NOTE: If working with GPS, build gps_setup.sh) +16. Run the executable that gets created in the `build/` folder. (NOTE: If working with GPS, run gps_setup.sh first) ### How to Run on Mac +1. Clone this repo +2. Install the CMake Tools extension on VS Code. +3. Install brew with `/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"` +5. Run `brew bundle` +4. Build the repo (ensure you're in either debug, simulation, or release mode depending on your need). +5. Create a logs folder inside repo directory with `mkdir logs` +6. Run the executable that gets created in the `build/` folder. (NOTE: If working with GPS, run gps_setup.sh first) ### How to Run on Windows @@ -370,18 +370,35 @@ Notes: The flight software should be connected with the Simulink simulation, sending actuator commands and receiving simulated sensor data. # Design +We have separated all of our header files in the `include` directory, all non-hardware files into `src` firectory and all hardware files into the `hardware` directory. Now depending on the build type that you used, we either use `hardware` if built in `Release` mode, `hardware_test` if built in `Debug` Mode, or `hardware_simulation` if built in `Simulation` mode. + +README'S for `Src` and `Hardware` files are located in [Src files README](Src/README.md) and [Hardware files README](hardware/README.md) + +If you add a new sensor, it belongs in the 3 hardware directories + +All config files listed below are in the ferda directory but should at somepoint be in a Config folder + - Angles.csv + - Height.csv + - Translation.csv + - linux_library_requirements.txt + - Brewfile + +We do have a `tests` folder but it has not been touched in a while. If you generate any unit tests, it should go here ## Flow 1. Look for command through RF.cpp -2. Change mode based on command +2. Change mode based on command ## Architecture -We use the **State machine pattern** where we have defined several modes/states and one while loop in main +We use the **State machine pattern** where we have defined several modes/states and one while loop in main. We use RF +to change modes but modes can also change based on a condition in the code as well. +In Mode.hpp, we define the Modes: ``` enum Phase { + Standby, Calibration, ActuatorCalibration, TestTVC, @@ -390,6 +407,7 @@ enum Phase Launch, Land, Terminate, + Abort, Safe, HotfireIdle, ASITest, @@ -397,8 +415,34 @@ enum Phase ThreeSecondHotfire }; ``` + +In RF.hpp, a subset of the commands look like below where Command is an enum where we add the RF command +``` + if (input_line == "ABORT") + ParsedCommand = RF::Command::ABORT; + else if (input_line == "ABORT_PAD") + ParsedCommand = RF::Command::ABORT_PAD; + else if (input_line == "ABORT_GROUND") + ParsedCommand = RF::Command::ABORT_GROUND; + else if (input_line == "TestTVC") + ParsedCommand = RF::Command::TestTVC; + else if (input_line == "ChirpTVC") + ParsedCommand = RF::Command::ChirpTVC; + else if (input_line == "Idle") + ParsedCommand = RF::Command::Idle; + else if (input_line == "Standby") + ParsedCommand = RF::Command::Standby; +``` + + +In Main.cpp, the while loop looks like: ``` while (mode.Update(navigation, controller, gps, igniter, imu, magnetometer, valveControl, sparkPlug, pressureTransducer, loadCell, camera)) { } -``` \ No newline at end of file +``` + +We either exit out of the while loop when the Mode is `Terminate` which returns false from `Update()` or if we hit `Abort`, before we ignite, then we exit the program right then and there + +## Ground Control Communication +So, this is the Flight Software that runs on the Raspberry Pi but like I've mentioned in [Flow](#flow), the flight software is expecting to see commands through the radio which is where Ground Control comes in. All Ground Control is found in [Ground Control Github Link](https://github.com/UConn-Rocketry/ground-control). So to actually communicate with the rocket, we use ground control and the xbees \ No newline at end of file diff --git a/hardware/README.md b/hardware/README.md index 4ba4761..b9671ee 100644 --- a/hardware/README.md +++ b/hardware/README.md @@ -54,6 +54,10 @@ Tips: 6. ADS1115 -> `0x4A` (ADDR is connected to SDA) Notes: +The Xbees are configured using XCTU software/ When configuring them, the Ground Control Xbee should to be the Coordinator +and the Flight Computer Xbee should be the End Device. The Coordinator is responsibe for setting up the network. We also set the baud rate of both of them to 38400. Also, to send data back and forth, the Channel and the Pan ID have to match. +Whenever you change the settings, you need to click on `Write`. + The ADS1115 are our analog-to-digital-converters because the Pi doesn't have any Analog pins and they are used to measure all of our Pressure Transducers We use `wiringPi's` `ads1115.c` custom library so we did not have to make our own and we initalize all our ads "variables" but they are not really variables with `ads1115setup()` in `Main.cpp` @@ -188,6 +192,34 @@ As of May 5th, 2026, the laod cell readings were not good normalize it, and then mulitply by that pressure's max PSI value to convert it to a Pressure value ### RF.cpp +We are currentely using 2 XBee ZB S2C series which should have an outdoor line-of-sight range of 4000ft. [XBee ZB S2C](https://www.digi.com/support/knowledge-base/the-major-differences-in-the-xbee-series-1-vs-the). + +In the constructor, we first check to see if the Xbee is connected and if it not, then we just use the terminal to send commands like how we would for user input. However, if the Xbee is connected, then we set some serial settings with the most important one being the baud rate to 38400 to match what the other Xbee on Ground Control should be. + +There are 3 methods at play here: +`ParseCommand()` which is defined in `RF.hpp` +`SendString()` +`GetCommand()` + +`ParseCommand()` takes in a string and sees if any of the commands the user typed in Ground Control matches any already defined and if so returns that specified command + +`SendString()` is only used in the XBEE is connected and it makes sure it writes the entire message to the other Xbee + +`GetCommand()` reads the sent by Ground Control XBEE and waits until it sees a newline because that signified the end of a message and when that happens, we call `ParseCommand()` to see if it is a valid command. If the Xbee is not connected, we constantly look to see if the user inputed a command in the terminal + +## How to add a New command +1. Go To RF.hpp and add the name of the command in the Command enum +2. In `ParseCommand()`, add another else if statement where if the user entered the command, then we set `ParsedCommand` to that command enum value + +IMPORTANT: +As of May 6th, 2026, in Ground Control, when we are parsing the json payload sometimes we get a parsing error like +``` +Received: Unexpected serial parsing error (Expected 9 engine values or 30 GNC values, got 15): {'data_type': 'telem', 'payload': [9.49, 0.0, 0.0, 0.35, 147.29, 755.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'type': 'GNC'} time: 125.23 +Received: Unexpected serial parsing error (Expected 9 engine values or 30 GNC values, got 24): {'data_type': 'telem', 'payload': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.43, 12.82, 4.14, 124.34], 'type': 'Liquid'} time: 190.24 +``` +I think this is because of how the XBees are sending data because currentely they are in AT mode which is Transparent mode +which does not have any structure. Please investigate further + ### SparkPlug.cpp `Sparkplug` is split into 3 methods `TurnOn()`, `TurnOff()`, and `IsOn()` diff --git a/include/MissionConstants.hpp b/include/MissionConstants.hpp index ff7c0f2..bb77268 100644 --- a/include/MissionConstants.hpp +++ b/include/MissionConstants.hpp @@ -212,6 +212,8 @@ namespace MissionConstants const int kFuelInletPTPin = ADS2BASE + 3; // Second ADS1115 A3 const int kFuelOutletPTPin = ADS3BASE + 0; // Third ADS1115 A0 + // IMPORANT: ON Test Stand, The sceond ADS1115 A1 pin is fried + // Load Cell Pin (Analog) const int kLoadCellPin = ADS1BASE + 3; // First ADS1115 A4 const int kChamberPressurePTPin = ADS2BASE + 0; // Second ADS1115 A0 diff --git a/k_matrix.csv b/k_matrix.csv deleted file mode 100644 index 5275e60..0000000 --- a/k_matrix.csv +++ /dev/null @@ -1,21 +0,0 @@ -0,0.025,0.0575,0.265,0.59,0.8575,1.045,1.1475,1.3425,1.9175 -0,-0.077624,0.002842,0,0.495449,0,0.137398,0,0,0 -0.077636,0,-0,0.002842,-0,0.493601,-0,0.136352,0,0 --0,-0.078029,0.001283,0,0.664818,-0,0.112972,-0,0,0 -0.078037,0,0,0.001283,0,0.662364,0,0.112128,0,0 -0,-0.078098,0.001022,0,0.724734,0,0.107133,0,0,0 -0.078105,0,0,0.001022,-0,0.722076,-0,0.106339,0,0 -0,-0.078131,0.000898,0,0.76141,-0,0.104028,0,0,0 -0.078137,0,-0,0.000898,-0,0.758629,0,0.103261,0,0 --0,-0.07811,0.000977,-0,0.737266,0,0.106036,-0,0,0 -0.078116,0,0,0.000977,0,0.734566,0,0.105251,0,0 -0,-0.078088,0.001059,-0,0.714815,-0,0.108029,-0,0,0 -0.078095,-0,-0,0.001059,0,0.712191,0,0.107228,0,0 -0,-0.078052,0.001196,-0,0.682826,-0,0.111105,-0,0,0 -0.078059,0,-0,0.001196,-0,0.68031,-0,0.110277,0,0 --0,-0.078015,0.001336,0,0.654848,-0,0.114051,-0,0,0 -0.078023,0,0,0.001336,-0,0.652428,-0,0.113198,0,0 -0,-0.077806,0.00215,-0,0.548705,0,0.128051,0,0,0 -0.077817,0,-0,0.00215,0,0.546662,0,0.127081,0,0 -0,-0.071858,0.015257,-0,0.272964,-0,0.218387,0,0,0 -0.071904,-0,0,0.015252,0,0.272026,0,0.21676,0,0 diff --git a/src/Mode.cpp b/src/Mode.cpp index 2cccdc3..72cccb8 100644 --- a/src/Mode.cpp +++ b/src/Mode.cpp @@ -716,24 +716,18 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat static bool seventhPartDone = false; static bool eigthPartDone = false; static bool ninthPartDone = false; - static bool tenthPartDone = false; - static bool eleventhPartDone = false; - /* - - */ if (!sequenceStarted) { startTime = currentTime; Telemetry::GetInstance().Log("Starting 3 Second Hotfire sequence"); - // Open purge valve - // valveControl.OpenValve(ValveControl::Purge); sequenceStarted = true; } double seconds_since_start = currentTime - startTime; navigation.UpdateNavigation(); - // Sequence timing (matching original hotfire.ino logic) + + // Sequence timing if (seconds_since_start >= 0.5 && seconds_since_start < 0.8) { // Close Purge valve and turn on asi oxygen and spark plug on @@ -742,7 +736,6 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; - // valveControl.CloseValve(ValveControl::Purge); valveControl.OpenValve(ValveControl::ASIOxygen); sparkPlug.TurnOn(); firstPartDone = true; @@ -787,11 +780,12 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat else if (seconds_since_start >= 2.0 && seconds_since_start < 3.0) { - // Turn off spark plug and asi oxygen + // Turn off spark plug, asi oxygen, and start moving TVC if (!fifthPartDone) { // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; + sparkPlug.TurnOff(); valveControl.CloseValve(ValveControl::ASIOxygen); fifthPartDone = true; @@ -801,65 +795,67 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat else if (seconds_since_start >= 3.0 && seconds_since_start < 4.0) { // Uncomment for debugging - controller.UpdateTestTVC(seconds_since_start); std::cout << "Time: " << seconds_since_start << "\n"; + + controller.UpdateTestTVC(seconds_since_start); } else if (seconds_since_start >= 4.0 && seconds_since_start < 5.0) { // Uncomment for debugging - controller.UpdateTestTVC(seconds_since_start); std::cout << "Time: " << seconds_since_start << "\n"; + + controller.UpdateTestTVC(seconds_since_start); } else if (seconds_since_start >= 5.0 && seconds_since_start < 5.2) { - // Turn off spark plug and asi oxygen - if (!eigthPartDone) + // Turn off TVC, spark plug, asi oxygen, and Main Ethanol + if (!sixthPartDone) { // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; controller.tvc.Stop(); valveControl.CloseValve(ValveControl::ASIEthanol); valveControl.CloseValve(ValveControl::MainEthanol); - eigthPartDone = true; + sixthPartDone = true; } } else if (seconds_since_start >= 5.2 && seconds_since_start < 5.7) { // Turn off Main nitrous - if (!ninthPartDone) + if (!seventhPartDone) { // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; valveControl.CloseValve(ValveControl::MainNitrous); - ninthPartDone = true; + seventhPartDone = true; } } else if (seconds_since_start >= 5.7 && seconds_since_start < 7.2) { // Open purge - if (!tenthPartDone) + if (!eigthPartDone) { // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; // Open purge valveControl.OpenValve(ValveControl::Purge); - tenthPartDone = true; + eigthPartDone = true; } } else if (seconds_since_start >= 7.2) { // Close purge - if (!eleventhPartDone) + if (!ninthPartDone) { // Uncomment for debugging std::cout << "Time: " << seconds_since_start << "\n"; // Close purge valveControl.CloseValve(ValveControl::Purge); - eleventhPartDone = true; + ninthPartDone = true; } if (seconds_since_start >= 7.5) { @@ -877,8 +873,6 @@ Mode::Phase Mode::Update3SecondHotfire(RF::Command &command, Navigation &navigat seventhPartDone = false; eigthPartDone = false; ninthPartDone = false; - tenthPartDone = false; - eleventhPartDone = false; return Mode::HotfireIdle; } } diff --git a/src/README.md b/src/README.md index cd81c48..fbe4410 100644 --- a/src/README.md +++ b/src/README.md @@ -29,7 +29,6 @@ Whenever we do change modes, it is important that we use `Telemety.GetInstance() ### Navigation.cpp - ### Controller.cpp ### LaunchManager.cpp