Team Rocket Goat

How can I give a model rocket a steerable descent?


From Google Gemini:

Replacing a standard passive parachute with a steerable descent requires converting your rocket's payload bay into a miniature radio-controlled glider. The most practical and reliable method is an RC Parafoil Recovery System.

Instead of floating aimlessly on the wind, the rocket deploys a steerable wing at apogee, which you then pilot back to the launch pad using standard radio controls.

Here is the physical computing architecture you need to build:

1. The Canopy (The Wing)

You will need to ditch the traditional dome parachute and use a miniature ram-air parafoil (similar to a skydiver's canopy). These have an airfoil shape that inflates with air to generate forward glide rather than just slowing vertical descent. The canopy is rigged with left and right control lines attached to the trailing edges.



2. The Flight Controller (The Brain)

You need a lightweight microcontroller to bridge the radio signals and the physical mechanics. An Arduino Nano or a micro:bit is ideal here due to their low weight and easy integration.

 You pair this with a standard micro 2.4 GHz RC receiver. The receiver catches your joystick inputs and passes the data to the microcontroller.

3. Actuation (The Muscle)

To actually steer the wing, you mount two micro servos (like standard 9g SG90s) inside the rocket.

  • One servo is connected to the left trailing edge line.

  • One servo is connected to the right trailing edge line.

When you push left on your transmitter, the microcontroller tells the left servo to rotate, pulling the left line down. This creates drag on the left side of the canopy, turning the entire system left. Pulling both lines simultaneously acts as a flare to slow the descent right before touchdown.

4. The Payload Sled (The Chassis)

All of this hardware has to survive high-G launch forces and fit snugly inside a cylindrical rocket body tube. You can design a custom electronics sled in Onshape to hold the microcontroller, LiPo battery, receiver, and servos securely. This sled can then be 3D printed or laser-cut from thin plywood. It slides directly into the payload section, with the servo arms positioned to safely route the control lines out the top.

The Deployment Sequence: The motor's ejection charge pushes the entire system out at apogee exactly like a standard parachute. The electronics remain powered on during the ascent. Once the canopy inflates and the payload stabilizes into a glide, you take manual control via the transmitter.

Sample Arduino Code:

To control a steerable parafoil smoothly, we need to implement a concept called mixing. When flying a parafoil, pulling the left line turns it left, pulling the right line turns it right, and pulling both lines acts as a brake or "flare" to slow down for a gentle landing.

This code will take two channels from your RC receiver (Steering on Channel 1, and Brake/Flare on Channel 2) and mix them so the two servos actuate perfectly in tandem. It also includes a failsafe: if the rocket flies out of radio range, it automatically slacks both lines so the canopy glides safely straight down instead of spiraling.

//-------------------------------------


#include <Servo.h>

// ==========================================
// PIN CONFIGURATIONS
// ==========================================
// RC Receiver Input Pins
const int CH1_PIN = 2; // Steering (Left/Right)
const int CH2_PIN = 3; // Flare/Brake (Pull both lines)

// Servo Output Pins
const int LEFT_SERVO_PIN = 9;
const int RIGHT_SERVO_PIN = 10;

// ==========================================
// SERVO TUNING PARAMETERS
// ==========================================
// Adjust these angles based on your specific sled and servo horn orientation!
// NEUTRAL = Lines have slight slack (no steering input)
// MAX_PULL = Maximum safe travel before pulling the lines too tight
const int LEFT_NEUTRAL_ANGLE = 0;
const int LEFT_MAX_PULL_ANGLE = 90;

const int RIGHT_NEUTRAL_ANGLE = 180; // Right servo usually mirrors the left
const int RIGHT_MAX_PULL_ANGLE = 90;

// ==========================================
// GLOBAL VARIABLES
// ==========================================
Servo leftServo;
Servo rightServo;

void setup() {
Serial.begin(9600);
// Attach servos to pins
leftServo.attach(LEFT_SERVO_PIN);
rightServo.attach(RIGHT_SERVO_PIN);
// Set receiver pins as inputs
pinMode(CH1_PIN, INPUT);
pinMode(CH2_PIN, INPUT);

// Initialize servos to neutral position (slack lines)
leftServo.write(LEFT_NEUTRAL_ANGLE);
rightServo.write(RIGHT_NEUTRAL_ANGLE);
Serial.println("Parafoil Control System Initialized.");
}

void loop() {
// 1. READ RC SIGNALS
// pulseIn reads the PWM duration in microseconds.
// Standard RC ranges from ~1000us to ~2000us. 1500us is center.
// 25000us timeout prevents the code from freezing if the radio disconnects.
unsigned long ch1_raw = pulseIn(CH1_PIN, HIGH, 25000);
unsigned long ch2_raw = pulseIn(CH2_PIN, HIGH, 25000);

// 2. FAILSAFE CHECK
// If pulseIn times out, it returns 0. This means the radio connection is lost.
if (ch1_raw == 0 || ch2_raw == 0) {
Serial.println("SIGNAL LOST - Activating Failsafe (Neutral Glide)");
leftServo.write(LEFT_NEUTRAL_ANGLE);
rightServo.write(RIGHT_NEUTRAL_ANGLE);
delay(100);
return; // Skip the rest of the loop until signal returns
}

// 3. NORMALIZE INPUTS
// Map steering to a -500 (Left) to +500 (Right) scale
int steering = map(ch1_raw, 1000, 2000, -500, 500);
// Add a small deadband to prevent twitching when the stick is centered
if (abs(steering) < 30) steering = 0;
// Map flare/brake to a 0 (No pull) to 500 (Max pull) scale
// Assuming CH2 is pushed down/forward for braking (1500 to 1000)
int flare = map(ch2_raw, 1500, 1000, 0, 500);
flare = constrain(flare, 0, 500); // Ignore forward stick movements

// 4. MIX STEERING AND FLARE
// Calculate how much each line needs to be pulled (0 to 500 scale)
int leftPullAmount = flare;
int rightPullAmount = flare;

// Add steering logic
if (steering < 0) {
// Stick left -> Pull left line
leftPullAmount += abs(steering);
} else if (steering > 0) {
// Stick right -> Pull right line
rightPullAmount += steering;
}

// Constrain to ensure we don't exceed the max 500 limit
leftPullAmount = constrain(leftPullAmount, 0, 500);
rightPullAmount = constrain(rightPullAmount, 0, 500);

// 5. MAP PULL AMOUNT TO SERVO ANGLES
int leftAngle = map(leftPullAmount, 0, 500, LEFT_NEUTRAL_ANGLE, LEFT_MAX_PULL_ANGLE);
int rightAngle = map(rightPullAmount, 0, 500, RIGHT_NEUTRAL_ANGLE, RIGHT_MAX_PULL_ANGLE);

// 6. ACTUATE SERVOS
leftServo.write(leftAngle);
rightServo.write(rightAngle);

// Optional: Debugging output (Uncomment to test via Serial Monitor)
/*
Serial.print("CH1 (Steer): "); Serial.print(ch1_raw);
Serial.print(" | CH2 (Flare): "); Serial.print(ch2_raw);
Serial.print(" || Left Angle: "); Serial.print(leftAngle);
Serial.print(" | Right Angle: "); Serial.println(rightAngle);
*/
// Short delay for stability
delay(20);
}

----------------------------------------------


---------------------------------------------------------------


5V Regulator AMS 1117 5V

1. Power Supply (Battery & BEC)

  • LiPo Battery (+): Connects to the IN/BAT+ pin of the 5V BEC.

  • LiPo Battery (-): Connects to the IN/GND pin of the 5V BEC.

  • BEC 5V Output (+): Connects to the 5V Power Bus (supplies the Arduino, Receiver,

  • and both Servos).

  • BEC Ground (-): Connects to the Common Ground Bus

  • (ties all grounds together).

2. Arduino Nano Connections

Arduino Pin

Connects To

Purpose

5V

5V Power Bus (from BEC)

Powers the Arduino logic

GND

Common Ground Bus

Completes the circuit

D2

RC Receiver CH1 (Signal)

Reads the Steering input

D3

RC Receiver CH2 (Signal)

Reads the Brake/Flare input

D9

Left Servo Signal (Orange/White)

Outputs PWM to Left Servo

D10

Right Servo Signal (Orange/White)

Outputs PWM to Right Servo

3. RC Receiver Connections

Receiver Pin

Connects To

Purpose

CH1 Signal

Arduino D2

Sends Steering PWM to Arduino

CH2 Signal

Arduino D3

Sends Flare PWM to Arduino

VCC / +

5V Power Bus

Powers the Receiver

GND / -

Common Ground Bus

Completes the circuit

4. Servo Connections (SG90)

Servo Wire Color

Connects To

Purpose

Red (VCC)

5V Power Bus

Powers the servo motor

Brown / Black (GND)

Common Ground Bus

Completes the circuit

Orange / White (Signal) - Left

Arduino D9

Receives commands for Left Line

Orange / White (Signal) - Right

Arduino D10

Receives commands for Right Line

Important Wiring Rules for Model Rockets:

  1. Common Ground is Mandatory: The system will not work (and servos will twitch violently)

  2. if the Arduino, Receiver, and Servos do not all share the exact same Ground connection.

  3. Solder, Don't Plug: For actual flight hardware, do not use standard breadboard jumper wires.

  4. The G-forces of launch will pull them out.

  5. Direct soldering to protoboard or using secure JST/Dupont locking connectors with

  6. a dab of hot glue is required.

  7. Keep Antennas Clear: Route the RC receiver's antenna away from the carbon fiber (if any)

  8. and the servos to prevent signal blocking or interference.


 Apogee Rockets- Gliding Parachute System

A gliding parachute (parafoil) for model rockets replaces a standard round parachute with a steerable wing. It allows the rocket to glide horizontally and be flown back to the launch pad, preventing it from drifting miles away in the wind. These systems usually require a small on-board battery, servo, and an RC








Team Rocket Goat Second Design Review[cite: 1]


Overview
  • The meeting focused on designing a project to land a device softly and accurately at a specific target.[cite: 1]

  • Initial tests showed issues with parachutes opening too late.[cite: 1]

  • Suggestions included using a helium balloon with three strings for controlled release, a radio-controlled parachute, or a fixed-wing glider.[cite: 1]

  • The team prioritized landing softly, followed by controlled flight and landing on target.[cite: 1]

  • They discussed using servos for control and the potential use of a dragon tail for steering.[cite: 1]

  • The goal is to create a device that can land within a 50-foot radius and safely, with controlled descent being a secondary concern.[cite: 1]

Action Items

  • Obtain a lightweight plastic dry cleaner bag from a local dry cleaner to use as a potential material for the parachute or glider component of the device.[cite: 1]

Outline

Discussion on Project Goals and Initial Test Results

  • Ed questions Speaker 2 about their power trip, leading to a discussion about seating arrangements and project goals.[cite: 1]

  • Speaker 3 asks about stopping a project's behavior, and Ed suggests moving the weight further down or closer.[cite: 1]

  • Jonathan shows a video of the first version of the project, which had a round parachute that opened late.[cite: 1]

  • Speaker 6 inquires about the project's goal, and Speaker 7 explains the need to land in a specific spot and steer the project.[cite: 1]

Comparisons to Goats and Predators

  • Ed and Speaker 3 discuss how goats walk downhill and how predators come from below.[cite: 1]

  • Ed suggests using a balloon with strings to release the project at a desired height.[cite: 1]

  • Ed proposes using a helium balloon and radio control for a more stable and controllable release.[cite: 1]

  • Jonathan mentions the challenges of model rockets and the need for a parachute to recover them.[cite: 1]

Exploring Glider Techniques and Control Mechanisms

  • Ed discusses the use of balloons and radio control for gliders, suggesting a simpler and more reliable method.[cite: 1]

  • Speaker 6 compares the project to a kite with two guide strings, emphasizing the importance of balance and control.[cite: 1]

  • Ed explains the concept of the center of lift and how it affects the project's stability.[cite: 1]

  • Jonathan introduces the idea of a rocket recovery car buyer with radio control and servos for steering.[cite: 1]

Discussion on Project Priorities and Design Principles

  • Speaker 6 lists three objectives: landing on target, landing quickly, and controlled flight.[cite: 1]

  • Ed emphasizes the importance of landing softly as the primary goal.[cite: 1]

  • The group discusses the relative importance of controlled flight, landing on target, and landing quickly.[cite: 1]

  • Ed suggests using a dragon tail or rudder for steering and controlling the project's descent.[cite: 1]

Considering Different Launch Methods and Control Techniques

  • Ed proposes using a helium balloon with three strings to control the project's release.[cite: 1]

  • Jonathan suggests using a simple radio module with a range of 3000 feet for control.[cite: 1]

  • Ed discusses the challenges of wind affecting the project's landing and the importance of a controlled descent.[cite: 1]

  • The group considers different launch methods, including dropping from a fixed point and using a parachute or glider.[cite: 1]

Finalizing Project Goals and Design Decisions

  • Speaker 6 summarizes the group's priorities: landing softly, controlled flight, landing on target, and landing quickly.[cite: 1]

  • Ed emphasizes the importance of landing softly and controlled flight as the primary goals.[cite: 1]

  • The group discusses the potential use of a parachute or glider for controlled descent and landing.[cite: 1]

  • Ed suggests using a fixed-wing plane or a paraglider for more precise control and landing.[cite: 1]

Testing and Refining the Project Design

  • Ed and Jonathan discuss the results of previous tests, including the use of a regular parachute and a plastic parachute.[cite: 1]

  • Speaker 7 mentions the challenges of controlling the project with servos and the need for more space inside the design.[cite: 1]

  • Jonathan suggests adding legs to the project for stability and control.[cite: 1]

  • The group considers the use of a reusable parachute or glider to ensure a soft landing and controlled descent.[cite: 1]

Addressing Wind and Distance Concerns

  • Ed discusses the impact of wind on the project's landing and the importance of a controlled descent.[cite: 1]

  • Jonathan shares experiences with model rockets and the challenges of wind affecting their landing.[cite: 1]

  • Ed suggests using a parachute or glider that can flare to land softly and accurately.[cite: 1]

  • The group considers the use of a helium balloon with three strings to control the project's release and landing.[cite: 1]

Considering Different Launch and Control Methods

  • Ed proposes using a helium balloon with three strings to control the project's release and landing.[cite: 1]

  • Jonathan suggests using a simple radio module for control and steering.[cite: 1]

  • Ed discusses the challenges of wind affecting the project's landing and the importance of a controlled descent.[cite: 1]

  • The group considers different launch methods, including dropping from a fixed point and using a parachute or glider.[cite: 1]

Finalizing the Project Design and Next Steps

  • Ed emphasizes the importance of landing softly and controlled flight as the primary goals.[cite: 1]

  • The group discusses the potential use of a parachute or glider for controlled descent and landing.[cite: 1]

  • Ed suggests using a fixed-wing plane or a paraglider for more precise control and landing.[cite: 1]

  • The group plans to proceed with building and testing the project based on the discussed design principles and goals.[cite: 1]


-----------------------------------------------------------------------------------
Sample transmitter program:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <SoftwareSerial.h>

// OLED Display Constants
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C

Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

// HC-12 Radio Setup
const int hc12RxPin = 2;
const int hc12TxPin = 3;
SoftwareSerial HC12(hc12RxPin, hc12TxPin);

// Hardware Pins
const int accelPin = A0;
const int buttonPin = 4; // Button connected to D4 and Ground

// State tracking for the button
int lastButtonState = HIGH;

void setup() {
Serial.begin(9600);
HC12.begin(9600);

// Set up the button with internal pull-up resistor
pinMode(buttonPin, INPUT_PULLUP);

if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}

display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(F("System Ready"));
display.display();
delay(2000);
}

void loop() {
// --- 1. HANDLE BUTTON PUSHES ---
// Read the button (LOW means pressed because of INPUT_PULLUP)
int currentButtonState = digitalRead(buttonPin);
// If the button state changed, transmit immediately
if (currentButtonState != lastButtonState) {
delay(50); // Simple debounce
if (currentButtonState == LOW) {
HC12.println("B1"); // B for Button, 1 for Pressed
Serial.println("Transmitted: B1");
} else {
HC12.println("B0"); // B for Button, 0 for Released
Serial.println("Transmitted: B0");
}
lastButtonState = currentButtonState;
}

// --- 2. HANDLE TILT SENSOR (Every 200ms) ---
// We use a non-blocking timer instead of delay(200) so we don't miss button pushes!
static unsigned long lastTiltTime = 0;
if (millis() - lastTiltTime >= 200) {
lastTiltTime = millis();

int rawValue = analogRead(accelPin);
int mappedValue = map(rawValue, 260, 410, 0, 180);
mappedValue = constrain(mappedValue, 0, 180);

// Update OLED
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.println(F("Transmitting..."));
display.setCursor(0, 25);
display.print(F("Tilt: "));
display.setTextSize(2);
display.print(mappedValue);
display.display();

// Transmit Tilt with 'T' prefix
HC12.print("T");
HC12.println(mappedValue);

Serial.print("Transmitted: T");
Serial.println(mappedValue);
}
}

No comments:

Post a Comment