PDA

View Full Version : Getting Familiar with Programming in WindRiver


kyungjin
12-26-2008, 01:38 AM
This is my second topic on the WindRiver IDE platform. Hopefully though, this topic will be able to be more broad on understanding the specifics of code.

Anyway... I've been trying to understand the sample code and trying to make sense of the Sample Code for a few days now (I've finally installed WindRiver) and I still can't get the gist of it. There's a number of issues surrounding this problem, most of it having to do with getting used to OOP but more importantly, learning what all the new function names, keywords and operators do (for example: what the heck is '->'?).

If someone can upload the sample code (if not I'll do it a bit later...) and kinda explain some of the things in the code (like what certain functions do and what certain keywords mean), I think it'll immensely help not only me, but other people trying to understand what's in the sample code.

Thanks,
- Daniel

kyungjin
12-26-2008, 01:39 PM
Here's the sample source code...

#include "WPILib.h"

/**
* This is a demo program showing the use of the RobotBase class.
* The SimpleRobot class is the base of a robot application that will automatically call your
* Autonomous and OperatorControl methods at the right time as controlled by the switches on
* the driver station or the field controls.
*/
class RobotDemo : public SimpleRobot
{
RobotDrive *myRobot; // robot drive system
Joystick *stick; // only joystick
DriverStation *ds; // driver station

public:
RobotDemo(void)
{
ds = DriverStation::GetInstance();
myRobot = new RobotDrive(1, 2); // create robot drive base
stick = new Joystick(1); // create the joysticks
GetWatchdog().SetExpiration(100);
}

/**
* Drive left & right motors for 2 seconds then stop
*/
void Autonomous(void)
{
GetWatchdog().SetEnabled(false);
myRobot->Drive(0.5, 0.0); // drive forwards half speed
Wait(2000); // for 2 seconds
myRobot->Drive(0.0, 0.0); // stop robot
}

/**
* Runs the motors with arcade steering.
*/
void OperatorControl(void)
{
GetWatchdog().SetEnabled(true);
while (IsOperatorControl())
{
GetWatchdog().Feed();
myRobot->ArcadeDrive(stick); // drive with arcade style (use right stick)
}
}
};

START_ROBOT_CLASS(RobotDemo);

koreabell
12-26-2008, 06:55 PM
I'm pretty sure you'll know most of it already, but just in case for someone else who is trying to get used to c/c++ itself, i'll explain from the very beginning

#include "WPILib.h"

/**
* This is a demo program showing the use of the RobotBase class.
* The SimpleRobot class is the base of a robot application that will automatically call your
* Autonomous and OperatorControl methods at the right time as controlled by the switches on
* the driver station or the field controls.
*/
class RobotDemo : public SimpleRobot
{
RobotDrive *myRobot; // robot drive system
Joystick *stick; // only joystick
DriverStation *ds; // driver station

public:
RobotDemo(void)
{
ds = DriverStation::GetInstance();
myRobot = new RobotDrive(1, 2); // create robot drive base
stick = new Joystick(1); // create the joysticks
GetWatchdog().SetExpiration(100);
}

/**
* Drive left & right motors for 2 seconds then stop
*/
void Autonomous(void)
{
GetWatchdog().SetEnabled(false);
myRobot->Drive(0.5, 0.0); // drive forwards half speed
Wait(2000); // for 2 seconds
myRobot->Drive(0.0, 0.0); // stop robot
}

/**
* Runs the motors with arcade steering.
*/
void OperatorControl(void)
{
GetWatchdog().SetEnabled(true);
while (IsOperatorControl())
{
GetWatchdog().Feed();
myRobot->ArcadeDrive(stick); // drive with arcade style (use right stick)
}
}
};

START_ROBOT_CLASS(RobotDemo);

#include "WPILib.h" <--- You're including header file called "WPILib.h" to your source to use various variables, functions, etc

class RobotDemo : public SimpleRobot <---You're declaring(and defining below) the class called "RobotDemo" which is derived from class called "SimpleRobot", and you'll access to public members of "SimpleRobot" class.
{ <--- you're now defining the class
RobotDrive *myRobot; <---you're declaring RobotDrive type pointer variable called "myRobot"
Joystick *stick; <--- you're declaring Joystick type pointer variable called "stick"
DriverStation *ds; <--- you're declaring DriverStation type pointer variable called "ds"

public: <---you're adding public members
RobotDemo(void) <---you're declaring and defining constructor
{ <--- you're now defining the constructor
ds = DriverStation::GetInstance(); <--- variable "ds" equals whatever value "GetInstance()" function under class called "DriverStation" returns
myRobot = new RobotDrive(1, 2); <--- you'll assign memory for pointer variable called "myRobot", and the size of that memory will be "RobotDrive(1,2)"
stick = new Joystick(1); <--- you'll assign memory for pointer variable called "stick", and the size of that memory will be "Joystick(1)"
GetWatchdog().SetExpiration(100); <--- you'll set the watchdog timer expiration to 100ms
} <--- you're done defining the constructor

void Autonomous(void) <--- you're declaring void type function called "Autonomous" taking no parameters
{ <--- you'll now define the function
GetWatchdog().SetEnabled(false); <--- you'll disable the watchdog timer
myRobot->Drive(0.5, 0.0); <--- execute "Drive(0.5,0.0)" using arrow operator(->) to access its(myRobot pointer's) member function
Wait(2000); <--- execute function called "Wait", taking one parameter, which value you put is 2000
myRobot->Drive(0.0, 0.0); <---- execute "Drive(0.0,0.0)" using arrow operator(->) to access its(myRobot pointer's) member function
} <--- you're done defining function


void OperatorControl(void) <--- you're declaring void type function called "OperatorControl" taking no parameters
{ <--- you're defining the function
GetWatchdog().SetEnabled(true); <--- you're setting watchdog timer
while (IsOperatorControl()) <---repeat while loop until "IsOperatorControl()" equals 0
{ <--- define while loop
GetWatchdog().Feed(); <--- feed the watchdog timer
myRobot->ArcadeDrive(stick); <---execute "ArcadeDrive" function(and parameter it takes is stick variable) using arrow operator(->) to access its(myRobot pointer's) member function
} <--- you're done defining while loop
} <--- you're done defining function

}; <--- you're done defining class

START_ROBOT_CLASS(RobotDemo); <--- you're calling function called "START_ROBOT_CLASS" with parameter "RobotDemo"

GGCO
12-26-2008, 10:37 PM
I was wondering if windriver has something similar to MS's intellisense. I love using it in VS and was hoping to use it with WR

jtdowney
12-27-2008, 06:21 AM
I was wondering if windriver has something similar to MS's intellisense. I love using it in VS and was hoping to use it with WR

Eclipse, the platform Workbench is built on, has intellisense for C/C++ development. It isn't nearly as good as Visual Studio in my opinion but still there.

McGurky
12-27-2008, 08:55 AM
this is a little off topic, but where/ what version of wind river should i download?

jtdowney
12-27-2008, 11:47 AM
this is a little off topic, but where/ what version of wind river should i download?

A version of WindRiver is included with the control system and it is tailored to FIRST and WPILib.

kyungjin
12-28-2008, 12:37 PM
To koreabell:
Thanks for taking the time to actually go down the code step by step. I've been a bit busy over the holidays and I've only gotten to read what you wrote now.

To everyone:
One thing I noticed so far in the code, is the use of an "Arcade Joystick". Is that referring to "tank-drive" type steering or to single joystick control of the robot? Also, is it possible to use a different type of steering mechanism, for example a steering wheel, to control the robot? If so, what other resources would I need and how will I be able to implement it in the source code?

Thanks for your time. I look forward to reading your replies.

- Dan

koreabell
12-28-2008, 07:50 PM
One thing I noticed so far in the code, is the use of an "Arcade Joystick". Is that referring to "tank-drive" type steering or to single joystick control of the robot? Also, is it possible to use a different type of steering mechanism, for example a steering wheel, to control the robot? If so, what other resources would I need and how will I be able to implement it in the source code?

If you read the WPI Robotics Library doxygen document (C Programming Reference),

under class "RobotDrive", there's definition for every function related to driving mechanism

Here's description for "ArcadeDrive" function

Arcade drive implements single stick driving. Given a single Joystick, the class assumes the Y axis for the move value and the X axis for the rotate value. (Should add more information here regarding the way that arcade drive works.)

if you want to make your robot to be controlled with tank drive system, there's a function called "TankDrive"

Description for "TankDrive" function

Provide tank steering using the stored robot configuration. Drive the robot using two joystick inputs. The Y-axis will be selected from each Joystick object.

there are more functions having same name -TankDrive- but taking different parameters so you should check it before you use it.


in the code you should call function by doing something like this

RobotDrive::TankDrive(Left,Right); //basic tank drive function under RobotDrive Class


or if you have RobotDrive type variable, you can do this also

variable->TankDrive(Left,Right);



and you can use steering wheel for controlling robot but, programming will be same since throttle stick or pedal will have/return y-axis value and the steering wheel will have/return x-axis value

kyungjin
12-28-2008, 10:02 PM
Hey thanks again for the help. I really appreciate it.

I'm looking through the WPI C Programming Reference and things are slowly getting processed so that's a good thing.

I think I have an idea on how I'll implement control by steering wheel. But I have a more technical question ask you. I've noticed that the new Driver Station Unit has 4 USB ports available for use. It's it okay to plug in any USB Human Interface Device into the DSU and program or do I have to configure it? Also, is there a way to directly obtain values from the joysticks for programming use?

Thanks again for everything.

koreabell
12-28-2008, 10:59 PM
When you're initializing joystick, you have to put which port the joystick is plugged in to as parameter

on the sample code you'll see this

stick = new Joystick(1); // create the joysticks


that "Joystick(1)" (which is constructor) means that it'll have control over Joystick that is plugged into port 1 on Driver Station

if for some reason it doesn't work, then it can be joystick driver software problem, which can be solved by copying driver file to USB Memory Stick(Mass Storage Device) and then plugging into driverstation.
I do not know the procedure of installing driver software since we didn't get new controller yet, but I heard that it can be done on both on-line and off-line workshops

also as I searched through some beta testing teams' codes, I found out that they were using Header & Source file for the joystick so I think it can be done via programming manually instead of installing device drivers. (I didn't analyze that files so i might be wrong but it looked like those files are in charge of joysticks teams are using)

and to obtain values from joystick, if you read Joystick class under C programming reference, there are a lot of functions like GetX, GetY, GetZ, etc

you can use that to get values of joystick axis, buttons, and stuff like that

kyungjin
12-29-2008, 02:00 AM
All this is very helpful information.

So, is this saying that there is a possibility of say, I plug in a random USB steering wheel into USB port 1 on the DSU, upload the driver files from a USB thumb drive (found off of the manufacturer's website) and then program using the various functions and classes using the WindRiver IDE?

Hopefully someone releases some precompiled header files so that we have steering control instead of joysticks.

koreabell
12-29-2008, 05:05 AM
So, is this saying that there is a possibility of say, I plug in a random USB steering wheel into USB port 1 on the DSU, upload the driver files from a USB thumb drive (found off of the manufacturer's website) and then program using the various functions and classes using the WindRiver IDE?

Yes, although you might not need to install device driver since steering wheel "joysticks" basically have same interface as that of normal joysticks(meaning that driverstation won't actually notice the difference between normal joysticks and steering wheel joysticks)

last year we tried to make steering wheel to drive our robot, and i remember it returning x-axis value of 127 on idle position, 0 when turning wheel all the way to left, 255 when turning wheel all the way to right or vice versa (can't remember exactly)

now, if you plug in mouse or something like that other than joystick-type HID, it'll be a different story and I'm not even sure whether it'll work or not, but as long as you plug in joystick-type HID, then you'll do fine programming

JDM
12-29-2008, 06:30 AM
All this is very helpful information.

So, is this saying that there is a possibility of say, I plug in a random USB steering wheel into USB port 1 on the DSU, upload the driver files from a USB thumb drive (found off of the manufacturer's website) and then program using the various functions and classes using the WindRiver IDE?

Hopefully someone releases some precompiled header files so that we have steering control instead of joysticks.

That's not exactly true. Right now, the only joysticks/steering wheels/etc. that the DS supports are standard HID joystick devices that don't require drivers. There's no (published, anyway) way to get any special drivers onto the DS. (see section 3.1.8 of the control system manual or look around the beta forums)

Also, keep in mind that the Driver's Station is Linux based so if there were a way to use drivers, then they'd have to be for that platform.

koreabell
12-29-2008, 08:10 AM
That's not exactly true. Right now, the only joysticks/steering wheels/etc. that the DS supports are standard HID joystick devices that don't require drivers. There's no (published, anyway) way to get any special drivers onto the DS. (see section 3.1.8 of the control system manual or look around the beta forums)

Also, keep in mind that the Driver's Station is Linux based so if there were a way to use drivers, then they'd have to be for that platform.

maybe i got confused with upgrading firmware. sorry about that

kyungjin
12-29-2008, 01:15 PM
Thanks both for the replies.

So in order to pull information from the HID joysticks, it has to be pure P&P that doesn't require any drivers whatsoever? So, if we find such as device, everything else should be preconfigured? For example, for a steering wheel, the wheel provides x-values, and the pedals provide the y-values? Or is there anyway to preset specific functions to specific buttons or features of the joystick?

koreabell
12-29-2008, 02:28 PM
most of joysticks come with drivers when you buy, but that doesn't mean you necessarily need that driver.

if you plug the joystick into the driver station, it'll most likely recognize the device without driver(unless the joystick really need driver).

you'll need WPILib to get information of joystick status, which can be interpreted as it is preconfigured.

you can assign specific functions to corresponding buttons by making if or switch case statements.

for example


int button[13]; // find which button is pushed
int a = 0; //how many buttons are pushed?

for(int i = 0; i < 12; i++){ //Get what button(s) is/are pushed and save it in array variable
if(Joystick::GetRawButton((i+1)) == TRUE){
button[a] = i;
a++;
}
}

for(int i = 0; i < a; i++){
switch(button[i+1]){
case 0: //if nothing is pushed
break;
case 1: //if button1 is pushed
DoThis();
break;
case 2: //if button2 is pushed
DoThat();
break;
case 3: //if button3 is pushed
DoThese();
break;
case 4: //if button4 is pushed
DoThose();
break;
case 5: //if button5 is pushed
DoIt();
break;
case 6: //if button6 is pushed
GoThere();
break;
case 7: //if button7 is pushed
ComeHere();
break;
case 8: //if button 8 is pushed
Shoot();
break;
case 9: //if button 9 is pushed
RunAway();
break;
case 10: //if button 10 is pushed
Stop();
break;
case 11: //if button 11 is pushed
DisableYourself();
break;
case 12: //if button 12 is pushed
AbortAndCatchOnFire();
break;
}
}
a = 0;
for(int i = 0; i < 12; i++){ //reset
button[i] = 0;
}


i think you can have up to 12 buttons and i doubt you'll assign all 12 buttons to its corresponding functions but that's one way to do it.

the other way is having a lot(depends on how many buttons you'll be assigning specific functions to) of if and else if statements

there might be other ways but I can't think of it at the moment

kyungjin
12-31-2008, 01:29 PM
I see... Since there are 12 programmable buttons, I'm guessing that either the standard joystick is labeled or there's a diagram showing what button corresponds to what... But what if we use a different joystick? Do we have to test which buttons match which input source?

koreabell
12-31-2008, 01:51 PM
most of the joysticks have number on each button, maybe except for trigger button and, if you're using logitech joystick and cannot figure out which button is which, install logitech gaming software that came with the joystick(to computer), execute it with joystick plugged in to one of the computer's usb ports, and start pressing buttons. the program will tell you what button you're pressing.

i don't know if other companies support those kind of software or not, but if you have logitech joystick, you can figure out that way

if you're making your own usb joystick, then you'll have to label it as you make it, but if you're buying joystick, then i wouldn't worry too much about not knowing which button is which

btw, if you want to test without robot or drivestation, run joystick-playable game and go to key configuration(or something like that), and try changing joystick key. it'll show you which button you pushed after you assign a key (for most games)

kyungjin
01-06-2009, 08:33 AM
Thanks for the reply. You've been really helpful ever since I posted this thread.

After much thinking (upon watching the game), I think we've made the decision to go with the USB joysticks that we're given standard to our team (Logitech ATK3).

Right now though... I have another problem that has been giving me major problems. Aside from not being able to get our camera correctly connected and configured when it's plugged into the cRIO... I'm not quite sure how I'm supposed to program it to track colors or shapes in WindRiver. Do I do so with pure code or is there another utility that helps monitor that? And of course... How am I supposed to implement that into the code.

Secondly... Right now, the only way I've gotten the motors to move is through the RobotBase class. Is there any other way to control a specific motor (whether it be Jaguars or Victors) a specific speed? The functions in WPIlib.h only tells you what speed you want to set it to... but there are no parameters that reference the PWM port the motor is plugged into...

wireties
01-06-2009, 03:40 PM
The PWM port is specified as a parameter to the constructor.

I think I read where the WPI guys are putting out an update to the camera classes (in the next few days) that works. How to use the data from the camera to guide your robot or dummper (or whatever) is up to you.

kyungjin
01-07-2009, 10:25 AM
Mmkay... I think I kinda get what you're saying... But just to clarify... How would you get a motor on PWM1 to go half speed for 2 seconds and PWM2 to go full speed for 3 seconds?

As for the camera classes... Do we check back on the FIRST website or the WPI site?

erikstotle
01-07-2009, 10:41 AM
Btw, in c++, you use -> to access elements of a class by pointer, and . to reference elements by refrence. I remember that concept always confusing me when I started out with OOP...luckily Visual Studio's Intellisense complains at you when you use the wrong one, so I learned quick enough :).

kyungjin
01-07-2009, 02:41 PM
Thanks for clarifying that up for me.

dnrobotics11
01-07-2009, 04:22 PM
How do you open a new C++ file with WindRiver? I've already downloaded the FIRST version and it is working but I do not know how to actually make a new program. Thanks for the help.

gvarndell
01-07-2009, 06:34 PM
How do you open a new C++ file with WindRiver? I've already downloaded the FIRST version and it is working but I do not know how to actually make a new program. Thanks for the help.

Do you mean to ask how to create a new source file in an existing project?
Or did you mean to ask how to create a new project?

dnrobotics11
01-07-2009, 07:08 PM
I have already set up WindRiver and the "MyRobot" template is set up but I don't know how to set up new source code files for my own robot code. I can't find it in the directions and I don't know what to do. Thanks

kyungjin
01-07-2009, 07:19 PM
Err... To do this go to File -> New...

And then select the project that you want. From there on the bottom there's a textbox where you type your file name WITH the extension. For example... If you want a C++ source file named test... then type in test.cpp. If you want a header file... for example, testlib... then type in testlib.h.

It should automatically create a file in the project that you selected.

dnrobotics11
01-07-2009, 07:22 PM
Oh ok thanks

gvarndell
01-07-2009, 07:32 PM
I have already set up WindRiver and the "MyRobot" template is set up but I don't know how to set up new source code files for my own robot code. I can't find it in the directions and I don't know what to do. Thanks

Right-click on the project to which you want to add the new file.
Select New->File from Template.
The New File dialog will appear.
Type in the new file's name.
Click the Change... button.
A Preferences dialog will appear -- here you'll select 'cpp_template'.
Click OK in the Preferences dialog.
Click Finish in the New File dialog.

kyungjin
01-08-2009, 02:34 PM
I've been kinda confused on how to get some of the basic stuff done...

A lot of the functions that are in the WPILib seem inadequate because they don't have enough parameters to get a specific amount of data or control for a specific component, etc.

I'm sure the constructors have something to do with the member functions of its class but so far, I haven't been able to make any sense or relation between the two functions. The only logical idea that I have so far goes something like this...

If, for example, we have two Jaguar motors plugged into PWM 1 and 2 and we want the first motor to go half speed for two seconds and the the second motor to go full speed for three seconds...

Jaguar::Jaguar(1);
Jaguar::Set(0.5);
Wait(2000);

Jaguar::Jaguar(2);
Jaguar::Set(1.0);
Wait(3000);

I'm pretty sure the above is wrong... Can anyone correct this?

dnrobotics11
01-08-2009, 03:06 PM
--------------------------------------------------------------------------------

I have set up the WindRiver programming compiler but first of all, I don't know how to set up a FIRST code template with the three phases of competition as subroutines. Also, I am extremely lost in regards to the configuration of the cRIO system with WindRiver. I set up the IP addresses but there is never a connection between the cRIO and the computer. I do not know what I'm doing. Can anyone help? Thank you

Jlulian
01-08-2009, 09:19 PM
I've been kinda confused on how to get some of the basic stuff done...

A lot of the functions that are in the WPILib seem inadequate because they don't have enough parameters to get a specific amount of data or control for a specific component, etc.

I'm sure the constructors have something to do with the member functions of its class but so far, I haven't been able to make any sense or relation between the two functions. The only logical idea that I have so far goes something like this...

If, for example, we have two Jaguar motors plugged into PWM 1 and 2 and we want the first motor to go half speed for two seconds and the the second motor to go full speed for three seconds...

Jaguar::Jaguar(1);
Jaguar::Set(0.5);
Wait(2000);

Jaguar::Jaguar(2);
Jaguar::Set(1.0);
Wait(3000);

I'm pretty sure the above is wrong... Can anyone correct this?

This should work:


Jaguar* jaguar1 = new Jaguar(1);
Jaguar* jaguar2 = new Jaguar(2);

jaguar1->Set(0.5);
Wait(2000);
jaguar2->Set(1.0);


incidentally, the following does compile (and _does_ work)


SpeedController* Motor1 = new Jaguar(1);
SpeedController* Motor2 = new Victor(1); //Implicit casts


Though I wouldn't recommend using two entirely different speed controllers for your drive train

kyungjin
01-10-2009, 04:53 AM
Thanks for the reply! It was just what I was looking for.

Just one question though... What is the difference between the first set of code and the second set of code?

kyungjin
01-12-2009, 08:58 PM
Hey Jlulian, I tried what you posted and for the most part everything seems to work fine... except when we try to put it into reverse...

Jaguar* jaguar1 = new Jaguar(1);
Jaguar* jaguar2 = new Jaguar(2);

jaguar1->Set(0.5);
Wait(2000);
jaguar2->Set(1.0);

I tried playing around with the code a bit and found that whenever I set the number to a negative value for example: jaguar1->Set(-1.0);... the code wouldn't run...

I haven't tried played around with it too much but I was wondering if you knew anything about this...

kyungjin
01-17-2009, 12:04 PM
I've tried playing with it some more.... It seems that the jaguar command doesn't like negative numbers... Is there a reason for this?