Overview
The movement module provides advanced autonomous movement algorithms for robot control, including PID-based motion, boomerang curves, path following, and pure pursuit. These functions are designed for VEX robotics competitions and implement industry-standard motion control techniques.
Movement Functions
pidMTPVel
pub fn pidMTPVel(
position: (f32, f32),
heading: f32,
target: (f32, f32),
rotationCut: f32,
lCont: &mut util::Pid,
rCont: &mut util::Pid,
min: f32
) -> (f32, f32)
Calculates left and right wheel velocities to move toward a target point using PID control.
Current robot position in pixels as (x, y)
Current robot heading in degrees (0-360)
Target position to move toward as (x, y)
Angle threshold in degrees for applying cosine scaling to forward velocity. Typical value: 90.0
PID controller for linear (forward) velocity
PID controller for angular (rotational) velocity
Minimum forward velocity to prevent stalling. Set to 0.0 to allow stopping
Returns: (f32, f32) - Left and right wheel velocities
Example:
use mars_rs::{movement, util};
let mut linear_pid = util::Pid::new(util::PidConstants {
p: 0.05,
i: 0.0,
d: 0.0,
tolerance: 5.0,
integralThreshold: 50.0,
maxIntegral: 100.0
});
let mut rotation_pid = util::Pid::new(util::PidConstants {
p: 0.015,
i: 0.0,
d: 0.0,
tolerance: 2.0,
integralThreshold: 30.0,
maxIntegral: 50.0
});
let velocities = movement::pidMTPVel(
(400.0, 300.0), // current position
45.0, // current heading
(600.0, 400.0), // target position
90.0, // rotation cut
&mut linear_pid,
&mut rotation_pid,
0.5 // minimum velocity
);
println!("Left: {}, Right: {}", velocities.0, velocities.1);
The rotation cut parameter controls when forward velocity is reduced due to large heading errors. When the heading error exceeds the rotation cut, forward velocity is scaled to 0.1 to prioritize turning.
pidMTP
pub fn pidMTP(
robot: &Arc<Mutex<robot::Robot>>,
target: (f32, f32),
rotationCut: f32,
timeout: u16,
lConstants: util::PidConstants,
rConstants: util::PidConstants,
min: f32
)
Move To Point: Autonomously moves the robot to a target position using PID control.
robot
&Arc<Mutex<Robot>>
required
Thread-safe reference to the robot
Target position coordinates
Angle threshold for velocity scaling (typically 90.0)
Maximum movement time in milliseconds
lConstants
util::PidConstants
required
PID constants for linear velocity control
rConstants
util::PidConstants
required
PID constants for rotational velocity control
Example:
use mars_rs::{robot::Robot, movement, util};
use std::sync::{Arc, Mutex};
let robot = Arc::new(Mutex::new(Robot {
position: (400.0, 300.0),
heading: 0.0,
robotSize: 30.0
}));
let pid_constants = util::PidConstants {
p: 0.05,
i: 0.001,
d: 0.01,
tolerance: 5.0,
integralThreshold: 50.0,
maxIntegral: 100.0
};
movement::pidMTP(
&robot,
(600.0, 400.0),
90.0,
3000, // 3 second timeout
pid_constants,
pid_constants,
0.5
);
boomerang
pub fn boomerang(
robot: &Arc<Mutex<robot::Robot>>,
target: (f32, f32),
timeout: u16,
dLead: f32,
thetaEnd: f32,
rotationCut: f32,
lConstants: util::PidConstants,
rConstants: util::PidConstants,
min: f32
)
Moves the robot to a target point while smoothly arriving at a specific heading angle. Creates smooth, curved trajectories.
robot
&Arc<Mutex<Robot>>
required
Thread-safe reference to the robot
Maximum movement time in milliseconds
Lead distance for the carrot point (typically 0.3-0.7)
Desired final heading angle in radians
Angle threshold for velocity scaling
lConstants
util::PidConstants
required
PID constants for linear control
rConstants
util::PidConstants
required
PID constants for rotation control
Example:
use mars_rs::{robot::Robot, movement, util};
use std::sync::{Arc, Mutex};
use std::f32::consts::PI;
let robot = Arc::new(Mutex::new(Robot {
position: (400.0, 300.0),
heading: 0.0,
robotSize: 30.0
}));
let pid_constants = util::PidConstants {
p: 0.05,
i: 0.0,
d: 0.0,
tolerance: 5.0,
integralThreshold: 50.0,
maxIntegral: 100.0
};
// Move to target while ending at 90 degrees
movement::boomerang(
&robot,
(600.0, 400.0),
3000,
0.5, // lead distance
PI / 2.0, // end at 90 degrees
90.0,
pid_constants,
pid_constants,
0.5
);
Boomerang creates smooth, curved paths by following a “carrot” point that leads toward the target. Adjust dLead to control how aggressive the curve is.
followPath
pub fn followPath(
robot: &Arc<Mutex<robot::Robot>>,
path: Vec<(f32, f32)>,
timeout: u32,
dLead: f32,
thetaEnd: f32,
rotationCut: f32,
lConstants: util::PidConstants,
rConstants: util::PidConstants,
min: f32
)
Follows a sequence of waypoints using smooth transitions between points.
robot
&Arc<Mutex<Robot>>
required
Thread-safe reference to the robot
Ordered list of waypoints to follow
Maximum time for entire path in milliseconds
Lead distance for carrot point
Heading adjustment parameter (use 0.0 for default)
Angle threshold for velocity scaling
lConstants
util::PidConstants
required
PID constants for linear control
rConstants
util::PidConstants
required
PID constants for rotation control
Example:
use mars_rs::{robot::Robot, movement, util};
use std::sync::{Arc, Mutex};
let robot = Arc::new(Mutex::new(Robot {
position: (400.0, 300.0),
heading: 0.0,
robotSize: 30.0
}));
let path = vec![
(450.0, 350.0),
(500.0, 400.0),
(550.0, 450.0),
(600.0, 400.0)
];
let pid_constants = util::PidConstants {
p: 0.05,
i: 0.0,
d: 0.0,
tolerance: 5.0,
integralThreshold: 50.0,
maxIntegral: 100.0
};
movement::followPath(
&robot,
path,
5000, // 5 second timeout
0.5,
0.0,
90.0,
pid_constants,
pid_constants,
0.5
);
The robot advances to the next waypoint when it comes within 40 pixels of the current target. Adjust this threshold in the source if you need different behavior.
moveToPurePursuit
pub fn moveToPurePursuit(
robot: &Arc<Mutex<robot::Robot>>,
path: Vec<(f32, f32)>,
lookAhead: f32,
lineLookAhead: usize,
finalTimeout: u16
)
Implements pure pursuit path following algorithm with look-ahead for smooth, predictive path tracking.
robot
&Arc<Mutex<Robot>>
required
Thread-safe reference to the robot
List of waypoints defining the path
Look-ahead distance in pixels (typically 50-100)
Number of path segments to search ahead (typically 3-5)
Maximum time in milliseconds
Example:
use mars_rs::{robot::Robot, movement};
use std::sync::{Arc, Mutex};
let robot = Arc::new(Mutex::new(Robot {
position: (400.0, 300.0),
heading: 0.0,
robotSize: 30.0
}));
let path = vec![
(400.0, 300.0),
(450.0, 350.0),
(500.0, 400.0),
(550.0, 450.0),
(600.0, 500.0)
];
movement::moveToPurePursuit(
&robot,
path,
75.0, // look-ahead distance
4, // segments to look ahead
5000 // 5 second timeout
);
Pure pursuit is excellent for smooth, high-speed path following. The algorithm finds intersection points between a look-ahead circle and the path, creating natural curved trajectories.
eulerTurn
pub fn eulerTurn(
robot: &Arc<Mutex<robot::Robot>>,
theta: f32,
rate: f32,
curvature: f32,
timeout: u32,
dir: i8,
constants: util::PidConstants
) -> f32
Performs a smooth turn to a target heading using Euler integration with variable curvature.
robot
&Arc<Mutex<Robot>>
required
Thread-safe reference to the robot
Target heading in degrees
Rate of curvature change per iteration
Maximum turn time in milliseconds
Turn direction: 1 for clockwise, -1 for counterclockwise
constants
util::PidConstants
required
PID constants for turn control
Returns: f32 - Final curvature value after turn completes
Example:
use mars_rs::{robot::Robot, movement, util};
use std::sync::{Arc, Mutex};
let robot = Arc::new(Mutex::new(Robot {
position: (400.0, 300.0),
heading: 0.0,
robotSize: 30.0
}));
let pid_constants = util::PidConstants {
p: 0.8,
i: 0.0,
d: 0.1,
tolerance: 2.0,
integralThreshold: 10.0,
maxIntegral: 50.0
};
// Turn to 90 degrees
let final_curvature = movement::eulerTurn(
&robot,
90.0, // target angle
0.001, // curvature rate
0.0, // initial curvature
2000, // 2 second timeout
1, // clockwise
pid_constants
);
PID Tuning Guide
Linear Movement
let linear_constants = util::PidConstants {
p: 0.05, // Start low, increase until responsive
i: 0.001, // Add small integral for steady-state error
d: 0.01, // Add derivative to reduce overshoot
tolerance: 5.0, // Error threshold to reset integral
integralThreshold: 50.0,
maxIntegral: 100.0
};
Rotation Control
let rotation_constants = util::PidConstants {
p: 0.015, // Lower than linear for smoother turns
i: 0.0, // Often not needed for rotation
d: 0.005, // Helps prevent oscillation
tolerance: 2.0,
integralThreshold: 30.0,
maxIntegral: 50.0
};
See Also
- Robot - Robot structure and basic control
- Util - PID controller and helper functions
- Paths - Path creation and management