View Full Version : Pointers and Tank Drive?
Straberrie
17-12-2008, 22:05
Hi! I am trying to program a Tank drive and am using the programming guide for C++ as well as the Simple Template found in File - New - Example etc... in the Workbench.
In the programming guide, the Operator control code looks like this
void OperatorContol (void)
{
while (1)
{
drivetrain.Tank (&stick1, &stick2);
}
}
and well, the header included in the program is "WPILib.h"; I have the same header included and I have the variables defined exactly the way they are defined in the guide, but when I try to build the project, it states the following
:C:/WindRiver/workspace/SimpleTemplate/MyRobot.cpp:31: error: `stick1' undeclared (first use this function):
How do pointers work?? In the guide, the joystick and pointer explanation is omitted *at least in the one I have, sorry if i skipped something*. So, is there anything I can read about pointers?? Or programming tank drive? Because I can't figure out whats wrong! *and yes, I am sorta kinda new to this, so if I made a silly error or am asking something stupid, sorry*
Thank you!!!!!!!!! :ahh: :yikes: :rolleyes: ;) :P
well, in my experience with the C++ for the cRIO with WPILib.h,
in the definition for your robot class, you need to have something like this:
Joystick* leftStick;
Joystick* rightStick; //the *'s mean they're a pointer.
RobotDrive* myRobot;
Then in the constructor, you need to have something like:
leftStick = new Joystick(1); //joystick in DS port 1
rightStick = new Joystick(2); //DS port 2
myRobot = new RobotDrive(1,2,3,4); //4 motor drive, with the motors connected to PWM1,2,3,4, on sidecar 1.
and then in the operator control bit, you need something like:
myRobot->TankDrive(leftStick, rightStick);
Dave Scheck
18-12-2008, 14:50
C:/WindRiver/workspace/SimpleTemplate/MyRobot.cpp:31: error: `stick1' undeclared (first use this function)This means that within MyRobot.cpp, the compiler doesn't know what stick is.
If you copy/pasted the example code that is on page 14, it will not work and you will get this exact error. The reason is that stick1 is never declared (hence the error). Look at the 3rd line of code in the sample codeJoystick stick(1);It looks like there was a mistake and they forgot to add the declaration for the correct sticks (maybe it started as arcade drive?). Based on the usage, try replacing that line with declarations for stick1 (and stick2 which should also be throwing an error) and this error should go away.Joystick stick1(1);
Joystick stick2(2);
Your issue isn't with pointers, but rather with undeclared variables. If you wanted to use pointers, you can use 1075guy's suggestion as a reference point.
BradAMiller
18-12-2008, 18:12
In that example (it might be a little confusing), it takes the sample program built into Workbench and looks at it a few lines at a time. So in each of those little snippets of code, you aren't seeing the whole program. If you look up a few code samples, you can see the declarations.
Straberrie
18-12-2008, 18:13
Thank you so much!!!!! :ahh: :ahh:
this explains it! :p
Dave Scheck
18-12-2008, 18:21
Brad - I understand the declarations are above (page 12), but the code on page 14 seems to be the combination of the snippets above. It would make sense that that would be the case. However, as I stated, the code on page 14 wouldn't compile because of the undeclared stick1 and stick2. If the original user copy/pasted the example verbatim, I believe that my explanation would explain the issue.
In case there are different doc versions, I'm referring to doc version .2 from Oct 15.
Straberrie
18-12-2008, 18:42
#include "WPILib.h"
class RobotDemo : public SimpleRobot
{
RobotDrive *Bot; // robot drive system
Joystick *stickRight;
Joystick *stickLeft;
DriverStation *ds; // driver station
public:
RobotDemo(void)
{
ds = DriverStation::GetInstance();
Bot = new RobotDrive(1, 2); // create robot drive base
stickRight = new Joystick(1);
stickLeft = new Joystick(2);
GetWatchdog().SetExpiration(100);
}
and the Operator:
void OperatorControl(void)
{
while (1)
{
Bot.TankDrive(&stickLeft, &stickRight);
}
}
};
START_ROBOT_CLASS(RobotDemo);
I edited it, but...
C:/WindRiver/workspace/ll/MyRobot.cpp:38: error: request for member `TankDrive' in `((RobotDemo*)this)->RobotDemo::Bot', which is of non-class type `RobotDrive*'
Thats what it says... If its not too much to ask, whats wrong?? :confused: :confused:
Dave Scheck
18-12-2008, 18:46
Now that Bot is a pointer, you need to use the arrow operator to access the TankDrive method. You also need to remove the & from stickLeft and stickRight that was turning them into pointers. TankDrive expects two pointer inputs and since stickLeft and stickRight are already pointers, you can pass them in directly. Try this out:
Bot->TankDrive(stickLeft, stickRight);
Straberrie
18-12-2008, 18:51
void OperatorControl(void)
{
while (1)
{
Bot->TankDrive(&stickLeft, &stickRight);
}
}
};
I tried that and here are the errors that r showing up! The only line highlighted as having an error is "Bot->TankDrive(&stickLeft, &stickRight);"
C:/WindRiver/workspace/ll/MyRobot.cpp: In member function `virtual void RobotDemo::OperatorControl()':
C:/WindRiver/workspace/ll/MyRobot.cpp:38: error: no matching function for call to `RobotDrive::TankDrive(Joystick**, Joystick**)'
C:/WindRiver/vxworks-6.3/target/h/WPILib/RobotDrive.h:43: note: candidates are: void RobotDrive::TankDrive(GenericHID*, GenericHID*)
C:/WindRiver/vxworks-6.3/target/h/WPILib/RobotDrive.h:44: note: void RobotDrive::TankDrive(GenericHID*, unsigned int, GenericHID*, unsigned int)
C:/WindRiver/vxworks-6.3/target/h/WPILib/RobotDrive.h:45: note: void RobotDrive::TankDrive(float, float)
C:\WindRiver\vxworks-6.3\host\x86-win32\bin\make.exe: *** [SimpleTemplate_partialImage/Debug/Objects/ll/MyRobot.o] Error 1
Build Failed in Project 'll' (Process Exit Value was 2): 2008-12-18 18:47:20 (Elapsed Time: 00:02)
BradAMiller
18-12-2008, 18:52
Brad - I understand the declarations are above (page 12), but the code on page 14 seems to be the combination of the snippets above. It would make sense that that would be the case. However, as I stated, the code on page 14 wouldn't compile because of the undeclared stick1 and stick2. If the original user copy/pasted the example verbatim, I believe that my explanation would explain the issue.
In case there are different doc versions, I'm referring to doc version .2 from Oct 15.
Dave -
Sorry about that, I missed that part of the example and just fixed it (in the next update). Thanks for pointing it out.
Brad
Straberrie
18-12-2008, 18:53
Nevermind! I just tried exactly what you said without "&" and ur worked!!! YAY!
http://i389.photobucket.com/albums/oo339/marlinman/537735a9.gif
BradAMiller
18-12-2008, 19:13
void OperatorControl(void)
{
while (1)
{
Bot->TankDrive(&stickLeft, &stickRight);
}
}
};
I tried that and here are the errors that r showing up! The only line highlighted as having an error is "Bot->TankDrive(&stickLeft, &stickRight);"
This is confusing.
There are two ways of declaring objects: either as an instance of the object or a pointer to the object. In the case of the instance the variable represents the object, and it is created at the time of the declaration. In the case of a pointer you are only creating the space to store the address of the object, but the object remains uncreated. With pointers you have to create the object using the new operator. Look at these two snippets of code to see the difference.
Joystick stick1(1); // this is an instance of a Joystick object called stick1
stick1.GetX(); // instances are dereferenced using the dot (.) operator
bot->ArcadeDrive(stick1); // and can be passed to methods as a reference
Joystick * stick2; // this is a pointer to an uncreated Joystick object
stick2 = new Joystick(1); // this creates the instance of the Joystick object
stick2->GetX(); // pointers are dereferenced with the arrow (->)
bot->ArcadeDrive(stick2); // and can be passed as pointers (notice, no &)
A friend just suggested that this example itself might be a little confusing, and this is going to get kind of geeky. The ArcadeDrive method in the library is taking advantage of a feature of C++ called function overloading. This allows us to have two methods with the same name that differ by the argument list. In the first ArcadeDrive(stick1), the variable stick1 is passed as a reference to a Joystick object. In the second ArcadeDrive(stick2), it is being passed as a pointer to a Joystick object. There are actually two methods in the RobotDrive object, both called ArcadeDrive that each take a different type of argument. The cool thing is that the compiler figures out which one to call. The library is built this way to let it adopt with the style of programmers that prefer to use pointers while at the same time accommodating those who prefer to use references.
Does this help?
Straberrie
18-12-2008, 19:24
:] :] Now i understand the way pointers and instances, etc work!!! Thank you so much!!!
and yep! Helps loads! :ahh:
vBulletin® v3.6.4, Copyright ©2000-2017, Jelsoft Enterprises Ltd.