Skip to content

Commit

Permalink
New command framework for C++ (#248)
Browse files Browse the repository at this point in the history
Update to export New Command Framework. Fixes #191
Use uniform initialization in header. Fixes #80

Co-authored-by: Joe <sciencewhiz@users.noreply.github.com>
  • Loading branch information
cbennet and sciencewhiz committed Oct 25, 2020
1 parent fbafff6 commit 7ba84ea
Show file tree
Hide file tree
Showing 78 changed files with 732 additions and 627 deletions.
4 changes: 2 additions & 2 deletions src/main/java/robotbuilder/actions/ExporterAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ public ExporterAction(String description) {
@Override
public void actionPerformed(ActionEvent ae) {
boolean newProject = false;
MainFrame.getInstance().setCursor(Cursor.WAIT_CURSOR);
MainFrame.getInstance().setCursor(new Cursor(Cursor.WAIT_CURSOR));
try {
newProject = exporter.export(MainFrame.getInstance().getCurrentRobotTree());
} catch (IOException ex) {
Logger.getLogger(ExporterAction.class.getName()).log(Level.SEVERE, null, ex);
}
MainFrame.getInstance().setCursor(Cursor.DEFAULT_CURSOR);
MainFrame.getInstance().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
if (newProject)
JOptionPane.showMessageDialog(MainFrame.getInstance(),
"Project successfully exported for the first time. Open project directory in"
Expand Down
6 changes: 4 additions & 2 deletions src/main/resources/export/cpp/Command-constructor-header.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
#set($len = $params.size() - 2)
#set($last = $len + 1)
#if( $params.size() > 0 )
#class($command.name)(#if( $len >= 0 )#foreach($i in [0..$len])#param_declaration_cpp($params.get($i)), #end#end#param_declaration_cpp($params.get($last)));
explicit #class($command.name)(#if( $len >= 0 )#foreach($i in [0..$len])#param_declaration_cpp($params.get($i)), #end#end#param_declaration_cpp($params.get($last))#if (${command.getProperty("Requires").getValue()} != "None"), #class(${command.getProperty("Requires").getValue()})* #variable(${command.getProperty("Requires").getValue().toLowerCase()})#end);
#elseif (${command.getProperty("Requires").getValue()} == "None")
explicit #class($command.name)();
#else
#class($command.name)();
explicit #class($command.name)(#class(${command.getProperty("Requires").getValue()})* #variable(${command.getProperty("Requires").getValue().toLowerCase()}));
#end
13 changes: 13 additions & 0 deletions src/main/resources/export/cpp/Command-constructor-variables.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,16 @@
## generates Foo m_foo;
#end
#end

#set($command = $helper.getByName($command_name, $robot))
#set($first = 1)
#if ($command.getProperty("Requires").getValue() != "None")
#if($first)
#class(${command.getProperty("Requires").getValue()})* m_#variable(${command.getProperty("Requires").getValue().toLowerCase()});
#set($first = 0)
#else
## AddRequirements(Robot::#variable(${command.getProperty("Requires").getValue()}));
,#class(${command.getProperty("Requires").getValue()})* m_#variable(${command.getProperty("Requires").getValue().toLowerCase()});
#end
#end

32 changes: 18 additions & 14 deletions src/main/resources/export/cpp/Command-constructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,26 @@
#set($params = $command.getProperty("Parameters").getValue())
#set($len = $params.size() - 2)
#set($last = $len + 1)
#macro( klass $cmd )#if( "#type($cmd)" == "" )Command#else#type($cmd)#end#end

\#include "commands/#class($command.name).h"

#if( $params.size() > 0 )
#class($command.name)::#class($command.name)(#if( $len >= 0 )#foreach($i in [0..$len])#param_declaration_cpp($params.get($i)), #end#end#if( $last >= 0 )#param_declaration_cpp($params.get($last))#end): #klass($command)() {
#class($command.name)::#class($command.name)(#if( $len >= 0 )#foreach($i in [0..$len])#param_declaration_cpp($params.get($i)), #end#end#if( $last >= 0 )#param_declaration_cpp($params.get($last))#end#if(${command.getProperty("Requires").getValue()} != "None") ,#class(${command.getProperty("Requires").getValue()})* #variable(${command.getProperty("Requires").getValue().toLowerCase()})#end) :
#foreach($param in $params)
m_$param.getName()($param.getName())
#end
#if(${command.getProperty("Requires").getValue()} != "None"), m_#variable(${command.getProperty("Requires").getValue().toLowerCase()})(#variable(${command.getProperty("Requires").getValue().toLowerCase()}))#end
{
#elseif(${command.getProperty("Requires").getValue()} == "None")
#class($command.name)::#class($command.name)(){
#else
#class($command.name)::#class($command.name)(): #klass($command)() {
#class($command.name)::#class($command.name)(#class(${command.getProperty("Requires").getValue()})* #variable(${command.getProperty("Requires").getValue().toLowerCase()}))
:m_#variable(${command.getProperty("Requires").getValue().toLowerCase()})(#variable(${command.getProperty("Requires").getValue().toLowerCase()})){
#end
#foreach($param in $params)
m_$param.getName() = $param.getName();

// Use AddRequirements() here to declare subsystem dependencies
// eg. AddRequirements(Robot::chassis.get());
SetName("#class($command.name)");
#if (${command.getProperty("Requires").getValue()} != "None")
AddRequirements(m_#variable(${command.getProperty("Requires").getValue().toLowerCase()}));
#end
// Use Requires() here to declare subsystem dependencies
// eg. Requires(Robot::chassis.get());
#@autogenerated_code("requires", " ")
#parse("${exporter_path}Command-requires.cpp")
#end
#if ( $command.getProperty("Run When Disabled").getValue() )
SetRunWhenDisabled(true);
#end
}
6 changes: 6 additions & 0 deletions src/main/resources/export/cpp/Command-disabled.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#set($command = $helper.getByName($command_name, $robot))
#if ( $command.getProperty("Run When Disabled").getValue() )
return true;
#else
return false;
#end
4 changes: 0 additions & 4 deletions src/main/resources/export/cpp/Command-requires.cpp

This file was deleted.

14 changes: 7 additions & 7 deletions src/main/resources/export/cpp/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
#set($params = $command.getProperty("Parameters").getValue())
#header()

\#include "Commands/#class($command.name).h"

#@autogenerated_code("constructor", "")
#parse("${exporter_path}Command-constructor.cpp")
#end

}

// Called just before this Command runs the first time
void #class($command.name)::Initialize() {

Expand All @@ -24,12 +24,12 @@ bool #class($command.name)::IsFinished() {
}

// Called once after isFinished returns true
void #class($command.name)::End() {
void #class($command.name)::End(bool interrupted) {

}

// Called when another command which requires one or more of the same
// subsystems is scheduled to run
void #class($command.name)::Interrupted() {

bool #class($command.name)::RunsWhenDisabled() const {
#@autogenerated_code("disabled", " ")
#parse("${exporter_path}Command-disabled.cpp")
#end
}
23 changes: 12 additions & 11 deletions src/main/resources/export/cpp/Command.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
#set($command = $helper.getByName($command_name, $robot))
#macro( klass $cmd )#if( "#type($cmd)" == "" )frc::Command#else frc::#type($cmd)#end#end
#macro( klass $cmd ) frc2::CommandHelper<#type($cmd), $cmd.name>#end
#header()

#pragma once

\#include "frc/commands/Command.h"
\#include "frc/commands/Subsystem.h"
\#include "Robot.h"
#@autogenerated_code("includes", " ")
#parse("${exporter_path}command-includes.h")
#end

/**
*
*
* @author ExampleAuthor
*/
class #class($command.name): public #klass($command) {
class #class($command.name): public frc2::CommandHelper<#type($command), #class($command.name)> {
public:
#@autogenerated_code("constructor", " ")
#parse("${exporter_path}Command-constructor-header.h")
#end

void Initialize() override;
void Execute() override;
bool IsFinished() override;
void End() override;
void Interrupted() override;
void Initialize() override;
void Execute() override;
bool IsFinished() override;
void End(bool interrupted) override;
bool RunsWhenDisabled() const override;


private:
#@autogenerated_code("variables", " ")
#@autogenerated_code("variables", " ")
#parse("${exporter_path}Command-constructor-variables.h")
#end
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,11 @@
#if ($component.getBase().getType() == "Command"
&& $component.getProperty("Autonomous Selection").getValue())
#if( $component.getProperty("Parameter presets").getValue().isEmpty())
chooser.AddOption("$component.getName()", new #class($component.getName())());
chooser.AddOption("$component.getName()", new #class($component.getName())());
#else
#foreach( $set in $component.getProperty("Parameter presets").getValue() )
chooser.AddOption("$component.getName(): $set.getName()", #command_instantiation( $component.getName(), $set.getParameters() ));
chooser.AddOption("$component.getName(): $set.getName()", #command_instantiation( $component.getName(), $set.getParameters() ));
#end
#end
#end
#end

#if($command != "None")
chooser.SetDefaultOption("$command", #command_instantiation( $command, $params));
#end
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#foreach ($component in $components)
#if ($helper.exportsTo("Robot", $component))
#declaration($component)
#declaration($component)

#end
#end
4 changes: 2 additions & 2 deletions src/main/resources/export/cpp/CommandBasedRobot-includes.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#set($autonomous = $robot.getProperty("Autonomous Command").getValue())
#if($autonomous != "None")\#include "Commands/#class($autonomous).h"
#if($autonomous != "None")\#include "commands/#class($autonomous).h"
#end
#foreach( $component in $components )
#if ($component.getBase().getType() == "Command"
&& $component.getProperty("Autonomous Selection").getValue())
\#include "Commands/#class($component.getName()).h"
\#include "commands/#class($component.getName()).h"
#end
#end
${helper.getImports($robot, "Robot")}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#foreach ($component in $components)
#if ($helper.exportsTo("Robot", $component))
std::shared_ptr<#class($component.name)> Robot::#variable($component.name);
#class($component.name)* m_#variable($component.name);
#end
#end
std::unique_ptr<OI> Robot::oi;
98 changes: 45 additions & 53 deletions src/main/resources/export/cpp/CommandBasedRobot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,65 @@

\#include "Robot.h"

\#include <hal/FRCUsageReporting.h>

\#include <frc/commands/Scheduler.h>
\#include <frc/smartdashboard/SmartDashboard.h>
\#include <frc2/command/CommandScheduler.h>

#@autogenerated_code("initialization", " ")
#parse("${exporter_path}CommandBasedRobot-initialization.cpp")
#end

void Robot::RobotInit() {
#@autogenerated_code("constructors", " ")
#parse("${exporter_path}CommandBasedRobot-constructors.cpp")
#end
// This MUST be here. If the OI creates Commands (which it very likely
// will), constructing it during the construction of CommandBase (from
// which commands extend), subsystems are not guaranteed to be
// yet. Thus, their Requires() statements may grab null pointers. Bad
// news. Don't move it.
oi.reset(new OI());

HAL_Report(HALUsageReporting::kResourceType_Framework,
HALUsageReporting::kFramework_RobotBuilder);

// Add commands to Autonomous Sendable Chooser
#@autogenerated_code("autonomous", " ")
#parse("${exporter_path}CommandBasedRobot-autonomous.cpp")
#end
frc::SmartDashboard::PutData("Auto Modes", &chooser);
}
void Robot::RobotInit() {}

/**
* This function is called when the disabled button is hit.
* You can use it to reset subsystems before shutting down.
* This function is called every robot packet, no matter the mode. Use
* this for items like diagnostics that you want to run during disabled,
* autonomous, teleoperated and test.
*
* <p> This runs after the mode specific periodic functions, but before
* LiveWindow and SmartDashboard integrated updating.
*/
void Robot::DisabledInit(){
void Robot::RobotPeriodic() { frc2::CommandScheduler::GetInstance().Run(); }

}
/**
* This function is called once each time the robot enters Disabled mode. You
* can use it to reset any subsystem information you want to clear when the
* robot is disabled.
*/
void Robot::DisabledInit() {}

void Robot::DisabledPeriodic() {
frc::Scheduler::GetInstance()->Run();
}
void Robot::DisabledPeriodic() {}

/**
* This autonomous runs the autonomous command selected by your {@link
* RobotContainer} class.
*/
void Robot::AutonomousInit() {
autonomousCommand = chooser.GetSelected();
if (autonomousCommand != nullptr)
autonomousCommand->Start();
}
m_autonomousCommand = m_container.GetAutonomousCommand();

void Robot::AutonomousPeriodic() {
frc::Scheduler::GetInstance()->Run();
if (m_autonomousCommand != nullptr) {
m_autonomousCommand->Schedule();
}
}

void Robot::AutonomousPeriodic() {}

void Robot::TeleopInit() {
// This makes sure that the autonomous stops running when
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// these lines or comment it out.
if (autonomousCommand != nullptr)
autonomousCommand->Cancel();
// This makes sure that the autonomous stops running when
// teleop starts running. If you want the autonomous to
// continue until interrupted by another command, remove
// this line or comment it out.
if (m_autonomousCommand != nullptr) {
m_autonomousCommand->Cancel();
m_autonomousCommand = nullptr;
}
}

void Robot::TeleopPeriodic() {
frc::Scheduler::GetInstance()->Run();
}
/**
* This function is called periodically during operator control.
*/
void Robot::TeleopPeriodic() {}

/**
* This function is called periodically during test mode.
*/
void Robot::TestPeriodic() {}

#ifndef RUNNING_FRC_TESTS
int main(int argc, char** argv) {
return frc::StartRobot<Robot>();
}
#endif
int main() { return frc::StartRobot<Robot>(); }
#endif
43 changes: 20 additions & 23 deletions src/main/resources/export/cpp/CommandBasedRobot.h
Original file line number Diff line number Diff line change
@@ -1,30 +1,27 @@
#header()
#pragma once

\#include "frc/TimedRobot.h"
\#include "frc/commands/Command.h"
\#include "frc/livewindow/LiveWindow.h"
\#include "frc/smartdashboard/SendableChooser.h"
\#include <frc/TimedRobot.h>
\#include <frc2/command/Command.h>

#@autogenerated_code("includes", "")
#parse("${exporter_path}CommandBasedRobot-includes.h")
#end
\#include "OI.h"
\#include "RobotContainer.h"

class Robot : public frc::TimedRobot {
public:
frc::Command* autonomousCommand = nullptr;
static std::unique_ptr<OI> oi;
frc::LiveWindow *lw = frc::LiveWindow::GetInstance();
frc::SendableChooser<frc::Command*> chooser;
#@autogenerated_code("declarations", " ")
#parse("${exporter_path}CommandBasedRobot-declarations.cpp")
#end
void RobotInit() override;
void DisabledInit() override;
void DisabledPeriodic() override;
void AutonomousInit() override;
void AutonomousPeriodic() override;
void TeleopInit() override;
void TeleopPeriodic() override;
public:
void RobotInit() override;
void RobotPeriodic() override;
void DisabledInit() override;
void DisabledPeriodic() override;
void AutonomousInit() override;
void AutonomousPeriodic() override;
void TeleopInit() override;
void TeleopPeriodic() override;
void TestPeriodic() override;

private:
// Have it null by default so that if testing teleop it
// doesn't have undefined behavior and potentially crash.
frc2::Command* m_autonomousCommand = nullptr;

RobotContainer m_container;
};
Loading

0 comments on commit 7ba84ea

Please sign in to comment.