Skip to Content
VectorLib

Your first robot

Drivetrain, tracking wheels, IMU, controllers and the chassis, with LemLib's example constants.

Every value on this page is LemLib's example robot. Your PROS constants carry over unchanged: the same numbers move the robot the same way.

Drivetrain

src/main.rs
use vectorlib::prelude::*;
use vexide::prelude::*;

// left motor group: ports 5 and 3 reversed, port 4 forward
let left_motors = MotorGroup::new([
    Motor::new(peripherals.port_5, Gearset::Blue, Direction::Reverse),
    Motor::new(peripherals.port_4, Gearset::Blue, Direction::Forward),
    Motor::new(peripherals.port_3, Gearset::Blue, Direction::Reverse),
]);
let right_motors = MotorGroup::new([
    Motor::new(peripherals.port_6, Gearset::Blue, Direction::Forward),
    Motor::new(peripherals.port_9, Gearset::Blue, Direction::Reverse),
    Motor::new(peripherals.port_7, Gearset::Blue, Direction::Forward),
]);

let drivetrain = Drivetrain::new(
    left_motors,
    right_motors,
    10.0,             // track width, inches
    Omniwheel::NEW_4, // wheel diameter
    360.0,            // drivetrain rpm
    2.0,              // horizontal drift: 2 for omnis, 8 with traction wheels
);

Odometry sensors

let imu = InertialSensor::new(peripherals.port_10);
let horizontal_enc = RotationSensor::new(peripherals.port_20, Direction::Forward);
let vertical_enc = RotationSensor::new(peripherals.port_11, Direction::Reverse);

// 2.75" wheels; offsets are from the tracking centre, negative = left / behind
let horizontal = TrackingWheel::new(horizontal_enc, Omniwheel::NEW_275, -5.75, 1.0);
let vertical = TrackingWheel::new(vertical_enc, Omniwheel::NEW_275, -2.5, 1.0);

let sensors = OdomSensors::new(
    Some(vertical),   // vertical tracking wheel 1
    None,             // vertical tracking wheel 2
    Some(horizontal), // horizontal tracking wheel 1
    None,             // horizontal tracking wheel 2
    Some(imu),
);

Controllers, curves and the chassis

let lateral = ControllerSettings::new(
    10.0,  // kP
    0.0,   // kI
    3.0,   // kD
    3.0,   // anti windup
    1.0,   // small error range, inches
    100.0, // small error range timeout, ms
    3.0,   // large error range, inches
    500.0, // large error range timeout, ms
    20.0,  // maximum acceleration (slew)
);
let angular = ControllerSettings::new(2.0, 0.0, 10.0, 3.0, 1.0, 100.0, 3.0, 500.0, 0.0);

// deadband, minimum output, expo gain
let throttle_curve = ExpoDriveCurve::new(3.0, 10.0, 1.019);
let steer_curve = ExpoDriveCurve::new(3.0, 10.0, 1.019);

let chassis = Chassis::new(drivetrain, lateral, angular, sensors, throttle_curve, steer_curve);
chassis.calibrate(true).await; // calibrates the IMU and starts odometry

Chassis is a cheap handle: clone it to use the same chassis from a screen task, autonomous and driver control, the way a global lemlib::Chassis is shared between PROS tasks.

On this page