Skip to content

Commit

Permalink
Merge branch 'master' into events
Browse files Browse the repository at this point in the history
  • Loading branch information
MarwanMashaly1 authored Jun 26, 2024
2 parents d246f41 + 0251afa commit 0668a12
Show file tree
Hide file tree
Showing 24 changed files with 233 additions and 128 deletions.
27 changes: 20 additions & 7 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
# Base image for toolchain download
FROM mcr.microsoft.com/devcontainers/rust:latest as toolchain

RUN mkdir -p /toolchain && \
curl -L "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-eabi.tar.xz" \
| tar --strip-components=1 -xJ -C /toolchain

# Final image
FROM mcr.microsoft.com/devcontainers/rust:latest

# Copy the toolchain from the previous stage
COPY --from=toolchain /toolchain /toolchain

ENV PATH="${PATH}:/toolchain/bin"
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get upgrade -y && apt-get install -y cmake pkg-config libusb-1.0-0-dev libftdi1-dev libudev-dev libssl-dev

# Install ARM GCC deps
RUN mkdir -p toolchain && \
curl -L "https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-eabi.tar.xz" \
| tar --strip-components=1 -xJ -C toolchain && \
cargo install --locked probe-rs --features cli
ENV PATH="${PATH}:/toolchain/bin"
# Necessary system packages
RUN apt-get update && apt-get install -y cmake pkg-config libusb-1.0-0-dev libftdi1-dev libudev-dev libssl-dev && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Install Rust crates
RUN cargo install probe-rs --features cli \
&& cargo install cargo-make
3 changes: 3 additions & 0 deletions .github/workflows/clippy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ jobs:
components: clippy
toolchain: stable
target: thumbv7em-none-eabihf
- name: cargofmt
run: cargo fmt --check
- uses: actions/cache@v3
with:
path: |
Expand All @@ -31,3 +33,4 @@ jobs:
- uses: actions-rs/clippy-check@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}

3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/target
/.vscode/.cortex-debug.registers.state.json
/.vscode/.cortex-debug.peripherals.state.json
/.vscode/settings.json
/.vscode/settings.json
/toolchain
62 changes: 39 additions & 23 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# HYDRA   [![Build Status]][actions] [![docs-badge]][docs]
*HYper Dynamic Rocketry Avionics*

***HY**per **D**ynamic **R**ocketry **A**vionics*

[Build Status]: https://github.com/uorocketry/hydra/actions/workflows/build.yml/badge.svg
[actions]: https://github.com/uorocketry/hydra/actions?query=branch%3Amaster
Expand All @@ -12,46 +13,60 @@

## Getting Started

1. Install Rust: https://www.rust-lang.org/tools/install
2. Build: `cargo build`
3. Install probe-run: `cargo install --git https://github.com/uorocketry/probe-run`
- `probe-run` currently requires a patch to flash our chip, so please use the above version while the patch is upstreamed
4. Install cargo-make: `cargo install cargo-make`
4. Flash: `cargo run --bin main`
5. Run tests: `cargo make test-host` or `cargo make test-device`
> If you are in a DevContainer skip to step 5.
- Install Rust: https://www.rust-lang.org/tools/install
- Install necessary build tools:
- cargo-make: `cargo install cargo-make`
- probe-rs: `cargo install probe-rs --features cli`
- Install the [ARM GNU Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads) (last tested with 13.2) and have it available in your PATH
- Arch Linux: `sudo pacman -S arm-none-eabi-gcc`
- Alpine/Debian/Ubuntu: <https://pkgs.org/download/gcc-arm-none-eabi>
- MacOS: `brew install arm-none-eabi-gcc`
- Build: `cargo build`
- In case it fails, try `cargo build --release`
- Run tests:
- In the host machine: `cargo make test-host`
- In the device: `cargo make test-device`
- Flash on hardware: `cargo run --bin main`

For more detailed instructions on flashing, debugging, and more, please see [the wiki](https://avwiki.uorocketry.ca/en/Avionics/HYDRA/Software).

## Windows Users

### Setting up with Docker
1. Install Docker: https://docs.docker.com/desktop/install/windows-install/
2. Install VS Code: https://code.visualstudio.com/download
3. From VS Code, install the "Dev Containers" extension
4. press `ctrl` + `shift` + `p`, and search for `Dev Containers: Open Folder in Container`

- Install [Docker](https://docs.docker.com/desktop/install/windows-install/)
- Install [VS Code](https://code.visualstudio.com/download)
- From VS Code, install the "Dev Containers" extension
- press `ctrl` + `shift` + `p`, and search for `Dev Containers: Open Folder in Container`

### Setting up with WSL
1. Enable WSL: https://learn.microsoft.com/en-us/windows/wsl/install
2. Install a linux distro from the Microsoft Store
4. Install ARM GNU Toolchain: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads

- Enable WSL: https://learn.microsoft.com/en-us/windows/wsl/install
- Install a linux distro from the Microsoft Store
- Install the [ARM GNU Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads)
- NOTE: You may find this in your distro's package manager, but ensure it is version 13.2.
- Ubuntu has an outdated version in its repositories. If using Ubuntu, download it manually from the link above
3. Follow the rest of the instructions in [Getting Started](#-getting-started)
- Follow the rest of the instructions in [Getting Started](#-getting-started)

### Flashing

After plugging in J-Link, it will likely show up as unknown.

1. Install Zadig: https://zadig.akeo.ie/
2. From Zadig, select J-Link as the device and WinUSB as the driver
3. click Install Driver

If using WSL or Docker with a WSL backend (you probably are), you need to tell Windows to share J-Link with WSL.
1. From WSL, install linux-tools-generic
1. on Ubuntu: `sudo apt install linux-tools-generic`
2. Install usbipd-win: https://github.com/dorssel/usbipd-win/releases
3. Open command prompt/powershell with admin privileges and run `usbipd list`
4. Make note of the entry called J-Link and run `usbipd bind --busid <busid>`
5. Next, run `usbipd attach --wsl --busid <busid>`
6. You can now follow the flashing instructions in [Getting Started](#-getting-started)

- From WSL, install linux-tools-generic
- on Ubuntu: `sudo apt install linux-tools-generic`
- Install usbipd-win: https://github.com/dorssel/usbipd-win/releases
- Open command prompt/powershell with admin privileges and run `usbipd list`
- Make note of the entry called J-Link and run `usbipd bind --busid <busid>`
- Next, run `usbipd attach --wsl --busid <busid>`
- You can now follow the flashing instructions in [Getting Started](#getting-started)

## Documentation

Expand All @@ -60,6 +75,7 @@ Run `cargo doc --open` to build and open the documentation. Most documentation f
Documentation is also automatically built and deployed to https://hydra-docs.uorocketry.ca/common_arm

## Project Structure

The project is structured in a way to allow reuse of the code across various boards and other projects.

- `boards`: Folder containing each individual board's binary crates. Any code in those crates should only contain logic specific to the board.
Expand Down
8 changes: 4 additions & 4 deletions boards/beacon/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use messages::sender::Sender;
use messages::sender::Sender::BeaconBoard;
use messages::node::Node;
use messages::node::Node::BeaconBoard;

// -------
// Sender ID
// Node ID
// -------
pub static COM_ID: Sender = BeaconBoard;
pub static COM_ID: Node = BeaconBoard;

Check warning on line 7 in boards/beacon/src/types.rs

View workflow job for this annotation

GitHub Actions / clippy

static `COM_ID` is never used

warning: static `COM_ID` is never used --> boards/beacon/src/types.rs:7:12 | 7 | pub static COM_ID: Node = BeaconBoard; | ^^^^^^
3 changes: 1 addition & 2 deletions boards/camera/src/communication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,7 @@ impl CanDevice0 {
can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo0,
filter: ecan::StandardId::new(messages::sender::Sender::SensorBoard.into())
.unwrap(),
filter: ecan::StandardId::new(messages::node::Node::SensorBoard.into()).unwrap(),
mask: ecan::StandardId::ZERO,
})
.unwrap_or_else(|_| panic!("Sensor filter"));
Expand Down
6 changes: 3 additions & 3 deletions boards/camera/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use messages::sender::{Sender, Sender::CameraBoard};
use messages::node::{Node, Node::CameraBoard};
// -------
// Sender ID
// Node ID
// -------
pub static _COM_ID: Sender = CameraBoard;
pub static _COM_ID: Node = CameraBoard;
11 changes: 4 additions & 7 deletions boards/communication/src/communication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,34 +120,31 @@ impl CanDevice0 {
can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo0,
filter: ecan::StandardId::new(messages::sender::Sender::RecoveryBoard.into())
.unwrap(),
filter: ecan::StandardId::new(messages::node::Node::RecoveryBoard.into()).unwrap(),
mask: ecan::StandardId::ZERO,
})
.unwrap_or_else(|_| panic!("Recovery filter"));

can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo1,
filter: ecan::StandardId::new(messages::sender::Sender::SensorBoard.into())
.unwrap(),
filter: ecan::StandardId::new(messages::node::Node::SensorBoard.into()).unwrap(),
mask: ecan::StandardId::ZERO,
})
.unwrap_or_else(|_| panic!("Sensor filter"));

can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo0,
filter: ecan::StandardId::new(messages::sender::Sender::PowerBoard.into()).unwrap(),
filter: ecan::StandardId::new(messages::node::Node::PowerBoard.into()).unwrap(),
mask: ecan::StandardId::ZERO,
})
.unwrap_or_else(|_| panic!("Power filter"));

can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo0,
filter: ecan::StandardId::new(messages::sender::Sender::GroundStation.into())
.unwrap(),
filter: ecan::StandardId::new(messages::node::Node::GroundStation.into()).unwrap(),
mask: ecan::StandardId::ZERO,
})
.unwrap_or_else(|_| panic!("Ground Station filter"));
Expand Down
8 changes: 4 additions & 4 deletions boards/communication/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use atsamd_hal::gpio::*;
use atsamd_hal::sercom::uart::EightBit;
use atsamd_hal::sercom::{uart, IoSet1, Sercom5};
use messages::sender::Sender;
use messages::sender::Sender::CommunicationBoard;
use messages::node::Node;
use messages::node::Node::CommunicationBoard;

// -------
// Sender ID
// Node ID
// -------
pub static COM_ID: Sender = CommunicationBoard;
pub static COM_ID: Node = CommunicationBoard;

// -------
// Ground Station
Expand Down
2 changes: 1 addition & 1 deletion boards/power/src/communication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl CanDevice0 {
can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo1,
filter: ecan::StandardId::new(messages::sender::Sender::CommunicationBoard.into())
filter: ecan::StandardId::new(messages::node::Node::CommunicationBoard.into())
.unwrap(),
mask: ecan::StandardId::ZERO,
})
Expand Down
6 changes: 3 additions & 3 deletions boards/power/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use messages::sender::{Sender, Sender::PowerBoard};
use messages::node::{Node, Node::PowerBoard};
// -------
// Sender ID
// Node ID
// -------
pub static _COM_ID: Sender = PowerBoard;
pub static _COM_ID: Node = PowerBoard;
5 changes: 2 additions & 3 deletions boards/recovery/src/communication.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,7 @@ impl CanDevice0 {
can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo0,
filter: ecan::StandardId::new(messages::sender::Sender::SensorBoard.into())
.unwrap(),
filter: ecan::StandardId::new(messages::node::Node::SensorBoard.into()).unwrap(),
mask: ecan::StandardId::ZERO,
})
.unwrap_or_else(|_| panic!("Sensor Board filter"));
Expand All @@ -121,7 +120,7 @@ impl CanDevice0 {
can.filters_standard()
.push(Filter::Classic {
action: Action::StoreFifo1,
filter: ecan::StandardId::new(messages::sender::Sender::CommunicationBoard.into())
filter: ecan::StandardId::new(messages::node::Node::CommunicationBoard.into())
.unwrap(),
mask: ecan::StandardId::ZERO,
})
Expand Down
38 changes: 24 additions & 14 deletions boards/recovery/src/data_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ use messages::Message;

const MAIN_HEIGHT: f32 = 876.0; // meters ASL
const HEIGHT_MIN: f32 = 600.0; // meters ASL
const RECOVERY_DATA_POINTS: u8 = 8; // number of barometric altitude readings held by the recovery
// algorithm
const RECOVERY_TIMER_TIMEOUT: u8 = 15; // minutes

pub struct DataManager {
pub air: Option<Air>,
Expand All @@ -16,8 +19,11 @@ pub struct DataManager {
pub imu: (Option<Imu1>, Option<Imu2>),
pub utc_time: Option<UtcTime>,
pub gps_vel: Option<GpsVel>,
pub historical_barometer_altitude: HistoryBuffer<(f32, u32), 8>,
pub historical_barometer_altitude: HistoryBuffer<(f32, u32), 8>, // RECOVERY_DATA_POINTS (issue
// when putting as const)
pub current_state: Option<RocketStates>,
// each tick represents a minute that passed
pub recovery_counter: u8,
}

impl DataManager {
Expand All @@ -32,11 +38,12 @@ impl DataManager {
gps_vel: None,
historical_barometer_altitude,
current_state: None,
recovery_counter: 0,
}
}
/// Returns true if the rocket is descending
pub fn is_falling(&self) -> bool {
if self.historical_barometer_altitude.len() < 8 {
if (self.historical_barometer_altitude.len() as u8) < RECOVERY_DATA_POINTS {
return false;
}
let mut buf = self.historical_barometer_altitude.oldest_ordered();
Expand All @@ -56,14 +63,14 @@ impl DataManager {
avg_sum += slope;
prev = i;
}
match avg_sum / 7.0 {
match avg_sum / (RECOVERY_DATA_POINTS as f32 - 1.0) {
// 7 because we have 8 points.
// exclusive range
x if !(-100.0..=-5.0).contains(&x) => {
return false;
}
_ => {
info!("avg: {}", avg_sum / 7.0);
info!("avg: {}", avg_sum / (RECOVERY_DATA_POINTS as f32 - 1.0));
}
}
}
Expand All @@ -82,8 +89,8 @@ impl DataManager {
None => false,
}
}
pub fn is_landed(&self) -> bool {
if self.historical_barometer_altitude.len() < 8 {
pub fn is_landed(&mut self) -> bool {
if self.historical_barometer_altitude.len() < RECOVERY_DATA_POINTS.into() {
return false;
}
let mut buf = self.historical_barometer_altitude.oldest_ordered();
Expand All @@ -99,13 +106,15 @@ impl DataManager {
avg_sum += (i.0 - prev.0) / time_diff;
prev = i;
}
match avg_sum / 7.0 {
match avg_sum / (RECOVERY_DATA_POINTS as f32 - 1.0) {
// inclusive range
x if (-0.25..=0.25).contains(&x) => {
return true;
if self.recovery_counter >= RECOVERY_TIMER_TIMEOUT {
return true;
}
}
_ => {
// continue
self.recovery_counter = 0;
}
}
}
Expand All @@ -132,11 +141,12 @@ impl DataManager {
messages::Data::Sensor(sensor) => match sensor.data {
messages::sensor::SensorData::Air(air_data) => {
/*
NOTE!!!
There should be added a counter to check how many times
the alt is dropped, if the number is high switch to
the on board barometer.
git */
NOTE!!!
There should be added a counter to check how many times
the alt is dropped, if the number is high switch to
the on board barometer.
*/

if let Some(alt) = air_data.altitude {
let tup_data: (f32, u32) = (alt, air_data.time_stamp);
Expand Down
Loading

0 comments on commit 0668a12

Please sign in to comment.