Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[choreo] Frontend typing cleanup #721

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
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
16 changes: 10 additions & 6 deletions src-core/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,21 @@ pub struct OpenFilePayload {
/// A trait for types that can be snapshotted.
/// This allows for the type to be converted to a f64.
/// This trait is only implemented for [`f64`] and [`Expr`].
pub trait SnapshottableType: Debug + Clone {
fn snapshot(&self) -> f64;
pub trait ExprOrNumber: Debug + Clone {
fn as_number(&self) -> f64;
}

impl SnapshottableType for f64 {
impl ExprOrNumber for f64 {
#[inline]
fn snapshot(&self) -> f64 {
fn as_number(&self) -> f64 {
*self
}
}

/// A struct that represents an expression.
///
/// The string is a mathematical expression that can be evaluated to a number.
/// The number is the result of evaluating the expression.
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Expr(pub String, pub f64);
impl Expr {
Expand All @@ -33,9 +37,9 @@ impl Expr {
Self(name.to_string(), value)
}
}
impl SnapshottableType for Expr {
impl ExprOrNumber for Expr {
#[inline]
fn snapshot(&self) -> f64 {
fn as_number(&self) -> f64 {
self.1
}
}
44 changes: 22 additions & 22 deletions src-core/src/spec/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use trajoptlib::Translation2d;

use super::{traj::DriveType, Expr, SnapshottableType};
use super::{traj::DriveType, Expr, ExprOrNumber};

#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub enum Dimension {
Expand Down Expand Up @@ -36,34 +36,34 @@ pub struct Variables {
pub poses: HashMap<String, PoseVariable>,
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub struct Bumper<T: SnapshottableType> {
pub struct Bumper<T: ExprOrNumber> {
pub front: T,
pub left: T,
pub back: T,
pub right: T,
}

impl<T: SnapshottableType> Bumper<T> {
impl<T: ExprOrNumber> Bumper<T> {
pub fn snapshot(&self) -> Bumper<f64> {
Bumper {
front: self.front.snapshot(),
left: self.left.snapshot(),
back: self.back.snapshot(),
right: self.right.snapshot(),
front: self.front.as_number(),
left: self.left.as_number(),
back: self.back.as_number(),
right: self.right.as_number(),
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub struct Module<T: SnapshottableType> {
pub struct Module<T: ExprOrNumber> {
pub x: T,
pub y: T,
}

impl<T: SnapshottableType> Module<T> {
impl<T: ExprOrNumber> Module<T> {
pub fn snapshot(&self) -> Module<f64> {
Module {
x: self.x.snapshot(),
y: self.y.snapshot(),
x: self.x.as_number(),
y: self.y.as_number(),
}
}
}
Expand All @@ -77,7 +77,7 @@ impl Module<f64> {
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy)]
pub struct RobotConfig<T: SnapshottableType> {
pub struct RobotConfig<T: ExprOrNumber> {
pub modules: [Module<T>; 4],
pub mass: T,
pub inertia: T,
Expand All @@ -90,26 +90,26 @@ pub struct RobotConfig<T: SnapshottableType> {
pub bumper: Bumper<T>,
}

impl<T: SnapshottableType> RobotConfig<T> {
impl<T: ExprOrNumber> RobotConfig<T> {
pub fn snapshot(&self) -> RobotConfig<f64> {
RobotConfig {
modules: self.modules.clone().map(|modu: Module<T>| modu.snapshot()),
mass: self.mass.snapshot(),
inertia: self.inertia.snapshot(),
gearing: self.gearing.snapshot(),
radius: self.radius.snapshot(),
vmax: self.vmax.snapshot(),
tmax: self.tmax.snapshot(),
mass: self.mass.as_number(),
inertia: self.inertia.as_number(),
gearing: self.gearing.as_number(),
radius: self.radius.as_number(),
vmax: self.vmax.as_number(),
tmax: self.tmax.as_number(),
bumper: self.bumper.snapshot(),
}
}
}
impl<T: SnapshottableType> RobotConfig<T> {
impl<T: ExprOrNumber> RobotConfig<T> {
pub fn wheel_max_torque(&self) -> f64 {
self.tmax.snapshot() * self.gearing.snapshot()
self.tmax.as_number() * self.gearing.as_number()
}
pub fn wheel_max_velocity(&self) -> f64 {
self.vmax.snapshot() / self.gearing.snapshot()
self.vmax.as_number() / self.gearing.as_number()
}
}

Expand Down
91 changes: 65 additions & 26 deletions src-core/src/spec/traj.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use serde::{Deserialize, Serialize};
use trajoptlib::{DifferentialTrajectorySample, SwerveTrajectorySample};

use super::{Expr, SnapshottableType};
use super::{Expr, ExprOrNumber};

#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
#[serde(rename_all = "camelCase")]
/// A waypoint parameter.
pub struct Waypoint<T: SnapshottableType> {
pub struct Waypoint<T: ExprOrNumber> {
/// The x coordinate of the waypoint (blue origin).
///
/// Units: meters
Expand Down Expand Up @@ -36,12 +36,12 @@ pub struct Waypoint<T: SnapshottableType> {
}

#[allow(missing_docs)]
impl<T: SnapshottableType> Waypoint<T> {
impl<T: ExprOrNumber> Waypoint<T> {
pub fn snapshot(&self) -> Waypoint<f64> {
Waypoint {
x: self.x.snapshot(),
y: self.y.snapshot(),
heading: self.heading.snapshot(),
x: self.x.as_number(),
y: self.y.as_number(),
heading: self.heading.as_number(),
intervals: self.intervals,
split: self.split,
fix_translation: self.fix_translation,
Expand Down Expand Up @@ -108,7 +108,7 @@ pub enum ConstraintScope {
/// A constraint on the robot's motion.
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
#[serde(tag = "type", content = "props")]
pub enum ConstraintData<T: SnapshottableType> {
pub enum ConstraintData<T: ExprOrNumber> {
/// A constraint on the maximum velocity.
MaxVelocity {
/// The maximum velocity.
Expand Down Expand Up @@ -149,7 +149,7 @@ pub enum ConstraintData<T: SnapshottableType> {
KeepInRectangle { x: T, y: T, w: T, h: T },
}

impl<T: SnapshottableType> ConstraintData<T> {
impl<T: ExprOrNumber> ConstraintData<T> {
/// The scope of the constraint.
pub fn scope(&self) -> ConstraintScope {
match self {
Expand All @@ -162,44 +162,44 @@ impl<T: SnapshottableType> ConstraintData<T> {
pub fn snapshot(&self) -> ConstraintData<f64> {
match self {
ConstraintData::MaxVelocity { max } => ConstraintData::MaxVelocity {
max: max.snapshot(),
max: max.as_number(),
},
ConstraintData::MaxAngularVelocity { max } => ConstraintData::MaxAngularVelocity {
max: max.snapshot(),
max: max.as_number(),
},
ConstraintData::PointAt {
x,
y,
tolerance,
flip,
} => ConstraintData::PointAt {
x: x.snapshot(),
y: y.snapshot(),
tolerance: tolerance.snapshot(),
x: x.as_number(),
y: y.as_number(),
tolerance: tolerance.as_number(),
flip: *flip,
},
ConstraintData::MaxAcceleration { max } => ConstraintData::MaxAcceleration {
max: max.snapshot(),
max: max.as_number(),
},
ConstraintData::StopPoint {} => ConstraintData::StopPoint {},
ConstraintData::KeepInCircle { x, y, r } => ConstraintData::KeepInCircle {
x: x.snapshot(),
y: y.snapshot(),
r: r.snapshot(),
x: x.as_number(),
y: y.as_number(),
r: r.as_number(),
},
ConstraintData::KeepInRectangle { x, y, w, h } => ConstraintData::KeepInRectangle {
x: x.snapshot(),
y: y.snapshot(),
w: w.snapshot(),
h: h.snapshot(),
x: x.as_number(),
y: y.as_number(),
w: w.as_number(),
h: h.as_number(),
},
}
}
}

/// A constraint on the robot's motion and where it applies.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Constraint<T: SnapshottableType> {
pub struct Constraint<T: ExprOrNumber> {
/// The waypoint the constraint starts at.
pub from: WaypointID,
/// The waypoint the constraint ends at.
Expand All @@ -210,7 +210,7 @@ pub struct Constraint<T: SnapshottableType> {
pub data: ConstraintData<T>,
}

impl<T: SnapshottableType> Constraint<T> {
impl<T: ExprOrNumber> Constraint<T> {
#[allow(missing_docs)]
pub fn snapshot(&self) -> Constraint<f64> {
Constraint::<f64> {
Expand All @@ -223,7 +223,7 @@ impl<T: SnapshottableType> Constraint<T> {

/// A constraint on the robot's motion and where it applies.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct ConstraintIDX<T: SnapshottableType> {
pub struct ConstraintIDX<T: ExprOrNumber> {
/// The index of the waypoint the constraint starts at.
pub from: usize,
/// The index of the waypoint the constraint ends at.
Expand Down Expand Up @@ -344,14 +344,14 @@ pub enum DriveType {

/// The parameters used for generating a trajectory.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct Parameters<T: SnapshottableType> {
pub struct Parameters<T: ExprOrNumber> {
/// The waypoints the robot will pass through or use for initial guess.
pub waypoints: Vec<Waypoint<T>>,
/// The constraints on the robot's motion.
pub constraints: Vec<Constraint<T>>,
}

impl<T: SnapshottableType> Parameters<T> {
impl<T: ExprOrNumber> Parameters<T> {
#[allow(missing_docs)]
pub fn snapshot(&self) -> Parameters<f64> {
Parameters {
Expand Down Expand Up @@ -388,6 +388,14 @@ pub struct TrajFile {
pub params: Parameters<Expr>,
/// The trajectory the robot will follow.
pub traj: Trajectory,
/// The choreo events.
#[serde(default)]
pub events: Vec<EventMarker>,
/// The pplib commands to execute.
/// This is a compatibility layer for working with
/// the path planner library.
#[serde(default)]
pub pplib_commands: Vec<PplibCommandMarker>,
}

impl TrajFile {
Expand All @@ -402,3 +410,34 @@ impl TrajFile {
serde_json::from_str(content).map_err(Into::into)
}
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PplibCommandMarker {
pub name: String,
pub target: Option<usize>,
pub traj_target_index: Option<usize>,
pub target_timestamp: Option<f64>,
pub offset: f64,
pub command: PplibCommand,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "type", content = "data")]
pub enum PplibCommand {
Named { name: String },
Wait { wait_time: f64 },
Sequential { commands: Vec<PplibCommand> },
Parallel { commands: Vec<PplibCommand> },
Race { commands: Vec<PplibCommand> },
Deadline { commands: Vec<PplibCommand> },
}

#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct EventMarker {
/// The name of the event.
pub event: String,
/// The offset from the beginning of the trajectory.
pub timestamp: f64,
}
2 changes: 1 addition & 1 deletion src/AppMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
} from "./document/DocumentManager";

import SettingsModal from "./components/config/SettingsModal";
import { Commands } from "./document/tauriCommands";
import { Commands } from "./document/Backend";
import { version } from "./util/version";

type Props = object;
Expand Down
2 changes: 1 addition & 1 deletion src/components/config/CircularObstacleConfigPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { observer } from "mobx-react";
import { Component } from "react";
import styles from "./WaypointConfigPanel.module.css";
import { ICircularObstacleStore } from "../../document/CircularObstacleStore";
import { ICircularObstacleStore } from "../../document/stores/CircularObstacleStore";
import ExpressionInput from "../input/ExpressionInput";
import ExpressionInputList from "../input/ExpressionInputList";

Expand Down
2 changes: 1 addition & 1 deletion src/components/config/ConstraintsConfigPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { observer } from "mobx-react";
import { Component } from "react";
import { IConstraintStore } from "../../document/ConstraintStore";
import { IConstraintStore } from "../../document/stores//ConstraintStore";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extra slash here, does that even work?

import BooleanInput from "../input/BooleanInput";
import ExpressionInput from "../input/ExpressionInput";
import ExpressionInputList from "../input/ExpressionInputList";
Expand Down
2 changes: 1 addition & 1 deletion src/components/config/ScopeSlider.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Slider, SliderProps } from "@mui/material";
import { observer } from "mobx-react";
import { Component } from "react";
import { IHolonomicWaypointStore } from "../../document/HolonomicWaypointStore";
import { IHolonomicWaypointStore } from "../../document/stores/HolonomicWaypointStore";

type Props = {
isRange: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/components/config/WaypointConfigPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ToggleButton, ToggleButtonGroup, Tooltip } from "@mui/material";
import { observer } from "mobx-react";
import { Component, ReactElement } from "react";
import { IHolonomicWaypointStore } from "../../document/HolonomicWaypointStore";
import { IHolonomicWaypointStore } from "../../document/stores/HolonomicWaypointStore";
import { WaypointData } from "../../document/UIData";
import BooleanInput from "../input/BooleanInput";
import ExpressionInput from "../input/ExpressionInput";
Expand Down
2 changes: 1 addition & 1 deletion src/components/config/eventmarker/CommandDraggable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
CommandType,
CommandUIData,
ICommandStore
} from "../../../document/EventMarkerStore";
} from "../../../document/stores/PplibCommandMarkerStore";
import ExpressionInput from "../../input/ExpressionInput";
import ExpressionInputList from "../../input/ExpressionInputList";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DragDropContext } from "@hello-pangea/dnd";
import {
CommandStore,
IEventMarkerStore
} from "../../../document/EventMarkerStore";
} from "../../../document/stores/PplibCommandMarkerStore";
import ExpressionInput from "../../input/ExpressionInput";
import ExpressionInputList from "../../input/ExpressionInputList";
import InputStyles from "../../input/InputList.module.css";
Expand Down
Loading
Loading