How to Upload Program Pros V5 to Brain
Programming the Clawbot¶
Objective:¶
This tutorial volition guide you through bones programming of the VEX Clawbot.
Intended Audience:¶
This tutorial is intended for developers with some programming experience, but with petty to no experience with the PROS library. If y'all haven't programmed before, we recommend checking out all the "Introduction and Basic C++ Features" sections of this tutorial series; be sure to check out the "Classes and Objects" department every bit well.
Goals:¶
At the end of this tutorial yous will accept:
- Understood the basic organisation of an OkapiLib project
- Programmed a bones chassis with "tank" control or "arcade" control
- Programmed buttons to command the clawbot's lift
- Programmed a joystick axis to command the clawbot's hook
- Understood the standard subsystem module methodology
- Programmed an encoder-based democratic routine
Here's the robot nosotros'll be programming:
Yous can follow VEX's tutorial for building this robot hither.
For the purposes of this tutorial, nosotros've plugged in our motors into the following ports:
Port | Clarification | Port | Description |
---|---|---|---|
i | Left Wheels | 11 | |
2 | 12 | ||
3 | Hook Motor | xiii | |
4 | 14 | ||
5 | Vision Sensor | 15 | |
vi | xvi | ||
7 | 17 | ||
eight | Arm Motor | 18 | |
nine | nineteen | ||
x | Correct Wheels | xx |
Port 21: Radio
For the ADI:
Port | Description | Port | Description |
---|---|---|---|
A | Left Bumper | E | |
B | Correct Bumper | F | |
C | Grand | ||
D | H | Arm Limit |
To create, build, and upload a new project in PROS 3, run
prosv5 conduct new < path_to_project > prosv5 make prosv5 upload prosv5 terminal
The last 3 commands tin be simplified to prosv5 mut
.
Tank/Arcade Command¶
OkapiLib uses something called a ChassisController to interact with a robot's chassis. This interface lets you utilize open up-loop control methods to drive the robot around with a joystick, like tank and arcade control. It also provides methods to move the robot programmatically, like driving in an arc or only powering one side of the chassis. It likewise provides closed-loop control methods to drive a specific altitude or plow a specific bending.
There are two main subclasses we tin can use: ChassisControllerIntegrated and ChassisControllerPID. ChassisControllerIntegrated uses the V5 motor's built-in position and velocity control to move the robot around. This class is the easiest to utilise, and should be used by default. The other class, ChassisControllerPID, uses two PID controllers running on the V5 encephalon and sends velocity commands to the motors.
Nosotros will be using ChassisControllerIntegrated for this tutorial. Let's initialize information technology with our two motors in ports 1
and 10
, with the motor in port i
reversed.
using namespace okapi ; // Chassis Controller - lets us drive the robot effectually with open- or closed-loop control car drive = ChassisControllerFactory :: create ( - 1 , ten ); |
Next, allow's setup tank or arcade control. ChassisController provides methods for u.s.a. to apply, we just need to pass in joystick values which have been scaled to be in the range [-one, one]
. OkapiLib'south Controller returns analog values in the range [-1, 1]
, so we don't need to do any partition ourselves.
ane 2 3 iv 5 half dozen seven 8 ix 10 11 12 thirteen | // Joystick to read analog values for tank or arcade command. // Primary controller by default. Controller masterController ; while ( true ) { // Tank drive with left and right sticks. bulldoze . tank ( masterController . getAnalog ( ControllerAnalog :: leftY ), masterController . getAnalog ( ControllerAnalog :: rightY )); // Wait and requite upward the time nosotros don't need to other tasks. // Additionally, joystick values, motor telemetry, etc. all updates every 10 ms. pros :: filibuster ( x ); } |
1 2 three 4 five vi 7 8 9 x xi 12 13 | // Joystick to read analog values for tank or arcade control. // Master controller past default. Controller masterController ; while ( true ) { // Arcade drive with the left stick. drive . arcade ( masterController . getAnalog ( ControllerAnalog :: leftY ), masterController . getAnalog ( ControllerAnalog :: leftX )); // Wait and requite upward the time we don't need to other tasks. // Additionally, joystick values, motor telemetry, etc. all updates every 10 ms. pros :: filibuster ( x ); } |
Arm Command¶
This section will focus on controlling the clawbot'southward arm. At that place are two parts to this: showtime, the arm has a limit switch at the lesser of its travel range, so we should use that button to tell when we've hit a hard stop; second, the arm should be user-controlled with two buttons on the controller.
First, let'south focus on the limit switch at the bottom of the arm's travel range. When the arm hits this button, the arm motor should finish trying to make the arm move downwards. Nosotros can accomplish this using an if-statement that checks whether the button is pressed.
We can define our button as an ADIButton:
ADIButton armLimitSwitch ( 'H' );
And the arm motor:
The _mtr
syntax is called a user-defined literal. Information technology's a succinct style of initializing a motor, and is equivalent to calling the normal constructor. For case,
Motor foo = 1 _mtr ; // Motor in port 1 Motor foo ( i ); // Motor in port 1 Motor bar = ane _rmtr ; // Reversed motor in port 1 Motor bar ( one , true ); // Reversed motor in port 1
And then we can cheque if it's pressed and finish powering the arm motor:
// Don't power the arm if it is all the way downwards if ( armLimitSwitch . isPressed ()) { armMotor . moveVoltage ( 0 ); } else { // Normal arm control }
Adjacent, let's add the logic to make the arm user-controller with 2 buttons on the controller. Get-go, we need to define our two controller buttons equally ControllerButton instances:
ControllerButton armUpButton ( ControllerDigital :: A ); ControllerButton armDownButton ( ControllerDigital :: B );
Then we tin use them along with our limit switch logic from above to control the arm:
1 2 three 4 v 6 7 8 ix 10 11 12 13 | // Don't ability the arm if information technology is all the fashion down if ( armLimitSwitch . isPressed ()) { armMotor . moveVoltage ( 0 ); } else { // Else, the arm isn't all the manner downward if ( armUpButton . isPressed ()) { armMotor . moveVoltage ( 12000 ); // 12,000 millivolts } else if ( armDownButton . isPressed ()) { armMotor . moveVoltage ( - 12000 ); // -12,000 millivolts } else { armMotor . moveVoltage ( 0 ); // 0 millivolts, the motor will coast } } |
Autonomous Routine¶
To illustrate the airtight-loop control method that ChassisController has, allow'due south brand a simple autonomous routine to drive in a square.
Writing an autonomous routine is much easier when distances and turns can be done with real life units, so let'southward configure the ChassisController with the clawbot chassis'due south dimensions. This will require a change to the bulldoze's constructors; 2 additional parameters are needed. The first is the gearset of the motors on the chassis, in this example we will utilise the standard Green cartridges. The second is a list containing firstly the wheel diameter (iv") and secondly, the width of the wheel track (11.5").
// Chassis Controller - lets united states of america bulldoze the robot around with open- or airtight-loop command car drive = ChassisControllerFactory :: create ( ane , 10 , AbstractMotor :: gearset :: green , { 4 _in , 11.5 _in } ); |
Subsequently this, you tin can movement the chassis in actual units, such as inches and degrees.
for ( int i = 0 ; i < 4 ; i ++ ) { drive . moveDistance ( 12 _in ); // Drive forward 12 inches drive . turnAngle ( 90 _deg ); // Turn in place xc degrees } |
Wrap Up¶
This is the final product from this tutorial.
ane ii 3 iv five 6 vii 8 9 10 11 12 13 14 15 xvi 17 18 19 20 21 22 23 24 25 26 27 28 29 xxx 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include "okapi/api.hpp" using namespace okapi ; // Chassis Controller - lets u.s.a. drive the robot around with open up- or closed-loop control auto drive = ChassisControllerFactory :: create ( one , 10 , AbstractMotor :: gearset :: green , { 4 _in , 11.5 _in } ); void opcontrol () { // Joystick to read analog values for tank or arcade control // Master controller by default Controller masterController ; // Arm related objects ADIButton armLimitSwitch ( 'H' ); ControllerButton armUpButton ( ControllerDigital :: A ); ControllerButton armDownButton ( ControllerDigital :: B ); Motor armMotor = 8 _rmtr ; // Button to run our sample autonomous routine ControllerButton runAutoButton ( ControllerDigital :: X ); while ( true ) { // Tank drive with left and right sticks drive . tank ( masterController . getAnalog ( ControllerAnalog :: leftY ), masterController . getAnalog ( ControllerAnalog :: rightY )); // Don't power the arm if it is all the style down if ( armLimitSwitch . isPressed ()) { armMotor . moveVoltage ( 0 ); } else { // Else, the arm isn't all the way downward if ( armUpButton . isPressed ()) { armMotor . moveVoltage ( 12000 ); } else if ( armDownButton . isPressed ()) { armMotor . moveVoltage ( - 12000 ); } else { armMotor . moveVoltage ( 0 ); } } // Run the examination autonomous routine if nosotros press the button if ( runAutoButton . changedToPressed ()) { // Bulldoze the robot in a square design using closed-loop control for ( int i = 0 ; i < four ; i ++ ) { bulldoze . moveDistance ( 12 _in ); // Drive frontwards 12 inches bulldoze . turnAngle ( 90 _deg ); // Turn in place 90 degrees } } // Look and requite up the time we don't need to other tasks. // Additionally, joystick values, motor telemetry, etc. all updates every 10 ms. pros :: delay ( x ); } } |
1 2 3 4 v 6 7 viii 9 10 11 12 13 14 xv 16 17 xviii 19 twenty 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #include "okapi/api.hpp" using namespace okapi ; // Chassis Controller - lets united states of america drive the robot around with open- or closed-loop control auto bulldoze = ChassisControllerFactory :: create ( 1 , 10 , AbstractMotor :: gearset :: green , { 4 _in , 11.5 _in } ); void opcontrol () { // Joystick to read analog values for tank or arcade command // Master controller by default Controller masterController ; // Arm related objects ADIButton armLimitSwitch ( 'H' ); ControllerButton armUpButton ( ControllerDigital :: A ); ControllerButton armDownButton ( ControllerDigital :: B ); Motor armMotor = 8 _rmtr ; // Push button to run our sample autonomous routine ControllerButton runAutoButton ( ControllerDigital :: X ); while ( true ) { // Arcade drive with the left stick drive . arcade ( masterController . getAnalog ( ControllerAnalog :: leftY ), masterController . getAnalog ( ControllerAnalog :: rightY )); // Don't ability the arm if it is all the way down if ( armLimitSwitch . isPressed ()) { armMotor . moveVoltage ( 0 ); } else { // Else, the arm isn't all the way down if ( armUpButton . isPressed ()) { armMotor . moveVoltage ( 12000 ); } else if ( armDownButton . isPressed ()) { armMotor . moveVoltage ( - 12000 ); } else { armMotor . moveVoltage ( 0 ); } } // Run the examination autonomous routine if we press the button if ( runAutoButton . changedToPressed ()) { // Drive the robot in a square design using airtight-loop control for ( int i = 0 ; i < 4 ; i ++ ) { drive . moveDistance ( 12 _in ); // Drive forward 12 inches bulldoze . turnAngle ( xc _deg ); // Turn in place 90 degrees } } // Expect and requite up the time we don't demand to other tasks. // Additionally, joystick values, motor telemetry, etc. all updates every 10 ms. pros :: delay ( x ); } } |
Source: https://pros.mechdancer.org/okapi/tutorials/walkthrough/clawbot.html
0 Response to "How to Upload Program Pros V5 to Brain"
Post a Comment