05 - Controller Mode (Handheld)

Overview

In this lesson, we will exist working on controlling our robot with some class of handheld controller - A USB video game controller plugged into the computer and the VEX Controller for the physical robot. This page goes over how to prepare this up and the necessary code y'all will write.

    1. Built in Controller Mode (partially) - Briefly explains how RobotC Level Builder has a built in controller mode (partially).

    2. Connecting your USB Controller to Your Figurer - How to plug in a handheld USB controller to Windows, how to make sure information technology is existence detected, and how to check which buttons are which.

    3. Coding Joystick Configuration in RobotC - What necessary lines of lawmaking yous demand to write to exist able to use a handheld controller with RobotC

  1. Overall Logic of Coding a Controller - Goes over the overall logic of writing your lawmaking for controller way.

  2. Sample Code to Apply a Controller - This is a sample code you can copy and paste into RobotC that will allow you to move forward by pressing a button on your controller.

    1. Of import Notation - Debugger Window - In RobotC it is oft necessary to open up the joystick debugger window for RobotC to detect inputs from Windows at all. Too, this shows y'all which push button is named which.

    2. Actual Coding Names for a Handheld Controller - How to find which buttons, joysticks, triggers and d-pad inputs are chosen what in RobotC.

    3. Macro - The idea is that yous can pre-program certain sets of instructions to a unmarried button click such as "turn xc degrees", or any string of commands.

    4. What is VJoy - A cursory explanation of what this stands for and how we will use it.

    5. How to Set Up VJoy - This takes you through the actual setup of VJoy, describing how to employ and a few common issues that might arise.

  3. Common Mistakes

Built-in Controller Mode (partially)

The RobotC Level Builder actually has a built-in controller mode (partially). The standard controller setup shown in the table to a higher place is a built-in feature of RobotC Level Architect. If you compile and download a program to your virtual robot in Level Builder, you can freely use these controller buttons until you press the "Play" push. Equally soon as you lot printing the "Play" button, it is now running only your compiled programme and not any built-in RobotC code.

Standard Setup in RobotC Level Builder

"W" central - Robot moves forward

"Due south" key - Robot moves in opposite

"A" key - Robot turns left

"D" key - Robot turns right

"<" cardinal - Robot arm moves up

">" key - Robot arm moves downward

"}" central - Robot hook opens

"{" key - Robot claw closes

We volition be completely programming our own controller manner as the physical robot has no pre-programmed controller mode. Too, the Curriculum Companion that nosotros will go back to off and on also do not have a congenital-in controller way. The above pre-built controller mode only works in Level Builder and only before the "Play" button is pressed .

Connecting your USB Controller to Your Estimator

    1. Connect the USB controller to your calculator. Almost modernistic computers volition automatically detect a USB game controller connected and set information technology up for you.

      1. \

    1. Now we will test that Windows is detecting inputs from the controller. In your Command Panel, find "Set Up USB Game Controllers". This can easily be constitute using the Cortana search bar.

    1. Select the controller yous have plugged in (in that location is probable simply one controller shown), and click on "Properties"

    1. Y'all will be shown a screen that looks like the one below. Brainstorm to motion the different joysticks and printing the buttons on your controller. Every button, trigger, joystick and d-pad press should annals on the screen.

If this does not piece of work correctly, you actually accept ii options:

    1. Find the correct drivers on the internet that match your Operating System and actual controller y'all are property, download these, install them and endeavour once again.

    2. Trying a dissimilar controller. This is often the easiest ready if you lot have extra controllers lying around.

Coding Joystick Configuration in RobotC

Just like you need to include #pragma config(StandardModel, "RVW CLAWBOT") in your code to tell RobotC which robot your are using (CLAWBOT), you need to tell RobotC that you will exist using commands, functions and variables from a controller input.

We demand to include two main things in your code to correctly get admission to the controller:

    1. RobotC Commands - At the top of the lawmaking you are writing you demand to include #include "JoystickDriver.c"

    2. This sets upward the master joystick commands and functions that you volition write in RobotC

    3. Windows Inputs - In your chief body of code, we volition go out a forever loop running that will constantly detect when buttons are pressed. The very beginning line in this forever loop needs to be: getJoystickSettings(joystick); Each time this is called, this gets the inputs beingness pressed in that cycle of the loop (lasting a fraction of a second).

The lawmaking should await like this:

#pragma config(StandardModel, "RVW CLAWBOT") // Gets the standard setup for the CLAWBOT

#include "JoystickDriver.c" // Gets the C lawmaking for the joystick setup in RobotC for functions such as buttons beingness pressed

job main()

{

while(true) {

getJoystickSettings(joystick); // Gets the current joystick setup y'all have setup in Windows/Vjoy

// Write your code here that volition actually detect buttons existence pressed and tell the robot what to do

}

}

Overall Logic of Coding a Controller

The overall idea is that we demand to write code that is constantly checking/waiting for you lot to printing a button. Nosotros practice this past writing a forever loop without any look times. In this way, the lawmaking is e'er continuously running through the forever loop (no stops), fifty-fifty if you are pressing a button. I clocked my controller lawmaking on my circa 2010 Samsung laptop, and while moving forward (property down a button), the loop was running through virtually 450,000 times per second.

The overall idea of your code volition be this:

#pragma, #include, etc

In your principal, a forever loop starts hither

get joystick settings from windows

IF push i pressed

do this

IF push button 2 pressed

do this

IF button 3 pressed

practice this

... etc etc with each of the 8 buttons

ELSE

set all motors to zilch

In this way, when it is running through the plan hundreds of yard of times a second (or million depending on comp speed), it is instantly setting the motors to the values y'all want and then checking again and once again and again. As soon as yous allow go of the button, the "ELSE" says everything stay off until you press something again.

Note: If you want to clock how many times your code runs through your forever loop per second (as I was simply curious), you lot can employ this lawmaking: Link . Compile and download the plan to your robot. Make certain you open up the debugger window that shows "Global Variables". It volition go on a score/count of repetitions while you have button i pressed (the "W" key). Use your cell phone timer and exercise these simultaneously - press start on your phone timer and press-and-agree the "W" key. When you are ready (after 20-xxx seconds for a skilful boilerplate), printing cease on the timer and take your finger off of the "W" key. Dissever the score/count past the fourth dimension and you become the boilerplate number of times the forever loop ran per 2d.

Sample Code to Employ a Controller

Below is some lawmaking that yous can copy and paste into your RobotC. The lawmaking detects when "Push 1" on "Joystick ane" is pressed.

While "Button 1" is existence pressed, the robot'south left and right motors volition be on total power forrad.

Equally presently every bit yous allow go of "Push button 1", the robot's motors will be fix to zero.

While "Button two" is being pressed, the robot's left and right motors will be on full power reverse.

Once more this loop is running continuously hundreds of thousands of times per second. Each time it checks, it sets the ability level of the motors. There are no wait times .

#pragma config(StandardModel, "RVW CLAWBOT")

#include "JoystickDriver.c"

task main()

{

while(true) { // This is the forever loop that keeps continuously running over and over waiting for a button to be pressed

getJoystickSettings(joystick);

if ( joy1Btn(1) == one ) { // This means "If Button one on Controller #1 is pressed"

motor[leftMotor] = 127; // If push ane is pressed, motility frontwards (over and over in fractions of seconds)

motor[rightMotor] = 127;

}

else if ( joy1Btn(ii) == 1 ) { // This ways "Otherwise, if Button ii on Controller #1 is pressed"

motor[leftMotor] = -127; // If button 2 is pressed, motility backwards (over and over in fractions of seconds)

motor[rightMotor] = -127;

}

else {

motor[leftMotor] = 0; // If neither button 1 or button two are being pressed, don't motion at all (over and over every fraction of a second)

motor[rightMotor] = 0;

}

}

}

Note - Notice that you are using "joy1Btn" every time no matter which button you are referring to. This is considering you are talking most Controller #1 or Joystick #ane, and then the number in parenthesis is the number of the button on Controller #one that you are talking virtually.

Important Annotation - Debugger Window

Big motion-picture show - there are two actually important reasons to open up upward the "Joystick Command - Basic" debugger window that is shown below:

    1. RobotC often doesn't "connect" with Windows and receive joystick input at all until you lot open this debugger window. None of your lawmaking will piece of work until this window is open (nigh 50% of the time).

    2. When you lot have this window open up, you can printing any button and encounter the name of the button in the button left where it says "Buttons: _____". This tells you which button is which for y'all to write code with.

RobotC sometimes does not detect controller buttons. It is often necessary to open the Debugger Window called "Joystick Control - Basic" to kick start the connectedness between Windows and RobotC. Y'all tin open up this debugger window from the summit menu past selecting "Robot ---> Debugger Windows ---> Joystick Control - Basic"

In RobotC from the top bill of fare select:

Robot --> Debugger Windows --> Joystick Command - Basic

You will see the screen beneath.

Note that alternatively to manually opening this debugger window, yous can include this line of lawmaking in your program and it will open the debugger window each time when compiled

#pragma debuggerWindows("joystickSimple");

Refresh the Connection - If ever you open the debugger window above and meet the "Joystick Not Equipped" bulletin, you can refresh the connection. Select the drop-down menu underneath and select "Refresh List". This usually always gets the connection going.

Actual Coding Names for a Handheld Controller

Note - On the back of our classroom controllers is a little switch that determines how the inputs/buttons are setup in windows. Set this switch to the correct side then it is on the "D" - rather than the "X" on the left. From now on information technology will evidence up in windows as a "Dual Action" rather than as an "F310" controller.

Windows tin can support whatever number of handheld controllers from wired USB controllers to Bluetooth connected video game console controllers. These controllers will all function the same, with small button mapping differences.

Setting upwards each individual blazon of controller will have a slightly different process (automatic, installing drivers, pairing with Bluetooth, etc). However, once correctly detected by your reckoner, every controller will basically have these inputs:

    1. Buttons

    2. D-Pad

    3. 2 Joysticks

    4. Triggers?

1. Buttons - The buttons on your controller will show up as buttons numbered from zip to 7 (or however many buttons your controller has).

You can check which button is which by just having the debugger window open and pressing buttons.

Important Note - the push button number that shows up in the debugger window and the button number nosotros code with are ever off past one.

The below image shows button 1 being pressed on the controller (we will use the button #one in our code), notwithstanding information technology registers equally push null in the debugger window. Y'all will ever add one to this debugger window value, because the array of buttons starts counting at zero, while RobotC starts counting at ane. The #include "JoystickDriver.c" sets the values of the buttons this way, and you lot could even manually change this back yourself.

While pressing Button #1,

the robot will drive frontwards and when non pressing it the robot will stay stationary

When Push #1 is pressed,

the robot will drive forward for i 2d and then stop

if ( joy1Btn(1) == 1 ) {

motor[leftMotor] = sixty;

motor[rightMotor] = 60;

wait1Msec(m);

}

motor[leftMotor] = 0;

motor[rightMotor] = 0;

This sort of code with a wait time would be used every bit a "Macro" gear up of instructions. You could have a push button that turns your robot exactly 90 degrees to the correct for instance. Nix else will happen while this wait time is occurring in your loop. Your robot volition be completely unresponsive during this time and all past motor values volition stay at their current level until the wait time is over.

if ( joy1Btn(1) == 1 ) {

motor[leftMotor] = lx;

motor[leftMotor] = 60;

} else {

motor[leftMotor] = 0;

motor[leftMotor] = 0;

}

Notation that joy1Btn(1) refers to "Button #1" in images of the controller, just shows upward in the debugger window equally "Buttons: 00"

2. D-Pad - The D-PAD is digital in the sense that each of 8 possible directions is represented by a number (like a single button in each direction). There is not a spectrum or gradient of values.

The control y'all use: joystick.joy1_TopHat

The values of this are:

    • -1 if it is not pressed

    • 0-7 depending on which management of the "octant" you are point. Each direction has a discrete number (up, downwardly, left, correct, and the four diagonals). The numbering starts with a zero every bit pointed up and and then going around clockwise in numerical order.

      • 0 = Up

      • 1 = Diagonally up and right

      • 2 = Right

      • ... etc

To check which button is which, have the "Joystick Control - Basic" debugger window open up and but start pressing directions. In the display at the bottom left, the direction number will show upwardly by "POV". Check out the image below and notice that when no direction is pressed (leftmost) the value of POV is -i. When a management is pressed (every bit shown in the top red circles), then a new POV value shows up at the lesser.

Coding with the D-Pad is the same as coding with any other joystick button. Below is the aforementioned code, based on two separate types of inputs. The outset one uses whether or not "Button one" is pressed, while the 2nd is using the D-Pad's "Up" arrow.

Using "Button one" to Movement Frontwards

if ( joy1Btn(1) == 1 ) {

motor[leftMotor] = 60;

motor[leftMotor] = 60;

)

Using the D-Pad "Up" Direction to Move Forward

if ( joystick.joy1_TopHat == 0 ) {

motor[leftMotor] = 60;

motor[leftMotor] = 60;

)

iii. Two Joysticks - The two joysticks have a spectrum/slope of values. The #include "JoystickDriver.c" sets the values of the joysticks to range from -127 to +127 and so they are hands used with the motors.

The Left Joystick is "x1" and "y1" on Joy1 (Controller #1)

The Right Joystick is "x2" and "y2" on Joy1 (Controller #1)

The lawmaking yous utilise is:

  • joystick.joy1_x1

  • joystick.joy1_y1

  • These represent the x- and y- values of the joystick location. It is like a coordinate airplane that goes from -127 to +127. The values are usually opposite what you lot desire, as when you move the joystick up, the part of the joystick within the controller is actually going down.

You tin can use this in your code like this:

while(true) {

getJoystickSettings(joystick);

motor[leftMotor] = joystick.joy1_y1;

}

The code you use is:

  • joystick.joy1_x2

  • joystick.joy1_y2

  • These correspond the 10- and y- values of the joystick location. It is like a coordinate plane that goes from -127 to +127. The values are usually opposite what you want, as when you motility the joystick up, the part of the joystick inside the controller is actually going down.

You can utilize this in your lawmaking similar this:

while(true) {

getJoystickSettings(joystick);

motor[rightMotor] = joystick.joy1_y2;

}

Together these joysticks can exist used in a forever loop like this:

while(true) {

getJoystickSettings(joystick);

motor[leftMotor] = -joystick.joy1_y1;

motor[rightMotor] = -joystick.joy1_y2;

}

iv. Triggers - The left and right triggers are the oddball here. Depending on the controller and the version of Windows yous are using, these may show up every bit a z-axis joystick or equally button numbers. Y'all will have to test this out in the debugger window and come across how your controller and version of Windows behaves. It is non necessary to apply this, merely given the tutorials virtually buttons and joysticks already, simply apply the correct method to the triggers - whichever way they function on your computer.

Macros

Over the next few weeks we will have you programme a set of commands that will exist executed by a single push button press. For example, when a push button is pressed but once, have the robot travel forward 100cm and so turn right xc degrees and travel another 100cm.

We will refer to these stored commands equally a "Macro". Each of these volition be pre-programmed with a set of instructions.

Common Mistakes

    1. Push turns a motor on, only the motor doesn't stop when button is released - This is because you are not setting the motor to zero in the ELSE section of your code. Brand sure that your ELSE section conspicuously sets all 4 motors to power levels of zero. This means that if yous are not pressing any buttons, the robot will non move at all (unless it is still finishing some previous macro command that involves wait times).

    2. The arm motor won't move! - I coded it correctly, and even when I check the debugger window it says the arm motor has a power level of 60, still it doesn't move at all! The reason for this is that the arm motor must lift the arm and the claw - it needs more power. If you try to raise the arm motor upwards with a power level of 30, it won't motion. Even with a power level of 60 it may not move. Always use a power level of 127 when raising the arm motor (peculiarly if it is holding an object in the claw).