Skip to content

Commit 380743c

Browse files
Rocky14683cjsport11
andauthored
Readme for 0.1.2 release (#99)
* Added READ ME * Fixed Formatting * More formatting fixes * Back ticks not single quotes * Update README.md * Fixed back tick use * Update README.md Add reverse flag and fix thru flag explanation * Update README.md - ec * Update README.md * Touchup and added additional resources * added a space * Changed formatting and added more to tuning * More Formatting * added equals * Add info about tuning other controllers * made an a lower case * Update README.md * Update README.md --------- Co-authored-by: cjsport11 <[email protected]>
1 parent cb55a39 commit 380743c

File tree

1 file changed

+336
-0
lines changed

1 file changed

+336
-0
lines changed

README.md

Lines changed: 336 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,336 @@
1+
# PROS With VOSS
2+
3+
### Introduction
4+
VOSS is a [PROS](https://pros.cs.purdue.edu/) library that makes writing autonomous code for VEX robots a piece of cake.
5+
6+
## Installing VOSS
7+
1. Download the most recent [template](https://github.com/purduesigbots/VOSS/releases/tag/0.1.2)
8+
9+
2. Run this command from terminal `pros c fetch [email protected]`
10+
11+
3. `cd` into your pros project directory in your terminal
12+
13+
4. Apply the library to the project `pros c apply VOSS`
14+
15+
5. Put `#include "VOSS/api.h"` in your main.h
16+
17+
### Creating exit conditions
18+
* We will set up a exit conditions object in global scope
19+
1. Call `auto ec = voss::controller::ExitConditions::new_conditions()`
20+
2. Setup conditions
21+
* **Velocity base exit** = `.add_settle(int settle_time, double tolerance, int initial_delay)`
22+
* **Distance base exit** = `.add_tolerance(double linear_tolerance, double angular_tolerance, double tolerance_time)`
23+
* **Time base exit**(ms) = `.add_timeout(int time)`
24+
* **Motion chaining early exit**(as smoothness increase, accuracy decrease) = `.add_thru_smoothness(double thru_smoothness)`
25+
3. Call it to build --> `.build()`
26+
```cpp
27+
auto ec = voss::controller::ExitConditions::new_conditions()
28+
.add_settle(400, 0.5, 400)
29+
.add_tolerance(1.0, 2.0, 200)
30+
.add_timeout(22500)
31+
.add_thru_smoothness(4)
32+
.build();
33+
```
34+
### Creating a localizer
35+
* We will set up a localizer in global scope
36+
* You have three choices, IME (Internal motor encoder), ADI Encoders, or Smart Port Rotation sensors.
37+
1. Call `auto odom = voss::localizer::voss::localizer::TrackingWheelLocalizerBuilder::new_builder()`
38+
2. Setup inputs to localizer
39+
* **Left** :
40+
- `.with_left_encoder(int adi_port)`
41+
- `.with_left_encoder(int smart_port, int adi_port)`
42+
- `.with_left_rotation(int port)`
43+
- `.with_left_motor(int port)`
44+
* **Right** :
45+
- `.with_right_encoder(int adi_port)`
46+
- `.with_right_encoder(int smart_port, int adi_port)`
47+
- `.with_right_rotation(int port)`
48+
- `.with_right_motor(int port)`
49+
* **IMU** :
50+
- `.with_imu(int imu_port)`
51+
* **Track width**
52+
- `.with_track_width(double track_width_distance)`
53+
* **Left right TPI** (ratio of encoder rotations to 1 inch of linear movement)
54+
- `.with_left_right_tip(double tpi_value)`
55+
3. Call it to build --> `.build()`
56+
```cpp
57+
auto odom = voss::localizer::TrackingWheelLocalizerBuilder::new_builder()
58+
.with_right_motor(10)
59+
.with_left_motor(-4)
60+
.with_track_width(11)
61+
.with_left_right_tpi(18.43)
62+
.with_imu(16)
63+
.build();
64+
65+
66+
void initialize() {
67+
pros::lcd::initialize();
68+
odom->begin_localization(); //calibrate and begin localizing
69+
}
70+
```
71+
### Tuning a localizer
72+
* We will be tuning the TPI (ticks per inch) of the localizer
73+
1. Move the robot forard a measured ammount
74+
2. Read the odometry value
75+
3. Divide the amount you moved the robot by the measured movement value from the odometry
76+
* adjustment factor = robot actual move amount/odometry measured amount
77+
4. Set the new tpi value to the current tpi value multiplied by the value you got from step 3
78+
* new tip = old tpi x adjustment factor
79+
80+
### The basics of PID (Proportional Integral Derivative controllers)
81+
* **Linear error** = Linear distance from desired position to current position (inches)
82+
* **Angular error** = Angular distance from desired position to current position (degrees)
83+
* **Linear proportional constant** = Weight of how much linear error affects motor power (speeds up the robot movements)
84+
* **Linear derivative constant** = Weight of how much the change in linear error affects the motor power (increases the rate of acceleration and deceleration)
85+
* **Linear integral constant** = Weight of how much overall accumulated linear error affects the motor power (increase to improve slight long term error)
86+
* **Angular proportional constant** = Weight of how much Angular error affects motor power (speeds up the robot movements)
87+
* **Angular derivative constant** = Weight of how much the change in Angular error affects the motor power (increases the rate of acceleration and deceleration)
88+
* **Angular integral constant** = Weight of how much overall accumulated Angular error affects the motor power (increase to improve slight long term error)
89+
* **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
90+
91+
92+
### Creating a PID controller
93+
* We will set up a PID controller for chassis movements in global scope
94+
1. Call `auto pid = voss::controller::PIDControllerBuilder::new_builder(odom)`
95+
2. Set up inputs to pid controller
96+
* **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)`
97+
* **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)`
98+
* **Minimum exit error** = `.with_min_error(5)`
99+
* **Minimun velocity for thru motion** = `.with_min_vel_for_thru(100)`
100+
3. Call it to build --> `.build()`
101+
```cpp
102+
auto pid = voss::controller::PIDControllerBuilder::new_builder(odom)
103+
.with_linear_constants(20, 0.02, 169)
104+
.with_angular_constants(250, 0.05, 2435)
105+
.with_min_error(5)
106+
.with_min_vel_for_thru(100)
107+
.build();
108+
```
109+
110+
### Creating a Boomerang controller
111+
* Boomerang controller demo on [Desmos](https://www.desmos.com/calculator/zl0pizecei?lang=zh-TW)
112+
* We will set up a Boomerang controller for chassis movements in global scope
113+
1. Call `auto boomerang = voss::controller::BoomerangControllerBuilder::new_builder(odom)`
114+
2. Set up inputs to boomerang controller
115+
* **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)`
116+
* **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)`
117+
* **Leading percentage**(greater than 0, but less than 1) = `.with_lead_pct(0.5)`
118+
* **Minimum exit error** = `.with_min_error(5)`
119+
* **Minimun velocity for thru motion** = `.with_min_vel_for_thru(100)`
120+
3. Call it to build --> `.build()`
121+
```cpp
122+
auto boomerang = voss::controller::BoomerangControllerBuilder::new_builder(odom)
123+
.with_linear_constants(20, 0.02, 169)
124+
.with_angular_constants(250, 0.05, 2435)
125+
.with_lead_pct(0.5)
126+
.with_min_vel_for_thru(70)
127+
.with_min_error(5)
128+
.build();
129+
```
130+
131+
### Creating a Swing controller
132+
* We will set up a Swing controller for chassis movements in global scope
133+
1. Call `auto swing = voss::controller::SwingControllerBuilder::new_builder(odom)`
134+
2. Set up inputs to swing controller
135+
* **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)`
136+
3. Call it to build --> `.build()`
137+
```cpp
138+
auto swing = voss::controller::SwingControllerBuilder::new_builder(odom)
139+
.with_angular_constants(250, 0.05, 2435)
140+
.build();
141+
```
142+
143+
### Creating a Arc controller
144+
* We will set up a Arc controller for chassis movements in global scope
145+
* **Please avoid using this controller, because we are still trying to optimize it.**
146+
1. Call `voss::controller::ArcPIDControllerBuilder(odom)`
147+
2. Set up inputs to pid controller
148+
* **Track width** = `.with_track_width(16)`
149+
* **Linear proportional, derivative, and integral constant (in this order)** = `.with_linear_constants(20, 0.02, 169)`
150+
* **Angular proportional, derivative, and integral constant (in this order)** = `.with_angular_constants(250, 0.05, 2435)`
151+
* **Leading percentage** (greater than 0, but less than 1) = `.with_lead_pct(0.5)`
152+
* **Minimum exit error** = `.with_min_error(5)`
153+
* **Slew rate(limits linear acceleration. Higher slew rate = higher acceleration)** = `.with_slew(8)`
154+
4. Call it to build --> `.build()`
155+
```cpp
156+
auto arc = voss::controller::ArcPIDControllerBuilder(odom)
157+
.with_track_width(16)
158+
.with_linear_constants(20, 0.02, 169)
159+
.with_angular_constants(250, 0.05, 2435)
160+
.with_min_error(5)
161+
.with_slew(8)
162+
.build();
163+
```
164+
165+
## Tuning Controllers
166+
### Tuning PID
167+
* We will be tuning the PID controller constants
168+
* 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
169+
* Tune linear constants first
170+
1. Start with the constants all being 0
171+
2. Increase the proportional constant until oscillations start (the amount you need to increase by and total amount will vary with each robot)
172+
3. Slowly increase the derivative constant until the robot is no longer overshooting its target and oscilations have stopped
173+
4. If the robot is compounding error over time, slowly increase the integral constant to reduce that error
174+
* Tune the angular constants using steps 1-4 of tuning the linear constants
175+
* For more information on PID and Odometry check out the SIGBots Wiki at https://wiki.purduesigbots.com/
176+
* Another great intro to PID article can be found at http://georgegillard.com/documents/2-introduction-to-pid-controllers
177+
178+
### Tuning Other Controllers
179+
* Most of our controllers use PID but the logic of how it is applied is what makes the controller unique
180+
* For linear and angular constants reference **Tuning PID** above
181+
* Minimum exit error
182+
* The Outer tolerance zone in which the robot slows down to the tolerance point
183+
* In PID controller, once in this zone the robot stops correcting for heading
184+
* In Boomerang controller, once it is in this zone the robot starts correcting for heading
185+
* Increasing this value will increase the tolerance allowing for the robot to exit the movement easier, but will decrease the accuracy of the movement
186+
* 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
187+
* Minimun velocity for thru motion
188+
* Sets the robot's velocity as it reaches the target poing and transitions between movements
189+
* This value depends on the desired behavior for the robot
190+
* Leading percentage
191+
* Must be greater than 0
192+
* Must be less than 1
193+
* The larger the leading percentage, the further the robot will stray from a straight path to the point
194+
* This allows for the robot to correct for large difference in starting and ending heading
195+
* This requires more space for the robot to move around
196+
* This value will vary based on the desired behavior of the robot, but to tune this start small and increase until desired results
197+
* Slew rate
198+
* Limits linear acceleration
199+
* Higher slew rate = higher acceleration
200+
* This value will vary based on the desired behavior of the robot, but to tune this start small and increase until desired results
201+
* For other parameters reference each controller's description
202+
203+
## Setting up and starting robot control
204+
### Creating the chassis object
205+
* We will be creating a differential drive chassis in global scope
206+
* Call `DiffChassis(std::initializer_list<int8_t> left_motors, std::initializer_list<int8_t> right_motors, controller_ptr default_controller, ec_ptr ec, double slew_step, pros::motor_brake_mode_e brakeMode)`
207+
```cpp
208+
auto chassis = voss::chassis::DiffChassis(LEFT_MOTORS, RIGHT_MOTORS, pid, ec, 8, pros::E_MOTOR_BRAKE_COAST);
209+
//we recommend using the pid controller as default controller
210+
```
211+
212+
### Starting the odometry localization
213+
* We will be starting odomentry localization in the initalize scope
214+
1. Call `odom->begin_localization()`
215+
```cpp
216+
void initialize() {
217+
odom->begin_localization(); //calibrate and begin localizing
218+
pros::delay(3000); //don't move the robot for 3 seconds
219+
}
220+
```
221+
222+
### Driver Control
223+
* We will be setting up control scheme for the drive in the opcontrol scope
224+
1. Define the controller
225+
* Call `pros::Controller master(pros::E_CONTROLLER_MASTER)`
226+
2. Inside the while loop set the movement
227+
* **Tank control** = `chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y))`
228+
* **Arcade control** = `chassis.arcade(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_X))`
229+
```cpp
230+
void opcontrol() {
231+
pros::Controller master(pros::E_CONTROLLER_MASTER);
232+
233+
while(true){
234+
chassis.tank(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_Y));
235+
//or
236+
chassis.arcade(master.get_analog(ANALOG_LEFT_Y), master.get_analog(ANALOG_RIGHT_X));
237+
}
238+
}
239+
```
240+
## Autonomous Programming
241+
### Autonomus Movement
242+
* There are two types of basic movment calls which you can use to write an autonomous
243+
1. Move
244+
* Controllers
245+
- PID Controller
246+
- Boomerang Controller
247+
- Arc Controller **Please avoid using this controller, because we are still trying to optimize it.**
248+
* Parameters
249+
1. **Target** = Relative distance, {x, y}, or {x, y, theta} (Remember for boomerang controller, you need to specify theta)
250+
2. **Controller** = PID, Boomerang, or Arc
251+
3. **Speed** = 0 - 100 (100 is default)
252+
4. **Flags** = options of movements
253+
* **THRU** = Enable motion chaining
254+
* **ASYNC** = Next lines of code start executing even before movement is finished
255+
* **REVERSE** = Robot moves backwards
256+
* **RELATIVE** = Not absolute coordinate system
257+
* **NONE** = Defualt
258+
* Call `chassis.move(Parameters)`
259+
```cpp
260+
void autonomous(){
261+
// using default controller:
262+
chassis.move(10); //move forward 10
263+
chassis.move(-10, 100, voss::Flags::REVERSE) //move backward 10
264+
chassis.move(10, 70);
265+
chassis.move(voss::Point{1.0, 1.0}, 70);
266+
chassis.move(voss::Point{1.0, 1.0, 30}, 100, voss::Flags::RELATIVE);
267+
chassis.move(voss::Point{1.0, 1.0}, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU);
268+
// using boomerang controller:
269+
chassis.move(voss::Point{1.0, 1.0, 90}, boomerang);
270+
chassis.move(voss::Point{1.0, 1.0, 20}, boomerang, 70);
271+
chassis.move(voss::Point{1.0, 1.0, 30}, boomerang, 100, voss::Flags::RELATIVE);
272+
chassis.move(voss::Point{1.0, 1.0, 10}, boomerang, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU);
273+
// using arc controller:
274+
chassis.move(voss::Point{1.0, 1.0}, arc);
275+
chassis.move(voss::Point{1.0, 1.0}, arc, 70);
276+
chassis.move(voss::Point{1.0, 1.0}, arc, 100, voss::Flags::RELATIVE);
277+
chassis.move(voss::Point{1.0, 1.0}, arc, 100, voss::Flags::REVERSE | voss:Flags::ASYNC | voss::Flags::THRU);
278+
}
279+
```
280+
281+
2. Turn
282+
* Controllers
283+
- PID controller
284+
- Swing controller
285+
* Parameters
286+
1. **Target** = angle or {x, y}
287+
2. **Controller** = PID or Swing
288+
3. **Desired speed** = 0 - 100 (100 is default)
289+
4. **Flags** = options of movements
290+
* **THRU** = Enable motion chaining
291+
* **ASYNC** = Next lines of code start executing even before movement is finished
292+
* **REVERSE** = Robot moves backwards (for swing controller)
293+
* **RELATIVE** = Not absolute coordinate system
294+
* **NONE** = Defualt
295+
5. **Angular Direction** = direction of turn
296+
* **AUTO** = default
297+
* **COUNTERCLOCKWISE** or **CCW**
298+
* **CLOCKWISE** or **CW**
299+
* Call `chassis.turn(parameters)` or `chassis.turn_to(parameters)`
300+
```cpp
301+
void autonomous(){
302+
//using default controller:
303+
chassis.turn(90);
304+
chassis.turn_to({10, 10});
305+
chassis.turn(90, 50);
306+
chassis.turn_to({10, 10}, 40);
307+
chassis.turn(90, 100, voss::Flags::RELATIVE);
308+
chassis.turn_to({10, 10}, 40, voss::Flags::RELATIVE);
309+
chassis.turn(90, 100, voss::Flags::THRU | voss::Flags::ASYNC);
310+
chassis.turn(90, 100, voss::Flags::NONE, voss::AngularDirection::CW);
311+
chassis.turn_to({10, 10}, 40, voss::Flags::RELATIVE | voss::Flags::THRU, voss::AngularDirection::CW);
312+
313+
//using swing controller:
314+
chassis.turn(90, swing);
315+
chassis.turn_to({10, 10}, swing);
316+
chassis.turn(90, swing, 50);
317+
chassis.turn_to({10, 10}, swing, 40);
318+
chassis.turn(90, 100, swing, voss::Flags::RELATIVE);
319+
chassis.turn_to({10, 10}, swing, 40, voss::Flags::RELATIVE | voss::Flags::REVERSE);
320+
chassis.turn(90, 100, swing, voss::Flags::NONE, voss::AngularDirection::CW);
321+
chassis.turn_to({10, 10}, swing, 40, voss::Flags::RELATIVE | voss::Flags::THRU, voss::AngularDirection::CW);
322+
}
323+
```
324+
## Additional Resources
325+
326+
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:
327+
328+
- [Take a C++ programming course.](https://www.codecademy.com/learn/learn-c-plus-plus)
329+
330+
- [Explore the PROS API](https://pros.cs.purdue.edu/v5/index.html)
331+
332+
- [Learn PID](http://georgegillard.com/documents/2-introduction-to-pid-controllers)
333+
334+
- [Read the Vex Forums a lot](http://vexforum.com)
335+
336+
- [Get help from other teams on discord](https://discordapp.com/invite/9JDWW8e)

0 commit comments

Comments
 (0)