1use core::fmt;
6
7pub type Result<T> = core::result::Result<T, Error>;
9
10#[derive(Debug, Clone, PartialEq)]
12pub enum Error {
13 Config(ConfigError),
15 Motor(MotorError),
17 Motion(MotionError),
19 Trajectory(TrajectoryError),
21}
22
23#[derive(Debug, Clone, PartialEq)]
25pub enum ConfigError {
26 ParseError(heapless::String<128>),
28 InvalidMicrosteps(u16),
30 MotorNotFound(heapless::String<32>),
32 TrajectoryNotFound(heapless::String<32>),
34 DuplicateMotorName(heapless::String<32>),
36 DuplicateTrajectoryName(heapless::String<32>),
38 InvalidVelocityPercent(u8),
40 InvalidAccelerationPercent(u8),
42 InvalidGearRatio(f32),
44 InvalidMaxVelocity(f32),
46 InvalidMaxAcceleration(f32),
48 InvalidSoftLimits {
50 min: f32,
52 max: f32,
54 },
55 #[cfg(feature = "std")]
57 IoError(heapless::String<128>),
58}
59
60#[derive(Debug, Clone, PartialEq)]
62pub enum MotorError {
63 PinError,
65 InvalidState(heapless::String<32>),
67 NotInitialized,
69 LimitExceeded {
71 position: i64,
73 limit: i64,
75 },
76}
77
78#[derive(Debug, Clone, PartialEq)]
80pub enum MotionError {
81 VelocityExceedsLimit {
83 requested: f32,
85 max: f32,
87 },
88 AccelerationExceedsLimit {
90 requested: f32,
92 max: f32,
94 },
95 MoveTooShort {
97 steps: i64,
99 minimum: i64,
101 },
102 Overflow,
104}
105
106#[derive(Debug, Clone, PartialEq)]
108pub enum TrajectoryError {
109 MotorNotFound {
111 trajectory: heapless::String<32>,
113 motor: heapless::String<32>,
115 },
116 TargetExceedsLimits {
118 target: f32,
120 min: f32,
122 max: f32,
124 },
125 EmptyWaypoints,
127 TooManyWaypoints,
129 InvalidName(heapless::String<64>),
131 Empty,
133}
134
135impl fmt::Display for Error {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 match self {
138 Error::Config(e) => write!(f, "Configuration error: {}", e),
139 Error::Motor(e) => write!(f, "Motor error: {}", e),
140 Error::Motion(e) => write!(f, "Motion error: {}", e),
141 Error::Trajectory(e) => write!(f, "Trajectory error: {}", e),
142 }
143 }
144}
145
146impl fmt::Display for ConfigError {
147 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
148 match self {
149 ConfigError::ParseError(msg) => write!(f, "Parse error: {}", msg),
150 ConfigError::InvalidMicrosteps(v) => {
151 write!(f, "Invalid microsteps: {}. Valid values: 1, 2, 4, 8, 16, 32, 64, 128, 256", v)
152 }
153 ConfigError::MotorNotFound(name) => write!(f, "Motor '{}' not found", name),
154 ConfigError::TrajectoryNotFound(name) => write!(f, "Trajectory '{}' not found", name),
155 ConfigError::DuplicateMotorName(name) => write!(f, "Duplicate motor name: '{}'", name),
156 ConfigError::DuplicateTrajectoryName(name) => write!(f, "Duplicate trajectory name: '{}'", name),
157 ConfigError::InvalidVelocityPercent(v) => write!(f, "Invalid velocity percent: {}. Must be 1-200", v),
158 ConfigError::InvalidAccelerationPercent(v) => write!(f, "Invalid acceleration percent: {}. Must be 1-200", v),
159 ConfigError::InvalidGearRatio(v) => write!(f, "Invalid gear ratio: {}. Must be > 0", v),
160 ConfigError::InvalidMaxVelocity(v) => write!(f, "Invalid max velocity: {}. Must be > 0", v),
161 ConfigError::InvalidMaxAcceleration(v) => write!(f, "Invalid max acceleration: {}. Must be > 0", v),
162 ConfigError::InvalidSoftLimits { min, max } => {
163 write!(f, "Invalid soft limits: min ({}) must be < max ({})", min, max)
164 }
165 #[cfg(feature = "std")]
166 ConfigError::IoError(msg) => write!(f, "I/O error: {}", msg),
167 }
168 }
169}
170
171impl fmt::Display for MotorError {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 match self {
174 MotorError::PinError => write!(f, "GPIO pin operation failed"),
175 MotorError::InvalidState(state) => write!(f, "Invalid motor state: {}", state),
176 MotorError::NotInitialized => write!(f, "Motor not initialized"),
177 MotorError::LimitExceeded { position, limit } => {
178 write!(f, "Position {} exceeds limit {}", position, limit)
179 }
180 }
181 }
182}
183
184impl fmt::Display for MotionError {
185 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186 match self {
187 MotionError::VelocityExceedsLimit { requested, max } => {
188 write!(f, "Requested velocity {} exceeds maximum {}", requested, max)
189 }
190 MotionError::AccelerationExceedsLimit { requested, max } => {
191 write!(f, "Requested acceleration {} exceeds maximum {}", requested, max)
192 }
193 MotionError::MoveTooShort { steps, minimum } => {
194 write!(f, "Move of {} steps too short, minimum is {}", steps, minimum)
195 }
196 MotionError::Overflow => write!(f, "Motion profile computation overflow"),
197 }
198 }
199}
200
201impl fmt::Display for TrajectoryError {
202 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
203 match self {
204 TrajectoryError::MotorNotFound { trajectory, motor } => {
205 write!(f, "Trajectory '{}' references unknown motor '{}'", trajectory, motor)
206 }
207 TrajectoryError::TargetExceedsLimits { target, min, max } => {
208 write!(f, "Target position {} exceeds limits [{}, {}]", target, min, max)
209 }
210 TrajectoryError::EmptyWaypoints => write!(f, "Waypoint list is empty"),
211 TrajectoryError::TooManyWaypoints => {
212 write!(f, "Too many waypoints (max 32)")
213 }
214 TrajectoryError::InvalidName(name) => {
215 write!(f, "Invalid trajectory name or configuration: {}", name)
216 }
217 TrajectoryError::Empty => write!(f, "Trajectory is empty (no waypoints or target)"),
218 }
219 }
220}
221
222impl From<ConfigError> for Error {
224 fn from(e: ConfigError) -> Self {
225 Error::Config(e)
226 }
227}
228
229impl From<MotorError> for Error {
230 fn from(e: MotorError) -> Self {
231 Error::Motor(e)
232 }
233}
234
235impl From<MotionError> for Error {
236 fn from(e: MotionError) -> Self {
237 Error::Motion(e)
238 }
239}
240
241impl From<TrajectoryError> for Error {
242 fn from(e: TrajectoryError) -> Self {
243 Error::Trajectory(e)
244 }
245}
246
247#[cfg(feature = "std")]
248impl std::error::Error for Error {}
249
250#[cfg(feature = "std")]
251impl std::error::Error for ConfigError {}
252
253#[cfg(feature = "std")]
254impl std::error::Error for MotorError {}
255
256#[cfg(feature = "std")]
257impl std::error::Error for MotionError {}
258
259#[cfg(feature = "std")]
260impl std::error::Error for TrajectoryError {}