From 7b28c6a148b85c4eb632617a2e5cc05267514239 Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Fri, 8 Mar 2024 15:57:21 -0500 Subject: [PATCH 01/18] Added READ ME --- README.md | 183 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..1ef837cd --- /dev/null +++ b/README.md @@ -0,0 +1,183 @@ +#Pros With VOSS + +### Introduction +VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonomous code for VEX robots a piece of cake. + +## Installing VOSS +1. Download the most recent [template](https://github.com/purduesigbots/VOSS) + +2. Run this command from terminal `pros c fetch VOSS@0.1.0.zip` + +3. `cd` into your pros project directory in your terminal + +4. Apply the library to the project `pros c apply VOSS` + +5. Put `#include "VOSS/api.h"` in your main.h + +##Quick start guide +###Robot definitions +* 'LEFT_MOTORS' = list of motors on the left side of the drive +* 'RIGHT_MOTORS' = list of motors on the right side of the drive +* 'IMU_PORT' = the smart port number in which your imu is plugged into + +###Creating a localizer +* We will set up a IME localizer in global scope +1. 'Call' auto odom = voss::localizer::IMELocalizerBuilder::new_builder() +2. Setup inputs to localizer + * 'Left encoders' = .with_left_motors(LEFT_MOTORS) + * 'Right encoders' = .with_right_motors(RIGHT_Motors) + * 'IMU' = .with_imu(IMU_PORT) + * 'Left right TPi' is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with .with_left_right_tip(TIP value) +3. 'Call it to build' --> .build() +```cpp +auto odom = voss::localizer::IMELocalizerBuilder::new_builder() + .with_left_motors({-1, -2, -3}) + .with_right_motors({4, 5, 6}) + .with_left_right_tpi(20) + .with_track_width(5) + .with_imu(IMU_PORT) + .build(); + +void initialize() { + +} +``` + +###Creating a PID controller +* We will set up a PID controller for chassis movements in global scope +* 'Linear error' = Linear distance from desired position to current position +* 'Angular error' = Angular distance from desired position to current position +1. Required constants and their meaning + * 'Linear proportional constant' = Weight of how much linear error affects motor power (Speeds up the robot movements) + * 'Linear derivative constant' = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) + * 'Linear integral constant' = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) + * 'Linear exit error' = Allowed linear distance from point in inches for the robot to exit the movement + * 'Angular proportional constant' = Weight of how much Angular error affects motor power (Speeds up the robot movements) + * 'Angular derivative constant' = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) + * 'Angular integral constant' = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) + * 'Angular exit error' = Allowed Angular distance from point in degrees for the robot to exit the movement + * 'Minimum error' = linear distance allowed from desired position in inches where the robot will check if it has stopped moving + * 'Settle time' = defined time in miliseconds which the robot has not move in order to exit the movement when the desired point has not been reached +2. 'Call' auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) +3. Set up inputs to pid controller + * 'Linear proportional, derivative, and integral constant (in this order)' = .with_linear_constants(0.0, 0.0, 0.0) + * 'Angular proportional, derivative, and integral constant (in this order)' = .with_angular_constants(0.0, 0.0, 0.0) + * 'Linear exit error' = .with_exit_error(1.0) + * 'Angular exit error' = .with_angular_exit_error(1.0) + * 'Minimum exit error' = .with_min_error(5) + * 'Settle time' = .with_settle_time(200) +4. 'Call it to build' --> .build() +```cpp +auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) + .with_linear_constants(0.1, 0.1, 0.1) + .with_angular_constants(0.1, 0.1, 0.1) + .with_exit_error(1.0) + .with_angular_exit_error(1.0) + .with_min_error(5) + .with_settle_time(200) + .build(); + +void initialize() { + +} +``` + +###Creating the chassis object +* We will be creating a differential drive chassis in global scope +1. 'Call' voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT) +```cpp +voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT); + +void initialize() { + +} +``` + +###Starting the odometry localization +* We will be starting odomentry localization in the initalize scope +1. 'Call' odom->begin_localization() +```cpp +void initialize() { + odom->begin_localization(); +} +``` + +###Tuning localizer and controller +* We will be tuning the TPI (ticks per inch) of the localizer + 1. Move the robot forard a measured ammount + 2. Read the odometry value + 3. Divide the amount you moved the robot by the measured movement value from the odometry + * adjustment factor = robot actual move amount/odometry measured amount + 4. Set the new tpi value to the current tpi value multiplied by the value you got from step 3 + * new tip = old tpi x adjustment factor +* We will be tuning the PID controller constants + * This is a lot of guessing and making corrections based off of the behavior of the robot. This will change with any signifcant robot changes + * Tune linear constants first + 1. Start with the constants all being 0 + 2. Increase the proportional constant until oscillations start (the amount you need to increase by and total amount will vary with each robot) + 3. Slowly increase the derivative constant until the robot is no longer overshooting its target and oscilations have stopped + 4. If the robot is lowly compounding error over time, slowly increase the integral constant to reduce that error + * Tune the angular constants using steps 1-4 of tuning the linear constants +* For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/ +* Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers + +###Driver Control +* We will be setting up tank control scheme for the drive in the opcontrol scope +1. Define the controller + * 'Call' pros::Controller master(pros::E_CONTROLLER_MASTER) +2. Inside the while loop set the movement + * 'Call' chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y)) +```cpp +void opcontrol() { + pros::Controller master(pros::E_CONTROLLER_MASTER); + + while(true){ + chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y)); + } +} +``` + +###Autonomus Movement +*There are two types of basic movment calls which you can use to write an automous +1. Move + * Parameters + 1. 'Desired pose' = {x, y} + 2. 'Speed' = 0 - 100 + 3. 'Flags' = options of movements + * 'THRU' = No PID + * 'Async' = Next lines of code start executing even before movement is finished + * 'REVERSE' = Robot moves backwards + * 'Relative' = not absolute coordinate system + * 'NONE' = defualt + * 'Call' chassis.move(Parameters) +```cpp +void autonomous(){ + chassis.move({1.0, 1.0}); + chassis.move({1.0, 1.0}, 100); + chassis.move({1.0, 1.0}, 100, voss::Flags::RELATIVE); + chassis.move({1.0, 1.0}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC); +} +``` + +2. Turn + * Parameters + 1. 'Desired angle' + 2. 'Desired speed' + 3. 'Flags' = options of movements + * 'THUR' = No PID + * 'ASYNC' = Next lines of code start executing even before movement is finished + * 'RELATIVE' = not absolute coordinate system + * 'NONE' = default + 4. 'Angular Direction' = direction of turn + * 'AUTO' = default + * 'COUNTERCLOCKWISE' or 'CCW' + * 'CLOCKWISE' or 'CW' + * 'Call' chassis.turn(parameters) +```cpp +void autonomous(){ + chassis.turn(90); + chassis.turn(90, 100); + chassis.turn(90, 100, voss::Flags::RELATIVE); + chassis.turn(90, 100, voss::Flags::THRU | voss:Flags::ASYNC); + chassis.turn(90, 100, voss::Flags::THRU | voss:Flags::ASYNC, voss::AngularDirection::CW); +} From 56f14c65eadcbdfa839d5af73f159e24b24942cb Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Fri, 8 Mar 2024 16:01:11 -0500 Subject: [PATCH 02/18] Fixed Formatting --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 1ef837cd..93f23af2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#Pros With VOSS +# Pros With VOSS ### Introduction VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonomous code for VEX robots a piece of cake. @@ -14,13 +14,13 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom 5. Put `#include "VOSS/api.h"` in your main.h -##Quick start guide -###Robot definitions +## Quick start guide +### Robot definitions * 'LEFT_MOTORS' = list of motors on the left side of the drive * 'RIGHT_MOTORS' = list of motors on the right side of the drive * 'IMU_PORT' = the smart port number in which your imu is plugged into -###Creating a localizer +### Creating a localizer * We will set up a IME localizer in global scope 1. 'Call' auto odom = voss::localizer::IMELocalizerBuilder::new_builder() 2. Setup inputs to localizer @@ -43,7 +43,7 @@ void initialize() { } ``` -###Creating a PID controller +### Creating a PID controller * We will set up a PID controller for chassis movements in global scope * 'Linear error' = Linear distance from desired position to current position * 'Angular error' = Angular distance from desired position to current position @@ -82,7 +82,7 @@ void initialize() { } ``` -###Creating the chassis object +### Creating the chassis object * We will be creating a differential drive chassis in global scope 1. 'Call' voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT) ```cpp @@ -93,7 +93,7 @@ void initialize() { } ``` -###Starting the odometry localization +### Starting the odometry localization * We will be starting odomentry localization in the initalize scope 1. 'Call' odom->begin_localization() ```cpp @@ -102,7 +102,7 @@ void initialize() { } ``` -###Tuning localizer and controller +### Tuning localizer and controller * We will be tuning the TPI (ticks per inch) of the localizer 1. Move the robot forard a measured ammount 2. Read the odometry value @@ -121,7 +121,7 @@ void initialize() { * For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/ * Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers -###Driver Control +### Driver Control * We will be setting up tank control scheme for the drive in the opcontrol scope 1. Define the controller * 'Call' pros::Controller master(pros::E_CONTROLLER_MASTER) @@ -137,8 +137,8 @@ void opcontrol() { } ``` -###Autonomus Movement -*There are two types of basic movment calls which you can use to write an automous +### Autonomus Movement +* There are two types of basic movment calls which you can use to write an automous 1. Move * Parameters 1. 'Desired pose' = {x, y} From 7a188629e142b39f54050cf4c12663dd435add16 Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Fri, 8 Mar 2024 16:02:30 -0500 Subject: [PATCH 03/18] More formatting fixes --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93f23af2..13ed4b26 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Pros With VOSS +# PROS With VOSS ### Introduction VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonomous code for VEX robots a piece of cake. From b4cf19c236187b8dbe26784c009e92b3a0d10846 Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Fri, 8 Mar 2024 16:05:20 -0500 Subject: [PATCH 04/18] Back ticks not single quotes --- README.md | 108 +++++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 13ed4b26..5ca63674 100644 --- a/README.md +++ b/README.md @@ -16,19 +16,19 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom ## Quick start guide ### Robot definitions -* 'LEFT_MOTORS' = list of motors on the left side of the drive -* 'RIGHT_MOTORS' = list of motors on the right side of the drive -* 'IMU_PORT' = the smart port number in which your imu is plugged into +* `LEFT_MOTORS` = list of motors on the left side of the drive +* `RIGHT_MOTORS` = list of motors on the right side of the drive +* `IMU_PORT` = the smart port number in which your imu is plugged into ### Creating a localizer * We will set up a IME localizer in global scope -1. 'Call' auto odom = voss::localizer::IMELocalizerBuilder::new_builder() +1. `Call` auto odom = voss::localizer::IMELocalizerBuilder::new_builder() 2. Setup inputs to localizer - * 'Left encoders' = .with_left_motors(LEFT_MOTORS) - * 'Right encoders' = .with_right_motors(RIGHT_Motors) - * 'IMU' = .with_imu(IMU_PORT) - * 'Left right TPi' is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with .with_left_right_tip(TIP value) -3. 'Call it to build' --> .build() + * `Left encoders` = .with_left_motors(LEFT_MOTORS) + * `Right encoders` = .with_right_motors(RIGHT_Motors) + * `IMU` = .with_imu(IMU_PORT) + * `Left right TPi` is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with .with_left_right_tip(TIP value) +3. `Call it to build` --> .build() ```cpp auto odom = voss::localizer::IMELocalizerBuilder::new_builder() .with_left_motors({-1, -2, -3}) @@ -45,28 +45,28 @@ void initialize() { ### Creating a PID controller * We will set up a PID controller for chassis movements in global scope -* 'Linear error' = Linear distance from desired position to current position -* 'Angular error' = Angular distance from desired position to current position +* `Linear error` = Linear distance from desired position to current position +* `Angular error` = Angular distance from desired position to current position 1. Required constants and their meaning - * 'Linear proportional constant' = Weight of how much linear error affects motor power (Speeds up the robot movements) - * 'Linear derivative constant' = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) - * 'Linear integral constant' = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) - * 'Linear exit error' = Allowed linear distance from point in inches for the robot to exit the movement - * 'Angular proportional constant' = Weight of how much Angular error affects motor power (Speeds up the robot movements) - * 'Angular derivative constant' = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) - * 'Angular integral constant' = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) - * 'Angular exit error' = Allowed Angular distance from point in degrees for the robot to exit the movement - * 'Minimum error' = linear distance allowed from desired position in inches where the robot will check if it has stopped moving - * 'Settle time' = defined time in miliseconds which the robot has not move in order to exit the movement when the desired point has not been reached -2. 'Call' auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) + * `Linear proportional constant` = Weight of how much linear error affects motor power (Speeds up the robot movements) + * `Linear derivative constant` = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) + * `Linear integral constant` = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) + * `Linear exit error` = Allowed linear distance from point in inches for the robot to exit the movement + * `Angular proportional constant` = Weight of how much Angular error affects motor power (Speeds up the robot movements) + * `Angular derivative constant` = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) + * `Angular integral constant` = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) + * `Angular exit error` = Allowed Angular distance from point in degrees for the robot to exit the movement + * `Minimum error` = linear distance allowed from desired position in inches where the robot will check if it has stopped moving + * `Settle time` = defined time in miliseconds which the robot has not move in order to exit the movement when the desired point has not been reached +2. `Call` auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) 3. Set up inputs to pid controller - * 'Linear proportional, derivative, and integral constant (in this order)' = .with_linear_constants(0.0, 0.0, 0.0) - * 'Angular proportional, derivative, and integral constant (in this order)' = .with_angular_constants(0.0, 0.0, 0.0) - * 'Linear exit error' = .with_exit_error(1.0) - * 'Angular exit error' = .with_angular_exit_error(1.0) - * 'Minimum exit error' = .with_min_error(5) - * 'Settle time' = .with_settle_time(200) -4. 'Call it to build' --> .build() + * `Linear proportional, derivative, and integral constant (in this order)` = .with_linear_constants(0.0, 0.0, 0.0) + * `Angular proportional, derivative, and integral constant (in this order)` = .with_angular_constants(0.0, 0.0, 0.0) + * `Linear exit error` = .with_exit_error(1.0) + * `Angular exit error` = .with_angular_exit_error(1.0) + * `Minimum exit error` = .with_min_error(5) + * `Settle time` = .with_settle_time(200) +4. `Call it to build` --> .build() ```cpp auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) .with_linear_constants(0.1, 0.1, 0.1) @@ -84,7 +84,7 @@ void initialize() { ### Creating the chassis object * We will be creating a differential drive chassis in global scope -1. 'Call' voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT) +1. `Call` voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT) ```cpp voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT); @@ -95,7 +95,7 @@ void initialize() { ### Starting the odometry localization * We will be starting odomentry localization in the initalize scope -1. 'Call' odom->begin_localization() +1. `Call` odom->begin_localization() ```cpp void initialize() { odom->begin_localization(); @@ -124,9 +124,9 @@ void initialize() { ### Driver Control * We will be setting up tank control scheme for the drive in the opcontrol scope 1. Define the controller - * 'Call' pros::Controller master(pros::E_CONTROLLER_MASTER) + * `Call` pros::Controller master(pros::E_CONTROLLER_MASTER) 2. Inside the while loop set the movement - * 'Call' chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y)) + * `Call` chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y)) ```cpp void opcontrol() { pros::Controller master(pros::E_CONTROLLER_MASTER); @@ -141,15 +141,15 @@ void opcontrol() { * There are two types of basic movment calls which you can use to write an automous 1. Move * Parameters - 1. 'Desired pose' = {x, y} - 2. 'Speed' = 0 - 100 - 3. 'Flags' = options of movements - * 'THRU' = No PID - * 'Async' = Next lines of code start executing even before movement is finished - * 'REVERSE' = Robot moves backwards - * 'Relative' = not absolute coordinate system - * 'NONE' = defualt - * 'Call' chassis.move(Parameters) + 1. `Desired pose` = {x, y} + 2. `Speed` = 0 - 100 + 3. `Flags` = options of movements + * `THRU` = No PID + * `Async` = Next lines of code start executing even before movement is finished + * `REVERSE` = Robot moves backwards + * `Relative` = not absolute coordinate system + * `NONE` = defualt + * `Call` chassis.move(Parameters) ```cpp void autonomous(){ chassis.move({1.0, 1.0}); @@ -161,18 +161,18 @@ void autonomous(){ 2. Turn * Parameters - 1. 'Desired angle' - 2. 'Desired speed' - 3. 'Flags' = options of movements - * 'THUR' = No PID - * 'ASYNC' = Next lines of code start executing even before movement is finished - * 'RELATIVE' = not absolute coordinate system - * 'NONE' = default - 4. 'Angular Direction' = direction of turn - * 'AUTO' = default - * 'COUNTERCLOCKWISE' or 'CCW' - * 'CLOCKWISE' or 'CW' - * 'Call' chassis.turn(parameters) + 1. `Desired angle` + 2. `Desired speed` + 3. `Flags` = options of movements + * `THUR` = No PID + * `ASYNC` = Next lines of code start executing even before movement is finished + * `RELATIVE` = not absolute coordinate system + * `NONE` = default + 4. `Angular Direction` = direction of turn + * `AUTO` = default + * `COUNTERCLOCKWISE` or `CCW` + * `CLOCKWISE` or `CW` + * `Call` chassis.turn(parameters) ```cpp void autonomous(){ chassis.turn(90); From c2ab546f4e8e6c0aa91e436a0ad4fcccdf7d312d Mon Sep 17 00:00:00 2001 From: THERocky <101498190+Rocky14683@users.noreply.github.com> Date: Fri, 8 Mar 2024 16:21:17 -0500 Subject: [PATCH 05/18] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 5ca63674..d6719555 100644 --- a/README.md +++ b/README.md @@ -84,9 +84,9 @@ void initialize() { ### Creating the chassis object * We will be creating a differential drive chassis in global scope -1. `Call` voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT) +1. `Call` voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, slew rate, brake mode) ```cpp -voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, IMU_PORT); +voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, 8, pros::E_MOTOR_BRAKE_BRAKE); void initialize() { @@ -152,10 +152,10 @@ void opcontrol() { * `Call` chassis.move(Parameters) ```cpp void autonomous(){ - chassis.move({1.0, 1.0}); - chassis.move({1.0, 1.0}, 100); - chassis.move({1.0, 1.0}, 100, voss::Flags::RELATIVE); - chassis.move({1.0, 1.0}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC); + chassis.move(voss::Point{1.0, 1.0}); + chassis.move(voss::Point{1.0, 1.0}, 100); + chassis.move(voss::Point{1.0, 1.0}, 100, voss::Flags::RELATIVE); + chassis.move(voss::Point{1.0, 1.0}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC); } ``` @@ -178,6 +178,6 @@ void autonomous(){ chassis.turn(90); chassis.turn(90, 100); chassis.turn(90, 100, voss::Flags::RELATIVE); - chassis.turn(90, 100, voss::Flags::THRU | voss:Flags::ASYNC); - chassis.turn(90, 100, voss::Flags::THRU | voss:Flags::ASYNC, voss::AngularDirection::CW); + chassis.turn(90, 100, voss::Flags::THRU | voss::Flags::ASYNC); + chassis.turn(90, 100, voss::Flags::THRU | voss::Flags::ASYNC, voss::AngularDirection::CW); } From 9a69a9e9452893e8ab21ab314554b105615c7299 Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Wed, 13 Mar 2024 23:40:47 -0400 Subject: [PATCH 06/18] Fixed back tick use --- README.md | 108 +++++++++++++++++++++++++++--------------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index d6719555..62c4b140 100644 --- a/README.md +++ b/README.md @@ -16,19 +16,19 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom ## Quick start guide ### Robot definitions -* `LEFT_MOTORS` = list of motors on the left side of the drive -* `RIGHT_MOTORS` = list of motors on the right side of the drive -* `IMU_PORT` = the smart port number in which your imu is plugged into +* **LEFT_MOTORS** = list of motors on the left side of the drive +* **RIGHT_MOTORS** = list of motors on the right side of the drive +* **IMU_PORT** = the smart port number in which your imu is plugged into ### Creating a localizer * We will set up a IME localizer in global scope -1. `Call` auto odom = voss::localizer::IMELocalizerBuilder::new_builder() +1. Call `auto odom = voss::localizer::IMELocalizerBuilder::new_builder()` 2. Setup inputs to localizer - * `Left encoders` = .with_left_motors(LEFT_MOTORS) - * `Right encoders` = .with_right_motors(RIGHT_Motors) - * `IMU` = .with_imu(IMU_PORT) - * `Left right TPi` is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with .with_left_right_tip(TIP value) -3. `Call it to build` --> .build() + * **Left encoders** = `.with_left_motors(LEFT_MOTORS)` + * **Right encoders** = `.with_right_motors(RIGHT_Motors)` + * **IMU** = `.with_imu(IMU_PORT)` + * **Left right TPi** is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with `.with_left_right_tip`(TIP value) +3. Call it to build --> `.build()` ```cpp auto odom = voss::localizer::IMELocalizerBuilder::new_builder() .with_left_motors({-1, -2, -3}) @@ -45,28 +45,28 @@ void initialize() { ### Creating a PID controller * We will set up a PID controller for chassis movements in global scope -* `Linear error` = Linear distance from desired position to current position -* `Angular error` = Angular distance from desired position to current position +* **Linear error** = Linear distance from desired position to current position +* **Angular error** = Angular distance from desired position to current position 1. Required constants and their meaning - * `Linear proportional constant` = Weight of how much linear error affects motor power (Speeds up the robot movements) - * `Linear derivative constant` = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) - * `Linear integral constant` = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) - * `Linear exit error` = Allowed linear distance from point in inches for the robot to exit the movement - * `Angular proportional constant` = Weight of how much Angular error affects motor power (Speeds up the robot movements) - * `Angular derivative constant` = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) - * `Angular integral constant` = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) - * `Angular exit error` = Allowed Angular distance from point in degrees for the robot to exit the movement - * `Minimum error` = linear distance allowed from desired position in inches where the robot will check if it has stopped moving - * `Settle time` = defined time in miliseconds which the robot has not move in order to exit the movement when the desired point has not been reached -2. `Call` auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) + * **Linear proportional constant** = Weight of how much linear error affects motor power (Speeds up the robot movements) + * **Linear derivative constant** = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) + * **Linear integral constant** = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) + * **Linear exit error** = Allowed linear distance from point in inches for the robot to exit the movement + * **Angular proportional constant** = Weight of how much Angular error affects motor power (Speeds up the robot movements) + * **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) + * **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) + * **Angular exit error** = Allowed Angular distance from point in degrees for the robot to exit the movement + * **Minimum error** = linear distance allowed from desired position in inches where the robot will check if it has stopped moving + * **Settle time** = defined time in miliseconds which the robot has not move in order to exit the movement when the desired point has not been reached +2. Call `auto pid = voss::controller::PIDControllerBuilder::new_builder(odom)` 3. Set up inputs to pid controller - * `Linear proportional, derivative, and integral constant (in this order)` = .with_linear_constants(0.0, 0.0, 0.0) - * `Angular proportional, derivative, and integral constant (in this order)` = .with_angular_constants(0.0, 0.0, 0.0) - * `Linear exit error` = .with_exit_error(1.0) - * `Angular exit error` = .with_angular_exit_error(1.0) - * `Minimum exit error` = .with_min_error(5) - * `Settle time` = .with_settle_time(200) -4. `Call it to build` --> .build() + * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(0.0, 0.0, 0.0)` + * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(0.0, 0.0, 0.0)` + * **Linear exit error** = `.with_exit_error(1.0)` + * **Angular exit error** = `.with_angular_exit_error(1.0)` + * **Minimum exit error** = `.with_min_error(5)` + * **Settle time** = `.with_settle_time(200)` +4. Call it to build --> `.build()` ```cpp auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) .with_linear_constants(0.1, 0.1, 0.1) @@ -84,7 +84,7 @@ void initialize() { ### Creating the chassis object * We will be creating a differential drive chassis in global scope -1. `Call` voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, slew rate, brake mode) +1. Call `voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, slew rate, brake mode)` ```cpp voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, 8, pros::E_MOTOR_BRAKE_BRAKE); @@ -95,7 +95,7 @@ void initialize() { ### Starting the odometry localization * We will be starting odomentry localization in the initalize scope -1. `Call` odom->begin_localization() +1. Call `odom->begin_localization()` ```cpp void initialize() { odom->begin_localization(); @@ -124,9 +124,9 @@ void initialize() { ### Driver Control * We will be setting up tank control scheme for the drive in the opcontrol scope 1. Define the controller - * `Call` pros::Controller master(pros::E_CONTROLLER_MASTER) + * Call `pros::Controller master(pros::E_CONTROLLER_MASTER)` 2. Inside the while loop set the movement - * `Call` chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y)) + * Call `chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y))` ```cpp void opcontrol() { pros::Controller master(pros::E_CONTROLLER_MASTER); @@ -141,15 +141,15 @@ void opcontrol() { * There are two types of basic movment calls which you can use to write an automous 1. Move * Parameters - 1. `Desired pose` = {x, y} - 2. `Speed` = 0 - 100 - 3. `Flags` = options of movements - * `THRU` = No PID - * `Async` = Next lines of code start executing even before movement is finished - * `REVERSE` = Robot moves backwards - * `Relative` = not absolute coordinate system - * `NONE` = defualt - * `Call` chassis.move(Parameters) + 1. **Desired pose** = {x, y} + 2. **Speed** = 0 - 100 + 3. **Flags** = options of movements + * **THRU** = No PID + * **Async** = Next lines of code start executing even before movement is finished + * **REVERSE** = Robot moves backwards + * **Relative** = not absolute coordinate system + * **NONE** = defualt + * Call `chassis.move(Parameters)` ```cpp void autonomous(){ chassis.move(voss::Point{1.0, 1.0}); @@ -161,18 +161,18 @@ void autonomous(){ 2. Turn * Parameters - 1. `Desired angle` - 2. `Desired speed` - 3. `Flags` = options of movements - * `THUR` = No PID - * `ASYNC` = Next lines of code start executing even before movement is finished - * `RELATIVE` = not absolute coordinate system - * `NONE` = default - 4. `Angular Direction` = direction of turn - * `AUTO` = default - * `COUNTERCLOCKWISE` or `CCW` - * `CLOCKWISE` or `CW` - * `Call` chassis.turn(parameters) + 1. **Desired angle** + 2. **Desired speed** + 3. **Flags** = options of movements + * **THUR** = No PID + * **ASYNC** = Next lines of code start executing even before movement is finished + * **RELATIVE** = not absolute coordinate system + * **NONE** = default + 4. **Angular Direction** = direction of turn + * **AUTO** = default + * **COUNTERCLOCKWISE** or **CCW** + * **CLOCKWISE** or **CW** + * Call `chassis.turn(parameters)` ```cpp void autonomous(){ chassis.turn(90); From 450afb2f853626fbf8af3f763ecc27227e1d8053 Mon Sep 17 00:00:00 2001 From: THERocky <101498190+Rocky14683@users.noreply.github.com> Date: Fri, 15 Mar 2024 18:01:15 -0400 Subject: [PATCH 07/18] Update README.md Add reverse flag and fix thru flag explanation --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 62c4b140..21da1bcb 100644 --- a/README.md +++ b/README.md @@ -164,9 +164,10 @@ void autonomous(){ 1. **Desired angle** 2. **Desired speed** 3. **Flags** = options of movements - * **THUR** = No PID + * **THUR** = Enable motion chaining * **ASYNC** = Next lines of code start executing even before movement is finished * **RELATIVE** = not absolute coordinate system + * **REVERSE** = Go backward * **NONE** = default 4. **Angular Direction** = direction of turn * **AUTO** = default From ee48432650f0aa730614d5355bd152abd8f26caa Mon Sep 17 00:00:00 2001 From: THERocky <101498190+Rocky14683@users.noreply.github.com> Date: Wed, 15 May 2024 11:48:11 +0800 Subject: [PATCH 08/18] Update README.md - ec --- README.md | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 21da1bcb..e7f3ebd5 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,9 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonomous code for VEX robots a piece of cake. ## Installing VOSS -1. Download the most recent [template](https://github.com/purduesigbots/VOSS) +1. Download the most recent [template](https://github.com/purduesigbots/VOSS/releases/tag/0.1.1) -2. Run this command from terminal `pros c fetch VOSS@0.1.0.zip` +2. Run this command from terminal `pros c fetch VOSS@0.1.1.zip` 3. `cd` into your pros project directory in your terminal @@ -20,14 +20,31 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom * **RIGHT_MOTORS** = list of motors on the right side of the drive * **IMU_PORT** = the smart port number in which your imu is plugged into +### Creating a exit conditions +* We will set up a localizer in global scope +1. Call `auto ec = auto ec = voss::controller::ExitConditions::new_conditions()` +2. Setup conditions + * **velocity base exit** `.add_settle(int settle_time, double tolerance, int initial_delay)` + * **distance base exit** = `.add_tolerance(double linear_tolerance, double angular_tolerance, double tolerance_time)` + * **time base exit**(ms) = `.add_timeout(int time)` + * **motion chaining early exit**(smoothness increase, accuracy decrease) = `.add_thru_smoothness(double thru_smoothness)` +3. Call it to build --> `.build()` +```cpp +auto ec = voss::controller::ExitConditions::new_conditions() + .add_settle(400, 0.5, 400) + .add_tolerance(1.0, 2.0, 200) + .add_timeout(22500) + .add_thru_smoothness(4) + .build(); +``` ### Creating a localizer -* We will set up a IME localizer in global scope -1. Call `auto odom = voss::localizer::IMELocalizerBuilder::new_builder()` +* We will set up a localizer in global scope +1. Call `auto odom = voss::localizer::::new_builder()`. For example: `auto odom = voss::localizer::IMELocalizerBuilder::new_builder()` 2. Setup inputs to localizer * **Left encoders** = `.with_left_motors(LEFT_MOTORS)` * **Right encoders** = `.with_right_motors(RIGHT_Motors)` * **IMU** = `.with_imu(IMU_PORT)` - * **Left right TPi** is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with `.with_left_right_tip`(TIP value) + * **Left right TPI** is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with `.with_left_right_tip`(TPI value) 3. Call it to build --> `.build()` ```cpp auto odom = voss::localizer::IMELocalizerBuilder::new_builder() @@ -51,13 +68,10 @@ void initialize() { * **Linear proportional constant** = Weight of how much linear error affects motor power (Speeds up the robot movements) * **Linear derivative constant** = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) * **Linear integral constant** = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) - * **Linear exit error** = Allowed linear distance from point in inches for the robot to exit the movement * **Angular proportional constant** = Weight of how much Angular error affects motor power (Speeds up the robot movements) * **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) * **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) - * **Angular exit error** = Allowed Angular distance from point in degrees for the robot to exit the movement * **Minimum error** = linear distance allowed from desired position in inches where the robot will check if it has stopped moving - * **Settle time** = defined time in miliseconds which the robot has not move in order to exit the movement when the desired point has not been reached 2. Call `auto pid = voss::controller::PIDControllerBuilder::new_builder(odom)` 3. Set up inputs to pid controller * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(0.0, 0.0, 0.0)` @@ -71,10 +85,7 @@ void initialize() { auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) .with_linear_constants(0.1, 0.1, 0.1) .with_angular_constants(0.1, 0.1, 0.1) - .with_exit_error(1.0) - .with_angular_exit_error(1.0) .with_min_error(5) - .with_settle_time(200) .build(); void initialize() { @@ -164,7 +175,7 @@ void autonomous(){ 1. **Desired angle** 2. **Desired speed** 3. **Flags** = options of movements - * **THUR** = Enable motion chaining + * **THRU** = Enable motion chaining * **ASYNC** = Next lines of code start executing even before movement is finished * **RELATIVE** = not absolute coordinate system * **REVERSE** = Go backward From 968c03d8ebaa2bd83d022f37c46c01b9281d40bb Mon Sep 17 00:00:00 2001 From: THERocky <101498190+Rocky14683@users.noreply.github.com> Date: Thu, 16 May 2024 10:58:56 +0800 Subject: [PATCH 09/18] Update README.md --- README.md | 293 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 197 insertions(+), 96 deletions(-) diff --git a/README.md b/README.md index e7f3ebd5..2d2868b2 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom ## Installing VOSS 1. Download the most recent [template](https://github.com/purduesigbots/VOSS/releases/tag/0.1.1) -2. Run this command from terminal `pros c fetch VOSS@0.1.1.zip` +2. Run this command from terminal `pros c fetch VOSS@0.1.2.zip` 3. `cd` into your pros project directory in your terminal @@ -14,20 +14,14 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom 5. Put `#include "VOSS/api.h"` in your main.h -## Quick start guide -### Robot definitions -* **LEFT_MOTORS** = list of motors on the left side of the drive -* **RIGHT_MOTORS** = list of motors on the right side of the drive -* **IMU_PORT** = the smart port number in which your imu is plugged into - ### Creating a exit conditions * We will set up a localizer in global scope 1. Call `auto ec = auto ec = voss::controller::ExitConditions::new_conditions()` 2. Setup conditions - * **velocity base exit** `.add_settle(int settle_time, double tolerance, int initial_delay)` - * **distance base exit** = `.add_tolerance(double linear_tolerance, double angular_tolerance, double tolerance_time)` - * **time base exit**(ms) = `.add_timeout(int time)` - * **motion chaining early exit**(smoothness increase, accuracy decrease) = `.add_thru_smoothness(double thru_smoothness)` + * **Velocity base exit** `.add_settle(int settle_time, double tolerance, int initial_delay)` + * **Distance base exit** = `.add_tolerance(double linear_tolerance, double angular_tolerance, double tolerance_time)` + * **Time base exit**(ms) = `.add_timeout(int time)` + * **Motion chaining early exit**(smoothness increase, accuracy decrease) = `.add_thru_smoothness(double thru_smoothness)` 3. Call it to build --> `.build()` ```cpp auto ec = voss::controller::ExitConditions::new_conditions() @@ -39,69 +33,155 @@ auto ec = voss::controller::ExitConditions::new_conditions() ``` ### Creating a localizer * We will set up a localizer in global scope -1. Call `auto odom = voss::localizer::::new_builder()`. For example: `auto odom = voss::localizer::IMELocalizerBuilder::new_builder()` +* You have three choices, IME(Internal motor encoder), ADI Encoders, or Rotation sensors. +1. Call `auto odom = voss::localizer::voss::localizer::TrackingWheelLocalizerBuilder::new_builder()` 2. Setup inputs to localizer - * **Left encoders** = `.with_left_motors(LEFT_MOTORS)` - * **Right encoders** = `.with_right_motors(RIGHT_Motors)` - * **IMU** = `.with_imu(IMU_PORT)` - * **Left right TPI** is the ratio of rotations of the motor encoder to 1 inch of linear movement. It is called with `.with_left_right_tip`(TPI value) + * **Left** : + - `.with_left_encoder(int adi_port)` + - `.with_left_encoder(int smart_port, int adi_port)` + - `.with_left_rotation(int port)` + - `.with_left_motor(int port)` + * **Right** : + - `.with_right_encoder(int adi_port)` + - `.with_right_encoder(int smart_port, int adi_port)` + - `.with_right_rotation(int port)` + - `.with_right_motor(int port)` + * **IMU** : + - `.with_imu(int imu_port)` + * **Track width** + - `.with_track_width(double track_width_distance)` + * **Left right TPI**: the ratio of rotations of the motor encoder to 1 inch of linear movement. + - `.with_left_right_tip(double tpi_value)` 3. Call it to build --> `.build()` ```cpp -auto odom = voss::localizer::IMELocalizerBuilder::new_builder() - .with_left_motors({-1, -2, -3}) - .with_right_motors({4, 5, 6}) - .with_left_right_tpi(20) - .with_track_width(5) - .with_imu(IMU_PORT) - .build(); +auto odom = voss::localizer::TrackingWheelLocalizerBuilder::new_builder() + .with_right_motor(10) + .with_left_motor(-4) + .with_track_width(11) + .with_left_right_tpi(18.43) + .with_imu(16) + .build(); + void initialize() { - + pros::lcd::initialize(); + odom->begin_localization(); //calibrate and begin localizing } ``` +### Tuning localizer +* We will be tuning the TPI (ticks per inch) of the localizer + 1. Move the robot forard a measured ammount + 2. Read the odometry value + 3. Divide the amount you moved the robot by the measured movement value from the odometry + * adjustment factor = robot actual move amount/odometry measured amount + 4. Set the new tpi value to the current tpi value multiplied by the value you got from step 3 + * new tip = old tpi x adjustment factor -### Creating a PID controller -* We will set up a PID controller for chassis movements in global scope +### Before you start: Basic understand on PID * **Linear error** = Linear distance from desired position to current position * **Angular error** = Angular distance from desired position to current position -1. Required constants and their meaning * **Linear proportional constant** = Weight of how much linear error affects motor power (Speeds up the robot movements) * **Linear derivative constant** = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) * **Linear integral constant** = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) * **Angular proportional constant** = Weight of how much Angular error affects motor power (Speeds up the robot movements) * **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) * **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) - * **Minimum error** = linear distance allowed from desired position in inches where the robot will check if it has stopped moving -2. Call `auto pid = voss::controller::PIDControllerBuilder::new_builder(odom)` -3. Set up inputs to pid controller - * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(0.0, 0.0, 0.0)` - * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(0.0, 0.0, 0.0)` - * **Linear exit error** = `.with_exit_error(1.0)` - * **Angular exit error** = `.with_angular_exit_error(1.0)` + +### Tuning PID +* We will be tuning the PID controller constants + * This is a lot of guessing and making corrections based off of the behavior of the robot. This will change with any signifcant robot changes + * Tune linear constants first + 1. Start with the constants all being 0 + 2. Increase the proportional constant until oscillations start (the amount you need to increase by and total amount will vary with each robot) + 3. Slowly increase the derivative constant until the robot is no longer overshooting its target and oscilations have stopped + 4. If the robot is lowly compounding error over time, slowly increase the integral constant to reduce that error + * Tune the angular constants using steps 1-4 of tuning the linear constants +* For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/ +* Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers + +### Creating a PID controller +* We will set up a PID controller for chassis movements in global scope +1. Call `auto pid = voss::controller::PIDControllerBuilder::new_builder(odom)` +2. Set up inputs to pid controller + * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)` + * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)` * **Minimum exit error** = `.with_min_error(5)` - * **Settle time** = `.with_settle_time(200)` -4. Call it to build --> `.build()` + * **Minimun velocity for thru motion** = `.with_min_vel_for_thru(100)` +3. Call it to build --> `.build()` ```cpp auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) - .with_linear_constants(0.1, 0.1, 0.1) - .with_angular_constants(0.1, 0.1, 0.1) - .with_min_error(5) - .build(); - -void initialize() { - -} + .with_linear_constants(20, 0.02, 169) + .with_angular_constants(250, 0.05, 2435) + .with_min_error(5) + .with_min_vel_for_thru(100) + .build(); +``` + +### Creating a Boomerang controller +* Boomerang controller demo on [Desmos](https://www.desmos.com/calculator/zl0pizecei?lang=zh-TW) +* We will set up a Boomerang controller for chassis movements in global scope +1. Call `auto boomerang = voss::controller::BoomerangControllerBuilder::new_builder(odom)` +2. Set up inputs to boomerang controller + * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)` + * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)` + * **Leading percentage**(not smaller than 0, and not greater than 1) = `.with_lead_pct(0.5)` + * **Minimum exit error** = `.with_min_error(5)` + * **Minimun velocity for thru motion** = `.with_min_vel_for_thru(100)` +3. Call it to build --> `.build()` +```cpp +auto boomerang = voss::controller::BoomerangControllerBuilder::new_builder(odom) + .with_linear_constants(20, 0.02, 169) + .with_angular_constants(250, 0.05, 2435) + .with_lead_pct(0.5) + .with_min_vel_for_thru(70) + .with_min_error(5) + .build(); +``` + +### Creating a Swing controller +* We will set up a Swing controller for chassis movements in global scope +1. Call `auto swing = voss::controller::SwingControllerBuilder::new_builder(odom)` +2. Set up inputs to swing controller + * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)` +3. Call it to build --> `.build()` +```cpp +auto swing = voss::controller::SwingControllerBuilder::new_builder(odom) + .with_angular_constants(250, 0.05, 2435) + .build(); ``` +### Creating a Arc controller +* We will set up a Arc controller for chassis movements in global scope +* **Temporary avoid using this controller, because we are still trying to optimize it.** +1. Call `voss::controller::ArcPIDControllerBuilder(odom)` +2. Set up inputs to pid controller + * **Track width** = `.with_track_width(16)` + * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)` + * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)` + * **Leading percentage**(not smaller than 0, and not greater than 1) = `.with_lead_pct(0.5)` + * **Minimum exit error** = `.with_min_error(5)` + * **Slew rate(for limiting linear acceleration)** = `.with_slew(8)` +4. Call it to build --> `.build()` +```cpp +auto arc = voss::controller::ArcPIDControllerBuilder(odom) + .with_track_width(16) + .with_linear_constants(20, 0.02, 169) + .with_angular_constants(250, 0.05, 2435) + .with_min_error(5) + .with_slew(8) + .build(); +``` + + + + ### Creating the chassis object * We will be creating a differential drive chassis in global scope -1. Call `voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, slew rate, brake mode)` +* `DiffChassis(std::initializer_list left_motors, std::initializer_list right_motors, + controller_ptr default_controller, ec_ptr ec, + double slew_step, pros::motor_brake_mode_e brakeMode)` ```cpp -voss::chassis::DiffChassis chassis(LEFT_MOTORS, RIGHT_MOTORS, pid, 8, pros::E_MOTOR_BRAKE_BRAKE); - -void initialize() { - -} +auto chassis = voss::chassis::DiffChassis(LEFT_MOTORS, RIGHT_MOTORS, pid, ec, 8, pros::E_MOTOR_BRAKE_COAST); //use pid as default controller is suggested ``` ### Starting the odometry localization @@ -109,35 +189,18 @@ void initialize() { 1. Call `odom->begin_localization()` ```cpp void initialize() { - odom->begin_localization(); + odom->begin_localization(); //calibrate and begin localizing + pros::delay(3000); //don't move the robot for 3 seconds } ``` -### Tuning localizer and controller -* We will be tuning the TPI (ticks per inch) of the localizer - 1. Move the robot forard a measured ammount - 2. Read the odometry value - 3. Divide the amount you moved the robot by the measured movement value from the odometry - * adjustment factor = robot actual move amount/odometry measured amount - 4. Set the new tpi value to the current tpi value multiplied by the value you got from step 3 - * new tip = old tpi x adjustment factor -* We will be tuning the PID controller constants - * This is a lot of guessing and making corrections based off of the behavior of the robot. This will change with any signifcant robot changes - * Tune linear constants first - 1. Start with the constants all being 0 - 2. Increase the proportional constant until oscillations start (the amount you need to increase by and total amount will vary with each robot) - 3. Slowly increase the derivative constant until the robot is no longer overshooting its target and oscilations have stopped - 4. If the robot is lowly compounding error over time, slowly increase the integral constant to reduce that error - * Tune the angular constants using steps 1-4 of tuning the linear constants -* For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/ -* Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers - ### Driver Control -* We will be setting up tank control scheme for the drive in the opcontrol scope +* We will be setting up control scheme for the drive in the opcontrol scope 1. Define the controller * Call `pros::Controller master(pros::E_CONTROLLER_MASTER)` 2. Inside the while loop set the movement - * Call `chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y))` + * **Tank control** = `chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y))` + * **Arcade control** = `chassis.arcade(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_X))` ```cpp void opcontrol() { pros::Controller master(pros::E_CONTROLLER_MASTER); @@ -149,47 +212,85 @@ void opcontrol() { ``` ### Autonomus Movement -* There are two types of basic movment calls which you can use to write an automous +* There are two types of basic movment calls which you can use to write an autonomous 1. Move + * Controllers + - PID Controller + - Boomerang Controller + - Arc Controller * Parameters - 1. **Desired pose** = {x, y} - 2. **Speed** = 0 - 100 - 3. **Flags** = options of movements - * **THRU** = No PID - * **Async** = Next lines of code start executing even before movement is finished + 1. **Target** = Relative distance or {x, y} or {x, y, theta} (Remember for boomerang controller, you need to specify theta.) + 2. **Controller** = PID/ Boomerang/ Arc + 3. **Speed** = 0 - 100 (100 is default) + 4. **Flags** = options of movements + * **THRU** = Enable motion chaining + * **ASYNC** = Next lines of code start executing even before movement is finished * **REVERSE** = Robot moves backwards - * **Relative** = not absolute coordinate system - * **NONE** = defualt + * **RELATIVE** = Not absolute coordinate system + * **NONE** = Defualt * Call `chassis.move(Parameters)` ```cpp void autonomous(){ - chassis.move(voss::Point{1.0, 1.0}); - chassis.move(voss::Point{1.0, 1.0}, 100); - chassis.move(voss::Point{1.0, 1.0}, 100, voss::Flags::RELATIVE); - chassis.move(voss::Point{1.0, 1.0}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC); + // using default controller: + chassis.move(10); //move forward 10 + chassis.move(-10, 100, voss::Flags::REVERSE) //move backward 10 + chassis.move(10, 70); + chassis.move(voss::Point{1.0, 1.0}, 70); + chassis.move(voss::Point{1.0, 1.0, 30}, 100, voss::Flags::RELATIVE); + chassis.move(voss::Point{1.0, 1.0}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU); + // using boomerang controller: + chassis.move(voss::Point{1.0, 1.0, 90}, boomerang); + chassis.move(voss::Point{1.0, 1.0, 20}, boomerang, 70); + chassis.move(voss::Point{1.0, 1.0, 30}, boomerang, 100, voss::Flags::RELATIVE); + chassis.move(voss::Point{1.0, 1.0, 10}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU); + // using arc controller: + chassis.move(voss::Point{1.0, 1.0}, arc); + chassis.move(voss::Point{1.0, 1.0}, arc, 70); + chassis.move(voss::Point{1.0, 1.0}, arc, 100, voss::Flags::RELATIVE); + chassis.move(voss::Point{1.0, 1.0}, arc, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU); } ``` 2. Turn + * Controllers + - PID controller + - Swing controller * Parameters - 1. **Desired angle** - 2. **Desired speed** - 3. **Flags** = options of movements - * **THRU** = Enable motion chaining - * **ASYNC** = Next lines of code start executing even before movement is finished - * **RELATIVE** = not absolute coordinate system - * **REVERSE** = Go backward - * **NONE** = default - 4. **Angular Direction** = direction of turn + 1. **Target** = angle or {x, y} + 2. **Controller** = PID/ Swing + 3. **Desired speed** = 0 - 100 (100 is default) + 4. **Flags** = options of movements + * **THRU** = Enable motion chaining + * **ASYNC** = Next lines of code start executing even before movement is finished + * **REVERSE** = Robot moves backwards (for swing controller) + * **RELATIVE** = Not absolute coordinate system + * **NONE** = Defualt + 5. **Angular Direction** = direction of turn * **AUTO** = default * **COUNTERCLOCKWISE** or **CCW** * **CLOCKWISE** or **CW** - * Call `chassis.turn(parameters)` + * Call `chassis.turn(parameters)` or `chassis.turn_to(parameters)` ```cpp void autonomous(){ +//using default controller: chassis.turn(90); - chassis.turn(90, 100); + chassis.turn_to({10, 10}); + chassis.turn(90, 50); + chassis.turn_to({10, 10}, 40); chassis.turn(90, 100, voss::Flags::RELATIVE); + chassis.turn_to({10, 10}, 40, voss::Flags::RELATIVE); chassis.turn(90, 100, voss::Flags::THRU | voss::Flags::ASYNC); - chassis.turn(90, 100, voss::Flags::THRU | voss::Flags::ASYNC, voss::AngularDirection::CW); + chassis.turn(90, 100, voss::Flags::NONE, voss::AngularDirection::CW); + chassis.turn_to({10, 10}, 40, voss::Flags::RELATIVE | voss::Flags::THRU, voss::AngularDirection::CW); + +//using swing controller: + chassis.turn(90, swing); + chassis.turn_to({10, 10}, swing); + chassis.turn(90, swing, 50); + chassis.turn_to({10, 10}, swing, 40); + chassis.turn(90, 100, swing, voss::Flags::RELATIVE); + chassis.turn_to({10, 10}, swing, 40, voss::Flags::RELATIVE | voss::Flags::REVERSE); + chassis.turn(90, 100, swing, voss::Flags::NONE, voss::AngularDirection::CW); + chassis.turn_to({10, 10}, swing, 40, voss::Flags::RELATIVE | voss::Flags::THRU, voss::AngularDirection::CW); } +``` From f36165929e162afd44c422b27fdc3adfecb450c9 Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Wed, 15 May 2024 23:43:29 -0400 Subject: [PATCH 10/18] Touchup and added additional resources --- README.md | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 2d2868b2..6bf4f30f 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,14 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom 5. Put `#include "VOSS/api.h"` in your main.h -### Creating a exit conditions +### Creating exit conditions * We will set up a localizer in global scope -1. Call `auto ec = auto ec = voss::controller::ExitConditions::new_conditions()` +1. Call `auto ec = voss::controller::ExitConditions::new_conditions()` 2. Setup conditions * **Velocity base exit** `.add_settle(int settle_time, double tolerance, int initial_delay)` * **Distance base exit** = `.add_tolerance(double linear_tolerance, double angular_tolerance, double tolerance_time)` * **Time base exit**(ms) = `.add_timeout(int time)` - * **Motion chaining early exit**(smoothness increase, accuracy decrease) = `.add_thru_smoothness(double thru_smoothness)` + * **Motion chaining early exit**(as smoothness increase, accuracy decrease) = `.add_thru_smoothness(double thru_smoothness)` 3. Call it to build --> `.build()` ```cpp auto ec = voss::controller::ExitConditions::new_conditions() @@ -33,7 +33,7 @@ auto ec = voss::controller::ExitConditions::new_conditions() ``` ### Creating a localizer * We will set up a localizer in global scope -* You have three choices, IME(Internal motor encoder), ADI Encoders, or Rotation sensors. +* You have three choices, IME(Internal motor encoder), ADI Encoders, or Smart Port Rotation sensors. 1. Call `auto odom = voss::localizer::voss::localizer::TrackingWheelLocalizerBuilder::new_builder()` 2. Setup inputs to localizer * **Left** : @@ -50,7 +50,7 @@ auto ec = voss::controller::ExitConditions::new_conditions() - `.with_imu(int imu_port)` * **Track width** - `.with_track_width(double track_width_distance)` - * **Left right TPI**: the ratio of rotations of the motor encoder to 1 inch of linear movement. + * **Left right TPI**: the ratio of encoder rotations to 1 inch of linear movement. - `.with_left_right_tip(double tpi_value)` 3. Call it to build --> `.build()` ```cpp @@ -78,8 +78,8 @@ void initialize() { * new tip = old tpi x adjustment factor ### Before you start: Basic understand on PID -* **Linear error** = Linear distance from desired position to current position -* **Angular error** = Angular distance from desired position to current position +* **Linear error** = Linear distance from desired position to current position (Inches) +* **Angular error** = Angular distance from desired position to current position (Degrees) * **Linear proportional constant** = Weight of how much linear error affects motor power (Speeds up the robot movements) * **Linear derivative constant** = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) * **Linear integral constant** = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) @@ -94,7 +94,7 @@ void initialize() { 1. Start with the constants all being 0 2. Increase the proportional constant until oscillations start (the amount you need to increase by and total amount will vary with each robot) 3. Slowly increase the derivative constant until the robot is no longer overshooting its target and oscilations have stopped - 4. If the robot is lowly compounding error over time, slowly increase the integral constant to reduce that error + 4. If the robot is compounding error over time, slowly increase the integral constant to reduce that error * Tune the angular constants using steps 1-4 of tuning the linear constants * For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/ * Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers @@ -124,7 +124,7 @@ auto pid = voss::controller::PIDControllerBuilder::new_builder(odom) 2. Set up inputs to boomerang controller * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)` * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)` - * **Leading percentage**(not smaller than 0, and not greater than 1) = `.with_lead_pct(0.5)` + * **Leading percentage**(greater than 0, but less than 1) = `.with_lead_pct(0.5)` * **Minimum exit error** = `.with_min_error(5)` * **Minimun velocity for thru motion** = `.with_min_vel_for_thru(100)` 3. Call it to build --> `.build()` @@ -152,15 +152,15 @@ auto swing = voss::controller::SwingControllerBuilder::new_builder(odom) ### Creating a Arc controller * We will set up a Arc controller for chassis movements in global scope -* **Temporary avoid using this controller, because we are still trying to optimize it.** +* **Please avoid using this controller, because we are still trying to optimize it.** 1. Call `voss::controller::ArcPIDControllerBuilder(odom)` 2. Set up inputs to pid controller * **Track width** = `.with_track_width(16)` * **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)` * **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)` - * **Leading percentage**(not smaller than 0, and not greater than 1) = `.with_lead_pct(0.5)` + * **Leading percentage** (greater than 0, but less than 1) = `.with_lead_pct(0.5)` * **Minimum exit error** = `.with_min_error(5)` - * **Slew rate(for limiting linear acceleration)** = `.with_slew(8)` + * **Slew rate(limits linear acceleration. Higher slew rate = higher acceleration)** = `.with_slew(8)` 4. Call it to build --> `.build()` ```cpp auto arc = voss::controller::ArcPIDControllerBuilder(odom) @@ -217,10 +217,10 @@ void opcontrol() { * Controllers - PID Controller - Boomerang Controller - - Arc Controller + - Arc Controller **Please avoid using this controller, because we are still trying to optimize it.** * Parameters - 1. **Target** = Relative distance or {x, y} or {x, y, theta} (Remember for boomerang controller, you need to specify theta.) - 2. **Controller** = PID/ Boomerang/ Arc + 1. **Target** = Relative distance or {x, y} or {x, y, theta} (Remember for boomerang controller, you need to specify theta) + 2. **Controller** = PID, Boomerang, or Arc 3. **Speed** = 0 - 100 (100 is default) 4. **Flags** = options of movements * **THRU** = Enable motion chaining @@ -257,7 +257,7 @@ void autonomous(){ - Swing controller * Parameters 1. **Target** = angle or {x, y} - 2. **Controller** = PID/ Swing + 2. **Controller** = PID or Swing 3. **Desired speed** = 0 - 100 (100 is default) 4. **Flags** = options of movements * **THRU** = Enable motion chaining @@ -294,3 +294,16 @@ void autonomous(){ chassis.turn_to({10, 10}, swing, 40, voss::Flags::RELATIVE | voss::Flags::THRU, voss::AngularDirection::CW); } ``` +## Additional Resources + +By following the [In Depth Documentation](**Coming Soon!**), your team should be able to create a competitive program for your competition robot. For people who are interested in more advanced programming such as programming skills runs, there is a lot of potential customization with this library. The following resources may interest people who want to take their programming skills further: + +- [Take a C++ programming course.](https://www.codecademy.com/learn/learn-c-plus-plus) + +- [Explore the PROS API](https://pros.cs.purdue.edu/v5/index.html) + +- [Learn PID](http://georgegillard.com/documents/2-introduction-to-pid-controllers) + +- [Read the Vex Forums a lot](http://vexforum.com) + +- [Get help from other teams on discord](https://discordapp.com/invite/9JDWW8e) \ No newline at end of file From 0266c4a7a33e2f2b7437ef3c3998b0b9ea6f8493 Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Wed, 15 May 2024 23:45:23 -0400 Subject: [PATCH 11/18] added a space --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6bf4f30f..6481cccc 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ auto ec = voss::controller::ExitConditions::new_conditions() ``` ### Creating a localizer * We will set up a localizer in global scope -* You have three choices, IME(Internal motor encoder), ADI Encoders, or Smart Port Rotation sensors. +* You have three choices, IME (Internal motor encoder), ADI Encoders, or Smart Port Rotation sensors. 1. Call `auto odom = voss::localizer::voss::localizer::TrackingWheelLocalizerBuilder::new_builder()` 2. Setup inputs to localizer * **Left** : From e7a9175e3cdf3455ed970b20a94a0e134230a42e Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Wed, 15 May 2024 23:58:18 -0400 Subject: [PATCH 12/18] Changed formatting and added more to tuning --- README.md | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 6481cccc..4c636854 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ auto ec = voss::controller::ExitConditions::new_conditions() - `.with_imu(int imu_port)` * **Track width** - `.with_track_width(double track_width_distance)` - * **Left right TPI**: the ratio of encoder rotations to 1 inch of linear movement. + * **Left right TPI** (ratio of encoder rotations to 1 inch of linear movement) - `.with_left_right_tip(double tpi_value)` 3. Call it to build --> `.build()` ```cpp @@ -78,27 +78,16 @@ void initialize() { * new tip = old tpi x adjustment factor ### Before you start: Basic understand on PID -* **Linear error** = Linear distance from desired position to current position (Inches) -* **Angular error** = Angular distance from desired position to current position (Degrees) - * **Linear proportional constant** = Weight of how much linear error affects motor power (Speeds up the robot movements) - * **Linear derivative constant** = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) - * **Linear integral constant** = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) - * **Angular proportional constant** = Weight of how much Angular error affects motor power (Speeds up the robot movements) - * **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) - * **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) - -### Tuning PID -* We will be tuning the PID controller constants - * This is a lot of guessing and making corrections based off of the behavior of the robot. This will change with any signifcant robot changes - * Tune linear constants first - 1. Start with the constants all being 0 - 2. Increase the proportional constant until oscillations start (the amount you need to increase by and total amount will vary with each robot) - 3. Slowly increase the derivative constant until the robot is no longer overshooting its target and oscilations have stopped - 4. If the robot is compounding error over time, slowly increase the integral constant to reduce that error - * Tune the angular constants using steps 1-4 of tuning the linear constants -* For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/ -* Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers +* **Linear error** = Linear distance from desired position to current position (inches) +* **Angular error** = Angular distance from desired position to current position (degrees) +* **Linear proportional constant** = Weight of how much linear error affects motor power (speeds up the robot movements) +* **Linear derivative constant** = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration) +* **Linear integral constant** = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error) +* **Angular proportional constant** = Weight of how much Angular error affects motor power (speeds up the robot movements) +* **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) +* **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) + ### Creating a PID controller * We will set up a PID controller for chassis movements in global scope 1. Call `auto pid = voss::controller::PIDControllerBuilder::new_builder(odom)` @@ -171,10 +160,26 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) .with_slew(8) .build(); ``` +## Tuning Controllers +### Tuning PID +* We will be tuning the PID controller constants + * This is a lot of guessing and making corrections based off of the behavior of the robot. This will change with any signifcant robot changes + * Tune linear constants first + 1. Start with the constants all being 0 + 2. Increase the proportional constant until oscillations start (the amount you need to increase by and total amount will vary with each robot) + 3. Slowly increase the derivative constant until the robot is no longer overshooting its target and oscilations have stopped + 4. If the robot is compounding error over time, slowly increase the integral constant to reduce that error + * Tune the angular constants using steps 1-4 of tuning the linear constants +* For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/ +* Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers +### Tuning Other Controllers +* Most of our controllers use PID but the logic of how it is applied is what makes the controller unique + * For linear and angular constants reference `Tuning PID` Above + * For other parameters reference each controller's description - +## Setting up and starting robot control ### Creating the chassis object * We will be creating a differential drive chassis in global scope * `DiffChassis(std::initializer_list left_motors, std::initializer_list right_motors, @@ -210,7 +215,7 @@ void opcontrol() { } } ``` - +## Autonomous Programming ### Autonomus Movement * There are two types of basic movment calls which you can use to write an autonomous 1. Move From dff06aa56bfa975adfcde8944e32b2c151bd10ae Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Thu, 16 May 2024 00:10:07 -0400 Subject: [PATCH 13/18] More Formatting --- README.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4c636854..4ae1b89d 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ void initialize() { odom->begin_localization(); //calibrate and begin localizing } ``` -### Tuning localizer +### Tuning a localizer * We will be tuning the TPI (ticks per inch) of the localizer 1. Move the robot forard a measured ammount 2. Read the odometry value @@ -77,7 +77,7 @@ void initialize() { 4. Set the new tpi value to the current tpi value multiplied by the value you got from step 3 * new tip = old tpi x adjustment factor -### Before you start: Basic understand on PID +### The basics of PID (Proportional Integral Derivative controllers) * **Linear error** = Linear distance from desired position to current position (inches) * **Angular error** = Angular distance from desired position to current position (degrees) * **Linear proportional constant** = Weight of how much linear error affects motor power (speeds up the robot movements) @@ -86,6 +86,7 @@ void initialize() { * **Angular proportional constant** = Weight of how much Angular error affects motor power (speeds up the robot movements) * **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) * **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) +* **Output of the control loop** = The error * proportional constant + the change in error * derivative constant + the sum of error over the entire time * integral constant ### Creating a PID controller @@ -160,6 +161,7 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) .with_slew(8) .build(); ``` + ## Tuning Controllers ### Tuning PID * We will be tuning the PID controller constants @@ -175,18 +177,15 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) ### Tuning Other Controllers * Most of our controllers use PID but the logic of how it is applied is what makes the controller unique - * For linear and angular constants reference `Tuning PID` Above + * For linear and angular constants reference **Tuning PID** Above * For other parameters reference each controller's description - ## Setting up and starting robot control ### Creating the chassis object * We will be creating a differential drive chassis in global scope -* `DiffChassis(std::initializer_list left_motors, std::initializer_list right_motors, - controller_ptr default_controller, ec_ptr ec, - double slew_step, pros::motor_brake_mode_e brakeMode)` +* Call `DiffChassis(std::initializer_list left_motors, std::initializer_list right_motors, controller_ptr default_controller, ec_ptr ec, double slew_step, pros::motor_brake_mode_e brakeMode)` ```cpp -auto chassis = voss::chassis::DiffChassis(LEFT_MOTORS, RIGHT_MOTORS, pid, ec, 8, pros::E_MOTOR_BRAKE_COAST); //use pid as default controller is suggested +auto chassis = voss::chassis::DiffChassis(LEFT_MOTORS, RIGHT_MOTORS, pid, ec, 8, pros::E_MOTOR_BRAKE_COAST); //we recommend using the default controller, pid ``` ### Starting the odometry localization @@ -212,6 +211,8 @@ void opcontrol() { while(true){ chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y)); + //or + chassis.arcade(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_X)); } } ``` From 238176f3b19b03c84f8f3a02045c11c5230ff5ab Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Thu, 16 May 2024 00:11:16 -0400 Subject: [PATCH 14/18] added equals --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4ae1b89d..206d85c3 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom * We will set up a localizer in global scope 1. Call `auto ec = voss::controller::ExitConditions::new_conditions()` 2. Setup conditions - * **Velocity base exit** `.add_settle(int settle_time, double tolerance, int initial_delay)` + * **Velocity base exit** = `.add_settle(int settle_time, double tolerance, int initial_delay)` * **Distance base exit** = `.add_tolerance(double linear_tolerance, double angular_tolerance, double tolerance_time)` * **Time base exit**(ms) = `.add_timeout(int time)` * **Motion chaining early exit**(as smoothness increase, accuracy decrease) = `.add_thru_smoothness(double thru_smoothness)` From 7a47bf647e7b9b6aabb2d5673cc202dd34734189 Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Thu, 16 May 2024 00:31:38 -0400 Subject: [PATCH 15/18] Add info about tuning other controllers --- README.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 206d85c3..f0298954 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ void initialize() { * **Angular proportional constant** = Weight of how much Angular error affects motor power (speeds up the robot movements) * **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration) * **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error) -* **Output of the control loop** = The error * proportional constant + the change in error * derivative constant + the sum of error over the entire time * integral constant +* **Output of the control loop** = The error X proportional constant + the change in error X derivative constant + the sum of error over the entire time X integral constant ### Creating a PID controller @@ -178,7 +178,27 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) ### Tuning Other Controllers * Most of our controllers use PID but the logic of how it is applied is what makes the controller unique * For linear and angular constants reference **Tuning PID** Above - * For other parameters reference each controller's description +* Minimum exit error + * The Outer tolerance zone in which the robot slows down to the tolerance point + * In PID controller, once in this zone the robot stops correcting for heading + * In Boomerang controller, once it is in this zone the robot starts correcting for heading + * Increasing this value will increase the tolerance allowing for the robot to exit the movement easier, but will decrease the accuracy of the movement + * This value will vary for the types of movements your robot is going to make but should be as small as possible without the robot getting stuck in movements and with the robot being able to correct for heading. To tune this start with small value and increase until desired results +* Minimun velocity for thru motion + * Sets the robot's velocity as it reaches the target poing and transitions between movements + * This value depends on the desired behavior for the robot +* Leading percentage + * Must be greater than 0 + * Must be less than 1 + * The larger the leading percentage, the further the robot will stray from a straight path to the point + * This allows for the robot to correct for large difference in staring and ending heading + * This requires more space for the robot to move around + * This value will vary based on the desired behavior of the robot, but to tune this start small and increase until desired results +* Slew rate + * Limits linear acceleration + * Higher slew reate = higher acceleration + * This value will vary based on the desired behavior of the robot, but to tune this start small and increase until desired results +* For other parameters reference each controller's description ## Setting up and starting robot control ### Creating the chassis object From 5267a2fb425c77a1de2be476375b143fba65020e Mon Sep 17 00:00:00 2001 From: cjsport11 Date: Thu, 16 May 2024 00:32:51 -0400 Subject: [PATCH 16/18] made an a lower case --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0298954..5df4b23e 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) ### Tuning Other Controllers * Most of our controllers use PID but the logic of how it is applied is what makes the controller unique - * For linear and angular constants reference **Tuning PID** Above + * For linear and angular constants reference **Tuning PID** above * Minimum exit error * The Outer tolerance zone in which the robot slows down to the tolerance point * In PID controller, once in this zone the robot stops correcting for heading From 8752e2616931656d2cd3cc5a16461f68a9b4fbf0 Mon Sep 17 00:00:00 2001 From: THERocky <101498190+Rocky14683@users.noreply.github.com> Date: Thu, 16 May 2024 12:44:20 +0800 Subject: [PATCH 17/18] Update README.md --- README.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5df4b23e..8d403bd4 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonomous code for VEX robots a piece of cake. ## Installing VOSS -1. Download the most recent [template](https://github.com/purduesigbots/VOSS/releases/tag/0.1.1) +1. Download the most recent [template](https://github.com/purduesigbots/VOSS/releases/tag/0.1.2) 2. Run this command from terminal `pros c fetch VOSS@0.1.2.zip` @@ -191,7 +191,7 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) * Must be greater than 0 * Must be less than 1 * The larger the leading percentage, the further the robot will stray from a straight path to the point - * This allows for the robot to correct for large difference in staring and ending heading + * This allows for the robot to correct for large difference in starting and ending heading * This requires more space for the robot to move around * This value will vary based on the desired behavior of the robot, but to tune this start small and increase until desired results * Slew rate @@ -205,7 +205,8 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) * We will be creating a differential drive chassis in global scope * Call `DiffChassis(std::initializer_list left_motors, std::initializer_list right_motors, controller_ptr default_controller, ec_ptr ec, double slew_step, pros::motor_brake_mode_e brakeMode)` ```cpp -auto chassis = voss::chassis::DiffChassis(LEFT_MOTORS, RIGHT_MOTORS, pid, ec, 8, pros::E_MOTOR_BRAKE_COAST); //we recommend using the default controller, pid +auto chassis = voss::chassis::DiffChassis(LEFT_MOTORS, RIGHT_MOTORS, pid, ec, 8, pros::E_MOTOR_BRAKE_COAST); +//we recommend using the pid controller as default controller ``` ### Starting the odometry localization @@ -245,7 +246,7 @@ void opcontrol() { - Boomerang Controller - Arc Controller **Please avoid using this controller, because we are still trying to optimize it.** * Parameters - 1. **Target** = Relative distance or {x, y} or {x, y, theta} (Remember for boomerang controller, you need to specify theta) + 1. **Target** = Relative distance, {x, y}, or {x, y, theta} (Remember for boomerang controller, you need to specify theta) 2. **Controller** = PID, Boomerang, or Arc 3. **Speed** = 0 - 100 (100 is default) 4. **Flags** = options of movements @@ -268,7 +269,7 @@ void autonomous(){ chassis.move(voss::Point{1.0, 1.0, 90}, boomerang); chassis.move(voss::Point{1.0, 1.0, 20}, boomerang, 70); chassis.move(voss::Point{1.0, 1.0, 30}, boomerang, 100, voss::Flags::RELATIVE); - chassis.move(voss::Point{1.0, 1.0, 10}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU); + chassis.move(voss::Point{1.0, 1.0, 10}, boomerang, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU); // using arc controller: chassis.move(voss::Point{1.0, 1.0}, arc); chassis.move(voss::Point{1.0, 1.0}, arc, 70); @@ -322,7 +323,7 @@ void autonomous(){ ``` ## Additional Resources -By following the [In Depth Documentation](**Coming Soon!**), your team should be able to create a competitive program for your competition robot. For people who are interested in more advanced programming such as programming skills runs, there is a lot of potential customization with this library. The following resources may interest people who want to take their programming skills further: +By following the In Depth Documentation(**Coming Soon!**), your team should be able to create a competitive program for your competition robot. For people who are interested in more advanced programming such as programming skills runs, there is a lot of potential customization with this library. The following resources may interest people who want to take their programming skills further: - [Take a C++ programming course.](https://www.codecademy.com/learn/learn-c-plus-plus) @@ -332,4 +333,4 @@ By following the [In Depth Documentation](**Coming Soon!**), your team should be - [Read the Vex Forums a lot](http://vexforum.com) -- [Get help from other teams on discord](https://discordapp.com/invite/9JDWW8e) \ No newline at end of file +- [Get help from other teams on discord](https://discordapp.com/invite/9JDWW8e) From 0418f50a2b557241512c8c749dccf0147e0d8a1b Mon Sep 17 00:00:00 2001 From: THERocky <101498190+Rocky14683@users.noreply.github.com> Date: Thu, 16 May 2024 12:51:55 +0800 Subject: [PATCH 18/18] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8d403bd4..be39b4db 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonom 5. Put `#include "VOSS/api.h"` in your main.h ### Creating exit conditions -* We will set up a localizer in global scope +* We will set up a exit conditions object in global scope 1. Call `auto ec = voss::controller::ExitConditions::new_conditions()` 2. Setup conditions * **Velocity base exit** = `.add_settle(int settle_time, double tolerance, int initial_delay)` @@ -196,7 +196,7 @@ auto arc = voss::controller::ArcPIDControllerBuilder(odom) * This value will vary based on the desired behavior of the robot, but to tune this start small and increase until desired results * Slew rate * Limits linear acceleration - * Higher slew reate = higher acceleration + * Higher slew rate = higher acceleration * This value will vary based on the desired behavior of the robot, but to tune this start small and increase until desired results * For other parameters reference each controller's description