Skip to content
This repository was archived by the owner on Jun 19, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ Before releasing:
- Added support for getting motor fault flags (e.g. over-temperature, over-current, H-bridge faults).
- Added support for internal motor PID tuning. Feature gated behind `dangerous_motor_tuning`, as this can cause hardware damage and is not recommended.
- Added various constants for convenience around `Motor` and `Gearset`.
- An ``embedded_graphics`` driver in the new `pros_graphics` crate.
- New `graphics` and `embedded-graphics` features in the `pros` crate.

### Fixed

Expand Down
115 changes: 92 additions & 23 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 24 additions & 0 deletions packages/pros-graphics/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "pros-graphics"
version = "0.1.0"
edition = "2021"
license = "MIT"
description = "Core functionality for pros-rs"
keywords = ["PROS", "Robotics", "graphics", "vex", "v5"]
categories = [
"api-bindings",
"no-std",
"science::robotics",
]

[dependencies]
embedded-graphics-core = { version = "0.4.0", optional = true }
pros-devices = { version = "0.1.0", path = "../pros-devices" }
pros-sys = { version = "0.7.0", path = "../pros-sys" }

[lints]
workspace = true

[features]
default = []
embedded-graphics = ["dep:embedded-graphics-core"]
94 changes: 94 additions & 0 deletions packages/pros-graphics/src/embedded_graphics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//! An embedded_graphics driver for VEX V5 Brain displays.

use alloc::boxed::Box;

use embedded_graphics_core::{
draw_target::DrawTarget,
geometry::{Dimensions, Point, Size},
pixelcolor::{Rgb888, RgbColor},
primitives::Rectangle,
Pixel,
};
use pros_devices::{color::Rgb, Screen};

/// An embedded_graphics driver for the V5 Brain display
pub struct V5BrainDisplay {
pixel_buffer:
Box<[u32; Screen::HORIZONTAL_RESOLUTION as usize * Screen::VERTICAL_RESOLUTION as usize]>,
}

impl V5BrainDisplay {
/// Creates a new VexDisplay from a Screen
pub fn new(_screen: Screen) -> Self {
let pixel_buffer = Box::new_zeroed();
let pixel_buffer = unsafe { pixel_buffer.assume_init() };

Self { pixel_buffer }
}

/// Draws the pixel buffer to the screen
///
/// # Note
///
/// I would use the [`Screen::draw_buffer`](pros_devices::screen::Screen::draw_buffer) API,
/// but unfortunately it stack overflows with a buffer this big and is more complicated.
fn draw_buffer(&self) {
// SAFETY: The pixel buffer is guarenteed to be large enough and live long enough and we take ownership of the screen when created.
unsafe {
pros_sys::screen_copy_area(
0,
0,
Screen::HORIZONTAL_RESOLUTION,
Screen::VERTICAL_RESOLUTION,
self.pixel_buffer.as_ptr(),
Screen::HORIZONTAL_RESOLUTION as _,
);
}
}
}

impl From<Screen> for V5BrainDisplay {
fn from(value: Screen) -> Self {
Self::new(value)
}
}

impl Dimensions for V5BrainDisplay {
fn bounding_box(&self) -> Rectangle {
Rectangle::new(
Point::new(0, 0),
Size::new(
Screen::HORIZONTAL_RESOLUTION as _,
Screen::VERTICAL_RESOLUTION as _,
),
)
}
}

impl DrawTarget for V5BrainDisplay {
type Color = Rgb888;
type Error = pros_devices::screen::ScreenError;

fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
where
I: IntoIterator<Item = Pixel<Self::Color>>,
{
pixels
.into_iter()
.map(|pixel| (pixel.0, Rgb::new(pixel.1.r(), pixel.1.g(), pixel.1.b())))
.for_each(|(pos, color)| {
// Make sure that the coordinate is valid to index with.
if !(pos.x > Screen::HORIZONTAL_RESOLUTION as _ || pos.x < 0)
&& !(pos.y > Screen::VERTICAL_RESOLUTION as _ || pos.y < 0)
{
// SAFETY: We initialize the buffer with zeroes, so it's safe to assume it's initialized.
self.pixel_buffer[pos.y as usize * Screen::HORIZONTAL_RESOLUTION as usize
+ pos.x as usize] = color.into();
}
});

self.draw_buffer();

Ok(())
}
}
13 changes: 13 additions & 0 deletions packages/pros-graphics/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//! Graphics driver implementations for the V5 Brain display.
//!
//! Currently supports:
//! - [embedded-graphics](https://crates.io/crates/embedded-graphics)
//! Implemented for the [`pros-rs`](https://crates.io/crates/pros) ecosystem and implemented using [pros-devices](https://crates.io/crates/pros-devices).
#![no_std]
#![cfg_attr(feature = "embedded-graphics", feature(new_uninit))]

#[cfg(feature = "embedded-graphics")]
extern crate alloc;

#[cfg(feature = "embedded-graphics")]
pub mod embedded_graphics;
4 changes: 4 additions & 0 deletions packages/pros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rust-version = "1.75.0"
pros-sync = { version = "0.1.0", path = "../pros-sync", optional = true }
pros-async = { version = "0.1.0", path = "../pros-async", optional = true }
pros-devices = { version = "0.1.0", path = "../pros-devices", optional = true }
pros-graphics = { version = "0.1.0", path = "../pros-graphics", optional = true }
pros-panic = { version = "0.1.0", path = "../pros-panic", optional = true }
pros-core = { version = "0.1.0", path = "../pros-core", optional = true }
pros-math = { version = "0.1.0", path = "../pros-math", optional = true }
Expand All @@ -36,6 +37,9 @@ sync = ["dep:pros-sync"]

devices = ["dep:pros-devices"]

graphics = ["dep:pros-graphics"]
embedded-graphics = ["pros-graphics/embedded-graphics"]

math = ["dep:pros-math"]

panic = ["dep:pros-panic"]
Expand Down
10 changes: 9 additions & 1 deletion packages/pros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub use pros_async as async_runtime;
pub use pros_core as core;
#[cfg(feature = "devices")]
pub use pros_devices as devices;
#[cfg(feature = "graphics")]
pub use pros_graphics as graphics;
#[cfg(feature = "math")]
pub use pros_math as math;
#[cfg(feature = "panic")]
Expand All @@ -82,6 +84,10 @@ pub mod prelude {
print, println,
task::delay,
};
#[cfg(all(not(feature = "graphics"), feature = "devices"))]
pub use pros_devices::screen::{
Circle, Line, Rect, Text, TextFormat, TextPosition, TouchState,
};
#[cfg(feature = "devices")]
pub use pros_devices::{
adi::{
Expand All @@ -99,7 +105,7 @@ pub mod prelude {
color::Rgb,
peripherals::{DynamicPeripherals, Peripherals},
position::Position,
screen::{Circle, Line, Rect, Screen, Text, TextFormat, TextPosition, TouchState},
screen::Screen,
smart::{
distance::DistanceSensor,
expander::AdiExpander,
Expand All @@ -113,6 +119,8 @@ pub mod prelude {
SmartDevice, SmartPort,
},
};
#[cfg(all(feature = "graphics", feature = "embedded-graphics"))]
pub use pros_graphics::embedded_graphics::V5BrainDisplay;
#[cfg(feature = "math")]
pub use pros_math::{feedforward::MotorFeedforwardController, pid::PidController};
#[cfg(feature = "sync")]
Expand Down