Log in

View Full Version : Tweaks to be able to build C++ code from Robot Builder


Bryscus
09-01-2013, 13:42
Guys,

I've gone through the Robot Builder videos on youtube and was coding along with them, but in C++. I noticed a couple of things that might trip some coders up so I thought I'd post my findings. The generated codes always seems to build fine, but when adding methods and coding command sets there are some things to be wary of:

1. Case is slightly different for C++ methods than in Java. C++ seems to be camel case starting with a capital letter and Java seems to be camel case starting with a lower case letter.

SetTimeout(1);
IsTimedOut();

2. Accessing methods/members from classes is different. In this C++ code, everything is a pointer, so access is made with "->" rather than a ".". Also, when accessing a subsystem from the robot, "Robot::" is required before the system name.

Java: Robot.claw.close();
C++: Robot::claw->close();

3. If/when creating methods for a class (normally a subsystem class), the function prototype must be added to the header (.h) file of the same name. Also the class name follow by "::" must proceed the method name.


//In Claw.h
class Claw: public Subsystem {
private:
// It's desirable that everything possible under private except
// for methods that implement subsystem capabilities
public:
// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
SpeedController* motor;
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=DECLARATIONS
Claw();
void InitDefaultCommand();
void open();
void close();
void stop();
};


//In Claw.cpp
void Claw::open(){
motor->Set(1);
}


4. When using commands in another class (such as a command set) the headers for those commands need to be included.


//In DeliverCylinder.cpp
#include "DeliverCylinder.h"

#include "PreparetoPickup.h"
#include "Pickup.h"
#include "Place.h"
#include "RaiseWrist.h"
#include "CloseClaw.h"
#include "DriveToPlatform.h"
#include "Backup.h"

DeliverCylinder::DeliverCylinder() {

AddSequential(new PreparetoPickup());
AddSequential(new Pickup());
AddSequential(new DriveToPlatform());
AddSequential(new Place());
AddParallel(new Backup());
AddSequential(new RaiseWrist());
AddSequential(new CloseClaw());
}

5. Some else noteworthy: Keep in mind that there are auto-generated code areas. Brad talks about these in the videos. If you write code in these areas and then in the future regenerate code from Robot Builder you will loose code between these comments.

// BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=REQUIRES
Requires(Robot::claw);
// END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=REQUIRES

6. When regenerating code, Robot Builder will often create a backup of the file it replaced. It will end in a "~".


I've attached the C++ version of the project code just in case the examples above are incomplete. The code builds (I can't test whether is executes since I don't have his platform) and appears to be correct but peruse it at your own risk. The only thing missing is one of the last steps which is casting "autonomousModes->GetSelected();" to a "Command" type. This doesn't work in C++ and I don't yet have a solution.

Good luck.

- Bryce

EDIT: The project is now building fine thanks to Brad's example below (above depending on how you have your posts situated). I've updated the zip.

BradAMiller
09-01-2013, 15:16
Guys,
The only thing missing is one of the last steps which is casting "autonomousModes->GetSelected();" to a "Command" type. This doesn't work in C++ and I don't yet have a solution.
- Bryce

Nice resource you've provided!

I just posted an example of creating the SendableChooser for selecting autonomous programs in C++ at the bottom of this page:

http://wpilib.screenstepslive.com/s/3120/m/7932/l/81109-choosing-an-autonomous-program-from-smartdashboard

Brad

nightpool
24-01-2013, 21:28
Tiny side note, camelCase with a uppercase initial letter can be referred to less ambiguously as PascalCase.

jmullins16
28-01-2013, 02:04
For lack of a better place for adding RobotBuilder tweaks, I'm going to pile onto this thread. I'd love to see a dedicated forum for this since it spans Java and C++.

First, RobotBuilder is a fantastic tool, and I hope that teams--especially rookie teams--recognize the value of the software foundation that RobotBuilder can provide. Here are some C++ quirks we found (starting with version r619) that might be avoided by others:

1) Make subsystem names start with capital letters and preferably single words. We initially used lower case names (like chassis) and the default C++ code seemed to use lower case for type names which conflicted with the auto-generated instances of these types.

2) Don't bother to create a battery subsystem for analog input 8--it's already built in somewhere. An error message at runtime will tell you that you are reallocating an existing analog input.

3) When creating a PID subsystem, we got a malformed function name. It can be hand edited as a workaround (each time an export is done).

generated:
return entryShooterEncoder->PidGet();

should be:
return entryShooterEncoder->PIDGet();

4) When adding an initial default command, they must have the "requires" field set to point at the proper subsystem.

5) We were able to working generate C++ from the base .yml config file successfully, but when moving the config file to a new computer it would not generate the exact same set of code. The #include line in subsystems that have an initial default command would not be inserted. Probably due to the fact that that the #include line is outside of the auto-generation markers. In order to work around this, the #includes need to be entered manually (or just copy the exported source code instead of the .yml file).

I will try to enter these on the first forge project for RobotBuilder. Note that the current version is now r623.

Jeff