Simple Kenect Driver
<< | FRC | SmartDashboard >>
Here are 7 source files to get us started that controls the robot from the joystick and the kenect, along with SmartDashboard commands. If you build your own CommandRobot project, you may pick a different class and package convention. Here, I called it "SimpleKinectDriverBrobot", and the package name i used was "org.usfirst.frc4101" -- if you use your own, then the imports need to be updated to your package naming convention. I gathered all this from the videos and documentation you can find at http://www.mathorama.com/frc/ .
FIRST TIME YOU TRY THIS, PLACE THE ROBOT ON BLOCKS (WHEELS OFF THE GROUND) SO IT WON'T GO ANYWHERE!
OI.java
package org.usfirst.frc4101;
import org.usfirst.frc4101.commands.DriveWithJoystick;
import org.usfirst.frc4101.commands.DriveWithKenect;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.KinectStick;
import edu.wpi.first.wpilibj.buttons.Button;
import edu.wpi.first.wpilibj.buttons.JoystickButton;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
public class OI {
//adjust for joystick axis 1.0 means the axis goes from -1.0 to 1.0
public static final double max=1.0;
// Process operator interface input here.
Joystick joystick = new Joystick(1);
Button button1 = new JoystickButton(joystick, 1),
button2 = new JoystickButton(joystick, 2);
KinectStick leftArm = new KinectStick(1),
rightArm = new KinectStick(2);
public OI() {
// bind buttons to commands here, for example to test the driving modes:
button1.whenPressed(new DriveWithJoystick() );
button2.whenPressed(new DriveWithKenect() );
// For testing, you can activate your commands from the SmartDashboard:
SmartDashboard.putData(new DriveWithJoystick());
SmartDashboard.putData(new DriveWithKenect());
}
public double getLeftArmSpeed() {
// For safety, reduce to 33% of speed
return leftArm.getY()*.33;
}
public double getRightArmSpeed() {
// For safety, reduce to 33% of speed
return rightArm.getY()*.33;
}
public double getLeftSpeed() {
// see http://home.kendra.com/mauser/Joystick.html for algorithm
double x=-1.0*joystick.getX(); //invert x
double y=joystick.getY();
double v=(max-Math.abs(x))*(y/max)+y;
double w=(max-Math.abs(y))*(x/max)+x;
return .5*(v-w);
}
public double getRightSpeed() {
// see http://home.kendra.com/mauser/Joystick.html for algorithm
double x=-1.0*joystick.getX(); //invert x
double y=joystick.getY();
double v=(max-Math.abs(x))*(y/max)+y;
double w=(max-Math.abs(y))*(x/max)+x;
return .5*(v+w);
}
public void updateStatus(){
// if we had a sensor like a pot or a rangefinder, we can see the status
// on the smartDashboard like this:
SmartDashboard.putDouble(" joystick X", joystick.getX());
SmartDashboard.putDouble(" joystick Y", joystick.getY());
SmartDashboard.putDouble(" kenect right", getRightArmSpeed());
SmartDashboard.putDouble(" kenect left", getLeftArmSpeed());
}
}
RobotMap.java
package org.usfirst.frc4101;
/**
* The RobotMap is a mapping from the ports sensors and actuators are wired into
* to a variable name. This provides flexibility changing wiring, makes checking
* the wiring easier and significantly reduces the number of magic numbers
* floating around.
*/
public class RobotMap {
//Motors
public static final int
leftMotor = 1,
rightMotor = 2;
// we'll add later the collector motor
// we'll add later the elevator motor
// wel'll add the the tilt shooter motor
// we'll add later the actuator to shoot
// we'll add later the the actuator to deploy the wedge
// Sensors
// we may wish to at a pot for the motor that delivers the ball to shooter
// we may wish to add pot for the angle of the shooter
// the analog module stuff:
// public static final int
//shootAnglePot = ???3???;
}
SimpleKinectDriverBrobot.java
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package org.usfirst.frc4101;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.command.Scheduler;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import org.usfirst.frc4101.commands.CommandBase;
import org.usfirst.frc4101.commands.DriveWithKenect;
/**
* The VM is configured to automatically run this class, and to call the
* functions corresponding to each mode, as described in the IterativeRobot
* documentation. If you change the name of this class or the package after
* creating this project, you must also update the manifest file in the resource
* directory. (this is done for you if you use the IDE's 'Refactor' command)
*/
public class SimpleKinectDriverBrobot extends IterativeRobot {
Command autonomousCommand;
/**
* This function is run when the robot is first started up and should be
* used for any initialization code.
*/
public void robotInit() {
// instantiate the command used for the autonomous period
autonomousCommand = new DriveWithKenect();
// Initialize all subsystems
CommandBase.init();
// This is good for debugging to see what commands are running,
// which you can cancel from SmartDashboard:
SmartDashboard.putData(Scheduler.getInstance());
}
public void autonomousInit() {
// schedule the autonomous command (example)
autonomousCommand.start();
}
/**
* This function is called periodically during autonomous
*/
public void autonomousPeriodic() {
Scheduler.getInstance().run();
}
public void 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
// this line or comment it out.
autonomousCommand.cancel();
// for debugging:
updateStatus();
}
/**
* This function is called periodically during operator control
*/
public void teleopPeriodic() {
Scheduler.getInstance().run();
updateStatus();//for debugging
}
public void disabledPeriodic(){
updateStatus(); // for debugging
}
public void updateStatus() {
// For debugging we can call our subsystem's update status
// to see what is going on in the SmartDashboard
CommandBase.drivetrain.updateStatus();
CommandBase.oi.updateStatus();
}
}
CommandBase.java
package org.usfirst.frc4101.commands;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import org.usfirst.frc4101.OI;
import org.usfirst.frc4101.subsystems.DriveTrain;
/**
* The base for all commands. All atomic commands should subclass CommandBase.
* CommandBase stores creates and stores each control system. To access a
* subsystem elsewhere in your code in your code use CommandBase.exampleSubsystem
* @author Author
*/
public abstract class CommandBase extends Command {
public static OI oi;
// Create a single static instance of all of your subsystems
public static DriveTrain drivetrain = new DriveTrain();
// we'll add later the collector motor
// we'll add later the elevator motor
// wel'll add the the tilt shooter motor
// we'll add later the actuator to shoot
// we'll add later the the actuator to deploy the wedge
public static void init() {
// 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 = new OI();
// Show what command your subsystem is running on the SmartDashboard
SmartDashboard.putData(drivetrain);
}
public CommandBase(String name) {
super(name);
}
public CommandBase() {
super();
}
}
DriveWithJoystick.java
package org.usfirst.frc4101.commands;
public class DriveWithJoystick extends CommandBase {
public DriveWithJoystick() {
// Use requires() here to declare subsystem dependencies
requires(drivetrain);
}
// Called just before this Command runs the first time
protected void initialize() {
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
drivetrain.tankDrive(
oi.getLeftSpeed(),
oi.getRightSpeed());
}
// Make this return true when this Command no longer needs to run execute()
protected boolean isFinished() {
// if this is default command, always return false
return false;
}
// Called once after isFinished returns true
protected void end() {
}
// Called when another command which requires one or more of the same
// subsystems is scheduled to run
protected void interrupted() {
}
}
DriveWithKenect.java
package org.usfirst.frc4101.commands;
public class DriveWithKenect extends CommandBase {
public DriveWithKenect() {
// Use requires() here to declare subsystem dependencies
requires(drivetrain);
//For safety, we timeout after 15 seconds
this.setTimeout(15.0);
}
// Called just before this Command runs the first time
protected void initialize() {
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
drivetrain.tankDrive(
oi.getLeftArmSpeed(),
oi.getRightArmSpeed());
}
// Make this return true when this Command no longer needs to run execute()
protected boolean isFinished() {
// if this is default command, always return false
//return false;
//for safety, we exit after the time we specified in constructor
return this.isTimedOut();
}
// Called once after isFinished returns true
protected void end() {
}
// Called when another command which requires one or more of the same
// subsystems is scheduled to run
protected void interrupted() {
}
}
DriveTrain.java
package org.usfirst.frc4101.subsystems;
import org.usfirst.frc4101.RobotMap;
import org.usfirst.frc4101.commands.DriveWithJoystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.command.Subsystem;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
public class DriveTrain extends Subsystem {
RobotDrive drive;
public DriveTrain(){
super ("DriveTrain");
drive = new RobotDrive(RobotMap.leftMotor, RobotMap.rightMotor);
}
public void initDefaultCommand() {
setDefaultCommand(new DriveWithJoystick());
}
public void tankDrive(double left, double right){
drive.tankDrive(left, right);
}
public void updateStatus(){
// if we had a sensor like a pot or a rangefinder, we can see the status
// on the smartDashboard like this:
//SmartDashboard.putDouble("Shoot Angle", shootAnglePot.getVoltage());
double time=this.getCurrentCommand().timeSinceInitialized();
SmartDashboard.putDouble("Time running", time);
}
}
