Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
Merge branch 'main' into refactor/link-in-pros-sys
Browse files Browse the repository at this point in the history
  • Loading branch information
Tropix126 authored Mar 3, 2024
2 parents d2a9e8e + c25d1a2 commit 245a86a
Show file tree
Hide file tree
Showing 80 changed files with 1,735 additions and 938 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
toolchain: nightly-2024-02-07
override: true

- name: Check
Expand All @@ -33,7 +33,7 @@ jobs:
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: nightly
toolchain: nightly-2024-02-07
override: true

- name: Setup | Install Rustfmt
Expand All @@ -57,4 +57,4 @@ jobs:
with:
reporter: 'github-pr-check'
github_token: ${{ secrets.GITHUB_TOKEN }}
clippy_flags: --all-targets --all-features
clippy_flags: --all-targets --all-features
46 changes: 43 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,34 @@ Before releasing:

## [Unreleased]

### Added

### Fixed

### Changed

- Linked libpros through `pros_sys` rather than the vexos target spec. (#85)

### Removed

## [0.8.0]

### Added
- Added feedforward motor controllers (#80)
- Lightly document all APIs with missing documentation. (#70)
- Added `Debug`, `Copy`, and `Clone` derives for common structs (#70)

- Screen drawing API. (#81)
- Added screen field to `Peripherals` and `DynamicPeripherals::take_screen` method. (#81)
- Added `AdiSolenoid`, a wrapper over `AdiDigitalOut` for actuating SMC pneumatic solenoids. (#61)
- Added `AdiSwitch`, another `AdiDigitalOut` wrapper that abstracts bumper switches and limit switches. (#61)
- Added `AdiLineTracker` for abstracting the EDR line tracker sensor.

### Fixed

- Fix error handling and error type variats in ADI bindings
- Fix `AsynRobot` only running opcontrol
- Properly handle `EADDRINUSE` return for smart port errors (**Breaking Change**) (#97)

### Changed

- Re-exported printing macros from `pros::io`. (#82)
Expand All @@ -40,7 +58,26 @@ Before releasing:
- The VEXOS target has been updated to improve file size and floating point operation speed. (#81)
- `Peripherals::new()` is no longer const (**Breaking Change) (#81)
- Updated panic handler to print to the brain display as well as over serial (#81)
- Linked libpros through `pros_sys` rather than the vexos target spec. (#85)
- Refactors digital and analog ADI input/output. (**Breaking Change**) (#61)
- Adds LogicLevel rather than bools for controlling digital devices.
- Adds 0-5V voltage getters and setters for analog ADI.
- Changed analog getters and setters to use `u16` data.
- Changed `AdiPotentiometer` to return degrees rather than tenth degrees (**Breaking Change**) (#61).
- Renamed `AdiPotentiometer::value` to `AdiPotentiometer::angle`.
- Refactors `AdiMotor` to match the smart motor APIs, having output/raw output getters/setters.
- Renamed `AdiUltrasonic::value` to `AdiUltrasonic::distance` (**Breaking Change**) (#61).
- Renamed `AdiEncoder::value` to `AdiEncoder::position` (**Breaking Change**) (#61).
- Repurposed `AdiAnalogOut` as `AdiPwmOut` to correct match port output. (**Breaking Change**) (#90).
- Moved most device-related constants into their associated struct `impl` (**Breaking Change**) (#98).
- Renamed IMU_RESET_TIMEOUT to `InertialSensor::CALIBRATION_TIMEOUT` (**Breaking Change**) (#98).
- Repurposed the `pros` crate as a metapackage without any code of its own. (**Breaking Change**) (#86)
- Split the pros-rs into several small subcrates. (**Breaking Change**) (#86)
- `pros-async` with the async executor and robot trait.
- `pros-devices` for device bindings.
- `pros-sync` for the sync robot trait.
- `pros-core` with basic abstractions over `pros-sys` needed to compile a program to the brain.
- `pros-math` with commonly used controllers and other mathematical models.
- `pros-panic` for the panic handler implementation.

### Removed

Expand All @@ -49,6 +86,7 @@ Before releasing:
- Re-exported printing macros from `pros::io`. (#82)
- Applied several lints to improve code quality. (#70)
- Removed the confusingly named `write`, `ewrite`, `writeln`, and `ewriteln` macros. (**Breaking Change**) (#82)
- Removed AdiDigitalIn::new_press, instead swapping it for AdiSwitch::was_pressed. (**Breaking Change**) (#61)

## [0.7.0]

Expand All @@ -67,6 +105,7 @@ Before releasing:
- All ADI device bindings (#55)
- `LocalKey` now has `Cell`/`RefCell`-specific methods for setting and taking values. (#42)
- `Peripherals` and `DynamicPeripherals` structs to ensure that you have only registered one device on a given smart or ADI port. (#53)
- Support for ADI Expander modules with `AdiExpander`. (#63)

### Fixed

Expand Down Expand Up @@ -151,8 +190,9 @@ Before releasing:

### Removed

[unreleased]: https://github.com/pros-rs/pros-rs/compare/v0.7.0...HEAD
[unreleased]: https://github.com/pros-rs/pros-rs/compare/v0.8.0...HEAD
[0.4.0]: https://github.com/pros-rs/pros-rs/releases/tag/v0.4.0
[0.5.0]: https://github.com/pros-rs/pros-rs/compare/v0.4.0...v0.5.0
[0.6.0]: https://github.com/pros-rs/pros-rs/compare/v0.5.0...v0.6.0
[0.7.0]: https://github.com/pros-rs/pros-rs/compare/v0.6.0...v0.7.0
[0.8.0]: https://github.com/pros-rs/pros-rs/compare/v0.7.0...v0.8.0
8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
[workspace]
members = ["packages/*"]
resolver = "2"

[workspace.lints.rust]
rust_2018_idioms = "warn"
missing_docs = "warn"
unsafe_op_in_unsafe_fn = "warn"

[workspace.lints.clippy]
missing_const_for_fn = "warn"
15 changes: 15 additions & 0 deletions packages/pros-async/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[package]
name = "pros-async"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
async-task = { version = "4.5.0", default-features = false }
pros-core = { version = "0.1.0", path = "../pros-core" }
waker-fn = "1.1.1"
pros-sys = { version = "0.7.0", path = "../pros-sys" }

[lints]
workspace = true
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ use core::{
};

use async_task::{Runnable, Task};
use pros_core::{os_task_local, task::delay};
use waker_fn::waker_fn;

use super::reactor::Reactor;
use crate::{os_task_local, task::delay};

os_task_local! {
pub(crate) static EXECUTOR: Executor = Executor::new();
Expand Down
203 changes: 203 additions & 0 deletions packages/pros-async/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
//! Tiny async runtime and robot traits for `pros-rs`.
//! The async executor supports spawning tasks and blocking on futures.
//! It has a reactor to improve the performance of some futures.
//! It is recommended to use the `AsyncRobot` trait to run robot code.
//! FreeRTOS tasks can still be used, but it is recommended to use only async tasks for performance.
#![no_std]
#![feature(negative_impls)]

extern crate alloc;

use core::{future::Future, task::Poll};

use async_task::Task;
use executor::EXECUTOR;
use pros_core::error::Result;

mod executor;
mod reactor;

/// Runs a future in the background without having to await it
/// To get the the return value you can await a task.
pub fn spawn<T>(future: impl Future<Output = T> + 'static) -> Task<T> {
executor::EXECUTOR.with(|e| e.spawn(future))
}

/// Blocks the current task untill a return value can be extracted from the provided future.
/// Does not poll all futures to completion.
pub fn block_on<F: Future + 'static>(future: F) -> F::Output {
executor::EXECUTOR.with(|e| e.block_on(spawn(future)))
}

/// A future that will complete after the given duration.
/// Sleep futures that are closer to completion are prioritized to improve accuracy.
#[derive(Debug)]
pub struct SleepFuture {
target_millis: u32,
}
impl Future for SleepFuture {
type Output = ();

fn poll(
self: core::pin::Pin<&mut Self>,
cx: &mut core::task::Context<'_>,
) -> core::task::Poll<Self::Output> {
if self.target_millis < unsafe { pros_sys::millis() } {
Poll::Ready(())
} else {
EXECUTOR.with(|e| {
e.reactor
.borrow_mut()
.sleepers
.push(cx.waker().clone(), self.target_millis)
});
Poll::Pending
}
}
}

/// Returns a future that will complete after the given duration.
pub fn sleep(duration: core::time::Duration) -> SleepFuture {
SleepFuture {
target_millis: unsafe { pros_sys::millis() + duration.as_millis() as u32 },
}
}

/// A trait for robot code that spins up the pros-rs async executor.
/// This is the preferred trait to run robot code.
pub trait AsyncRobot {
/// Runs during the operator control period.
/// This function may be called more than once.
/// For that reason, do not use `Peripherals::take`in this function.
fn opcontrol(&mut self) -> impl Future<Output = Result> {
async { Ok(()) }
}
/// Runs during the autonomous period.
fn auto(&mut self) -> impl Future<Output = Result> {
async { Ok(()) }
}
/// Runs continuously during the disabled period.
fn disabled(&mut self) -> impl Future<Output = Result> {
async { Ok(()) }
}
/// Runs once when the competition system is initialized.
fn comp_init(&mut self) -> impl Future<Output = Result> {
async { Ok(()) }
}
}

#[doc(hidden)]
#[macro_export]
macro_rules! __gen_async_exports {
($rbt:ty) => {
pub static mut ROBOT: Option<$rbt> = None;

#[doc(hidden)]
#[no_mangle]
extern "C" fn opcontrol() {
$crate::block_on(<$rbt as $crate::AsyncRobot>::opcontrol(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before opcontrol")
}))
.unwrap();
}

#[doc(hidden)]
#[no_mangle]
extern "C" fn autonomous() {
$crate::block_on(<$rbt as $crate::AsyncRobot>::auto(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before auto")
}))
.unwrap();
}

#[doc(hidden)]
#[no_mangle]
extern "C" fn disabled() {
$crate::block_on(<$rbt as $crate::AsyncRobot>::disabled(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before disabled")
}))
.unwrap();
}

#[doc(hidden)]
#[no_mangle]
extern "C" fn competition_initialize() {
$crate::block_on(<$rbt as $crate::AsyncRobot>::comp_init(unsafe {
ROBOT
.as_mut()
.expect("Expected initialize to run before comp_init")
}))
.unwrap();
}
};
}

/// Allows your async robot code to be executed by the pros kernel.
/// If your robot struct implements Default then you can just supply this macro with its type.
/// If not, you can supply an expression that returns your robot type to initialize your robot struct.
/// The code that runs to create your robot struct will run in the initialize function in PROS.
///
/// Example of using the macro with a struct that implements Default:
/// ```rust
/// use pros::prelude::*;
/// #[derive(Default)]
/// struct ExampleRobot;
/// #[async_trait]
/// impl AsyncRobot for ExampleRobot {
/// asnyc fn opcontrol(&mut self) -> pros::Result {
/// println!("Hello, world!");
/// Ok(())
/// }
/// }
/// async_robot!(ExampleRobot);
/// ```
///
/// Example of using the macro with a struct that does not implement Default:
/// ```rust
/// use pros::prelude::*;
/// struct ExampleRobot {
/// x: i32,
/// }
/// #[async_trait]
/// impl AsyncRobot for ExampleRobot {
/// async fn opcontrol(&mut self) -> pros::Result {
/// println!("Hello, world! {}", self.x);
/// Ok(())
/// }
/// }
/// impl ExampleRobot {
/// pub fn new() -> Self {
/// Self { x: 5 }
/// }
/// }
/// async_robot!(ExampleRobot, ExampleRobot::new());
#[macro_export]
macro_rules! async_robot {
($rbt:ty) => {
$crate::__gen_async_exports!($rbt);

#[no_mangle]
extern "C" fn initialize() {
unsafe {
ROBOT = Some(Default::default());
}
}
};
($rbt:ty, $init:expr) => {
$crate::__gen_async_exports!($rbt);

#[no_mangle]
extern "C" fn initialize() {
unsafe {
ROBOT = Some($init);
}
}
};
}
21 changes: 21 additions & 0 deletions packages/pros-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "pros-core"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
pros-sys = { version = "0.7.0", path = "../pros-sys" }
no_std_io = { version = "0.6.0", features = ["alloc"] }
snafu = { version = "0.8.0", default-features = false, features = [
"rust_1_61",
"unstable-core-error",
] }
spin = "0.9.8"

[target.'cfg(target_arch = "wasm32")'.dependencies]
dlmalloc = { version = "0.2.4", features = ["global"] }

[lints]
workspace = true
6 changes: 6 additions & 0 deletions packages/pros-core/src/allocator/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//! Simple allocator using the VEX libc allocation functions in vexos and jemalloc in the sim.
#[cfg(target_os = "vexos")]
mod vexos;
#[cfg(target_arch = "wasm32")]
mod wasm;
File renamed without changes.
Loading

0 comments on commit 245a86a

Please sign in to comment.