-
Notifications
You must be signed in to change notification settings - Fork 3
AbstractServoTuneOp
Johan Vandegriff edited this page Dec 15, 2016
·
5 revisions
Go to Servo Presets to see how to extend this class to tune the servos.
Here is AbstractServoTuneOp, which can be extended to tune servos for any Robot Configuration.
ftc/evlib/opmodes/AbstractServoTuneOp.java
package ftc.evlib.opmodes;
import java.util.ArrayList;
import java.util.List;
import ftc.electronvolts.util.Function;
import ftc.electronvolts.util.Functions;
import ftc.electronvolts.util.Utility;
import ftc.electronvolts.util.files.Logger;
import ftc.electronvolts.util.files.OptionsFile;
import ftc.electronvolts.util.units.Time;
import ftc.evlib.hardware.config.RobotCfg;
import ftc.evlib.hardware.servos.ServoCfg;
import ftc.evlib.hardware.servos.ServoControl;
import ftc.evlib.hardware.servos.ServoName;
import ftc.evlib.util.EVConverters;
/**
* This file was made by the electronVolts, FTC team 7393
* Date Created: 9/30/16
*
* extends AbstractTeleOp and adds tuning of servo presets with the joysticks.
*
* Subclasses of this are very simple since this does most of the work.
*
* It allows you to change your servo presets without changing the code and re-deploying it to the
* phone. This means that you can swap out a servo and re-tune it without having to go into the
* program and fix magic numbers. Note: It only works if you use presets everywhere instead of
* hardcoded values.
*
* How to use for your robot:
* Create a subclass of this (AbstractServoTuneOp).
* return a new instance of your RobotCfg (it has the servos) in createRobotCfg().
*
* Subclass example:
*
* <code>
*
* \@TeleOp(name = "MyRobot ServoTuneOp")
* public class MyRobotServoTuneOp extends AbstractServoTuneOp {
* \@Override protected RobotCfg createRobotCfg() {
* return new MyRobotCfg(hardwareMap);
* }
* }
* </code>
*
* How to operate:
* Use the dpad up and down to cycle through all the servos
* Use the dpad left and right to move through the presets for that servo.
* Use the left and right joystick y values to change the servo position.
* Press start to save the current preset of the current servo to the current value.
*
* The presets are saved in files that are retrieved when you run other opmodes to find the value of each preset.
*
* @see ServoControl
* @see ServoCfg
*/
public abstract class AbstractServoTuneOp extends AbstractTeleOp<RobotCfg> {
/**
* The index of the servo in the list
*/
private int servoIndex = 0;
/**
* The index of the preset for the current servo
*/
private int presetIndex = 0;
/**
* records whether or not a new servo has been selected
*/
private boolean servoIndexChanged = true;
/**
* records whether or not a new servo preset has been selected
*/
private boolean servoPresetIndexChanged = true;
/**
* The list of current positions for each servo
*/
private final List<Double> servoPositions = new ArrayList<>();
/**
* The list of servo names
*/
private List<ServoName> servoNames;
/**
* The list of preset names for the current servo
*/
private List<Enum> presetNames;
/**
* The list of preset values for the current servo
*/
private List<Double> presetValues;
/**
* The current servo
*/
private ServoControl servo;
/**
* @return no joystick scaling
*/
@Override
protected Function getJoystickScalingFunction() {
return Functions.none();
}
/**
* @return no match timer
*/
@Override
public Time getMatchTime() {
return null;
}
/**
* @return no logging
*/
@Override
protected Logger createLogger() {
return null;
}
@Override
protected void setup() {
//get a list of servo names from the RobotCfg
servoNames = robotCfg.getServos().getServoNames();
//add servo positions to be the same length as servoNames
for (ServoName ignored : servoNames) {
servoPositions.add(0.5);
}
}
@Override
protected void setup_act() {
}
@Override
protected void go() {
}
@Override
protected void act() {
//if dpad up is pressed
if (driver1.dpad_up.justPressed() || driver2.dpad_up.justPressed()) {
servoIndex += 1; //move to the next servo
//wrap around if the index is too large
if (servoIndex > servoNames.size() - 1) servoIndex = 0;
servoIndexChanged = true; //signal that the index changed
}
//if dpad down is pressed
if (driver1.dpad_down.justPressed() || driver2.dpad_down.justPressed()) {
servoIndex -= 1; //move to the previous servo
//wrap around if the index is too small
if (servoIndex < 0) servoIndex = servoNames.size() - 1;
servoIndexChanged = true; //signal that the index changed
}
//if a different servo was selected
if (servoIndexChanged) {
servoIndexChanged = false;
servo = robotCfg.getServo(servoNames.get(servoIndex));//get the servo
presetNames = new ArrayList<>(servo.getPresets().keySet()); //get the preset names from the servo
presetValues = new ArrayList<>(servo.getPresets().values()); //get the presets from the servo
presetIndex = 0; //start at the first preset for the new servo
servoPresetIndexChanged = true; //signal to reload the servo preset
}
//get the servo position
double servoPosition = servoPositions.get(servoIndex);
//if the dpad left was just pressed
if (driver1.dpad_left.justPressed() || driver2.dpad_left.justPressed()) {
presetIndex -= 1; //select the previous servo preset
//wrap around if the index is too small
if (presetIndex < 0) presetIndex = presetValues.size() - 1;
servoPresetIndexChanged = true; //signal that the index changed
}
//if the dpad right was just pressed
if (driver1.dpad_right.justPressed() || driver2.dpad_right.justPressed()) {
presetIndex += 1; //select the next servo preset
//wrap around if the index is too large
if (presetIndex > presetValues.size() - 1) presetIndex = 0;
servoPresetIndexChanged = true; //signal that the index changed
}
//is the servo preset index changed
if (servoPresetIndexChanged) {
servoPresetIndexChanged = false;
servoPosition = presetValues.get(presetIndex); //set the servo to the preset position
}
telemetry.addData("Press start to set the current preset to the current value", "");
//if start is pressed, save the current preset to a file
if (driver1.start.justPressed() || driver2.start.justPressed()) {
//set the current selected preset to the current servo position
servo.getPresets().put(presetNames.get(presetIndex), servoPosition);
presetValues.set(presetIndex, servoPosition);
OptionsFile optionsFile = new OptionsFile(EVConverters.getInstance()); //create an OptionsFile
//put the preset names and presets into the OptionsFile
for (int i = 0; i < presetNames.size(); i++) {
optionsFile.set(presetNames.get(i).name(), presetValues.get(i).toString());
}
optionsFile.writeToFile(ServoCfg.getServoFile(servoNames.get(servoIndex))); //store the OptionsFile to a file
}
//modify the servo position using the joysticks
servoPosition += 2e-4 * matchTimer.getDeltaTime() * (driver1.left_stick_y.getValue() + 0.1 * driver1.right_stick_y.getValue() + driver2.left_stick_y.getValue() + 0.1 * driver2.right_stick_y.getValue());
//limit the position
servoPosition = Utility.servoLimit(servoPosition);
//set the servo to the position
servo.setPosition(servoPosition);
//store the position
servoPositions.set(servoIndex, servoPosition);
//display telemetry about the servo
telemetry.addData("Servo Name", servoNames.get(servoIndex));
telemetry.addData("Servo Preset Name", presetNames.get(presetIndex));
telemetry.addData("Servo Preset Value", servoPosition);
}
@Override
protected void end() {
}
}
This guide will step through the basics of how to set up OpModes using EVLib.
- Importing Into Your Project
- Sample Code
- Using EVLib Minimally
- Logging Example
- Robot Configuration
- Basic TeleOp Program
- Basic Autonomous Program
- Customizing StateMachineBuilder
- Servo Presets
- Adding Servos to the Configuration
- Adding Servos to TeleOp
- Adding Servos to Autonomous
- Vuforia and OpenCV Beacon Color Detection