|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
| Thread Tools | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Timer.Delay stops motor movement?
I'm currently trying to program autonomous and it's working, I've isolated this issue to be with the Timer.Delay(seconds) command. When hovering over the command, it states that it allows: "Motors [to] continue to run at their last assigned values," but it simply stops them for the time allotted. Are there any alternative timing methods that allow motors to continue to run and change the command after an allotted time?
code: Code:
case leftAuto:
System.out.print("YOU'RE LEFT");
Timer.delay(2.5);
arcadeDrive.drive(1, 0);
Timer.delay(5);
arcadeDrive.drive(0.75, .6);
Timer.delay(3);
solenoid2.set(DoubleSolenoid.Value.kForward);
Timer.delay(2);
solenoid2.set(DoubleSolenoid.Value.kReverse);
arcadeDrive.drive(-1, .8);
Timer.delay(4.8);
arcadeDrive.drive(-.25, 0);
Timer.delay(2);
break;
|
|
#2
|
|||
|
|||
|
Re: Timer.Delay stops motor movement?
Is "arcadeDrive" an instance of a RobotDrive? If so, did you disable the motor safety feature? If not, the speed controllers will think that they are no longer being controlled when your Timer.delay() pauses. This will cause the watchdog to time out and disable all of the drive motors.
Here is an example of turning off the motor safety feature while driving autonomously: Code:
case leftAuto:
// Disable watchdog when autonomous driving
arcadeDrive.setSafetyEnabled(false);
System.out.print("YOU'RE LEFT");
Timer.delay(2.5);
arcadeDrive.drive(1, 0);
Timer.delay(5);
arcadeDrive.drive(0.75, .6);
Timer.delay(3);
solenoid2.set(DoubleSolenoid.Value.kForward);
Timer.delay(2);
solenoid2.set(DoubleSolenoid.Value.kReverse);
arcadeDrive.drive(-1, .8);
Timer.delay(4.8);
arcadeDrive.drive(-.25, 0);
Timer.delay(2);
// WARNING! It looks like you leave the motors running! Is that what
// you want? Or, would it be better to stop at this point?
//arcadeDrive.drive(0, 0);
// Enable watchdog on driving again
arcadeDrive.setSafetyEnabled(true);
break;
|
|
#3
|
|||||
|
|||||
|
Re: Timer.Delay stops motor movement?
I'm not sure exactly what you're trying to do, but this many Timer.delay() calls in a single routine is definitely not the code you're looking for. Which robot model are you using (SampleRobot, IterativeRobot, CommandBasedRobot, etc)?
|
|
#4
|
|||
|
|||
|
Re: Timer.Delay stops motor movement?
Quote:
Quote:
![]() |
|
#5
|
||||
|
||||
|
Re: Timer.Delay stops motor movement?
We used this auto format in 2014 and it worked well. This format works just fine for simple autos.
|
|
#6
|
||||
|
||||
|
Re: Timer.Delay stops motor movement?
Quote:
Code:
import edu.wpi.first.wpilibj.Timer;
public class Robot extends IterativeRobot {
private double autoStartTime;
public void autonomousInit() {
autoStartTime = Timer.getFPGATimestamp();
//other stuff as needed
}
public void autonomousPeriodic() {
double currTime = Timer.getFPGATimestamp();
double timeElapsed = currTime - autoStartTime;
if( timeElapsed < 2 ) {
//put code here...whatever you want to do for the first 2 seconds
arcadeDrive.drive(1, 0);
}
else if( timeElapsed < 5) {
//put code here that you want to do for the next 3 seconds
arcadeDrive.drive(0.75, 0.6);
}
//etc.
}
//the rest of your Robot class
}
Code:
public void autonomousPeriodic() {
double currTime = Timer.getFPGATimestamp();
double timeElapsed = currTime - autoStartTime;
switch( AUTO_TYPE ) {
case LEFT:
if( timeElapsed < 2 ) {
//put code here...whatever you want to do for the first 2 seconds
arcadeDrive.drive(1, 0);
}
else if( timeElapsed < 5) {
//put code here that you want to do for the next 3 seconds
arcadeDrive.drive(0.75, 0.6);
}
//etc.
break;
case RIGHT:
//etc.
}
|
|
#7
|
|||
|
|||
|
Re: Timer.Delay stops motor movement?
I've tried using your code with the if and else if statements, as well as the time elapsed variable, and i believe it works. however, my robot just beyblades in place when enabled. do you have any idea why this might happen?
|
|
#8
|
|||
|
|||
|
Re: Timer.Delay stops motor movement?
That sounds like you have something very wrong that is entirely unrelated to the issues being discussed in this thread.
|
|
#9
|
|||
|
|||
|
Re: Timer.Delay stops motor movement?
Fair, but I can't imagine it's anything mechanical. Our teleop drive works, as does everything else.
|
|
#10
|
||||
|
||||
|
Re: Timer.Delay stops motor movement?
It would really help if you posted your code...the whole class, not just a snippet.
|
|
#11
|
|||
|
|||
|
Re: Timer.Delay stops motor movement?
Here it is:
Code:
package org.usfirst.frc.team2221.robot;
import edu.wpi.first.wpilibj.Compressor;
import edu.wpi.first.wpilibj.DoubleSolenoid;
import edu.wpi.first.wpilibj.GenericHID.Hand;
import edu.wpi.first.wpilibj.GenericHID.RumbleType;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Talon;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj.RobotDrive.MotorType;
public class Robot extends IterativeRobot {
/*--------------------------------------------------------------------*/
/*----------------------Setup Talons---------------------*/
Talon frontLeft = new Talon(0);
Talon rearLeft = new Talon(1);
Talon frontRight = new Talon(2);
Talon rearRight = new Talon(3);
Talon Spare = new Talon(4);
/*--------------------------------------------------------------------*/
/*---------------------CONTROLLERS-----------------------------*/
XboxController xbox1 = new XboxController(0); // Driver Xbox (xboxController)
XboxController xbox2 = new XboxController(1); // Manipulator Xbox (xboxController)
/*--------------------------------------------------------------------*/
/*----------------------Controller Settings----------------------------------*/
double xbox1_value_x; // Xbox1 x-values
double xbox1_value_y; // Xbox1 y-values
double xbox2_value_triggerRight = xbox2.getTriggerAxis(Hand.kRight);
double xbox2_value_triggerLeft = xbox2.getTriggerAxis(Hand.kLeft);
/*--------------------------------------------------------------------*/
/*---------------------Setup Arcade Drive-----------------------------*/
RobotDrive arcadeDrive = new RobotDrive(frontLeft, rearLeft, frontRight, rearRight);
/*--------------------------------------------------------------------*/
/*----------------------Autonomous Chooser---------------------------*/
SendableChooser<String> chooser = new SendableChooser<>();
final String leftAuto = "Drive Left";
final String straightAuto = "Drive Straight";
final String rightAuto = "Drive Right";
final String spyAuto = "Spybot";
/*--------------------------------------------------------------------*/
/*-----------------------Setup Compressor----------------------*/
Compressor comp = new Compressor(0); // the Zero is the PCM NODE ID in the Web Environment
/*--------------------------------------------------------------------*/
/*---------------------Setup Solenoids (And Triggers)---------------*/
DoubleSolenoid solenoid1 = new DoubleSolenoid(0, 1);
DoubleSolenoid solenoid2 = new DoubleSolenoid(2, 3);
DoubleSolenoid solenoid3 = new DoubleSolenoid(4, 5);
boolean solenoid1_trigger;
boolean solenoid2_trigger;
boolean solenoid3_trigger;
final String auto1 = "autoOne";
String autoSelected;
private double autoStartTime;
public Robot() {
arcadeDrive.setExpiration(0.1);
}
@Override
public void robotInit() {
comp.setClosedLoopControl(true);
arcadeDrive.setInvertedMotor(MotorType.kFrontLeft, false);
arcadeDrive.setInvertedMotor(MotorType.kFrontRight, false);
arcadeDrive.setInvertedMotor(MotorType.kRearLeft, false);
arcadeDrive.setInvertedMotor(MotorType.kRearRight, true);
}
@Override
public void autonomousInit(){
autoStartTime = Timer.getFPGATimestamp();
autoSelected = (String) chooser.getSelected();
System.out.println("Auto selected: " + autoSelected);
Timer timer = new Timer();
timer.start();
}
@Override
public void autonomousPeriodic() {
double currTime = Timer.getFPGATimestamp();
double timeElapsed = currTime - autoStartTime;
System.out.println("Auto selected: " + autoSelected);
switch (autoSelected) {
case leftAuto:
// Disable watchdog when autonomous driving
arcadeDrive.setSafetyEnabled(false);
System.out.print("You're left");
if ( timeElapsed < 2)
{
arcadeDrive.drive(1, 0);
}
else if (timeElapsed < 4)
{
arcadeDrive.drive(0.75, .6);
}
else if (timeElapsed < 6)
{
arcadeDrive.drive(0, 0);
solenoid2.set(DoubleSolenoid.Value.kForward);
}
else if (timeElapsed < 8.5)
{
solenoid2.set(DoubleSolenoid.Value.kReverse);
arcadeDrive.drive(-1, .8);
}
else if (timeElapsed < 9.5)
{
arcadeDrive.drive(-.25, 0);
}
else if (timeElapsed > 11)
{
arcadeDrive.drive(0, 0);
}
arcadeDrive.setSafetyEnabled(true);
break;
case "straightAuto":
arcadeDrive.setSafetyEnabled(false);
System.out.print("you're straight");
if(timeElapsed < 2)
{
arcadeDrive.drive(.5, 1);
}
else if(timeElapsed < 3)
{
arcadeDrive.drive(0, 0);
}
else if (timeElapsed < 3.5)
{
solenoid2.set(DoubleSolenoid.Value.kForward);
}
else if (timeElapsed < 4.5)
{
solenoid2.set(DoubleSolenoid.Value.kReverse);
}
else if (timeElapsed < 5)
{
arcadeDrive.drive(-.75, 0);
}
else if (timeElapsed > 8)
{
arcadeDrive.drive(0, 0);
}
else if (timeElapsed > 10)
{
arcadeDrive.setSafetyEnabled(true);
}
break;
case "rightAuto":
System.out.print("you're right");
arcadeDrive.setSafetyEnabled(false);
if(2.5 < timeElapsed && timeElapsed < 5)
{
arcadeDrive.drive(1, 0);
}
else if (timeElapsed < 7)
{
arcadeDrive.drive(0.75, -.6);
solenoid2.set(DoubleSolenoid.Value.kForward);
}
else if (timeElapsed < 9){
solenoid2.set(DoubleSolenoid.Value.kReverse);
arcadeDrive.drive(-1, -.8);
}
else if (timeElapsed < 11 )
{
arcadeDrive.drive(-.25, 0);
}
else if (timeElapsed > 12)
{
arcadeDrive.drive(0, 0);
arcadeDrive.setSafetyEnabled(true);
}
break;
default:
arcadeDrive.setSafetyEnabled(false);
System.out.print("YOU'RE LEFT");
if ( timeElapsed < 2)
{
arcadeDrive.drive(1, 0);
}
else if (timeElapsed < 4)
{
arcadeDrive.drive(0.75, .6);
}
else if (timeElapsed < 6)
{
arcadeDrive.drive(0, 0);
solenoid2.set(DoubleSolenoid.Value.kForward);
}
else if (timeElapsed < 8.5)
{
solenoid2.set(DoubleSolenoid.Value.kReverse);
arcadeDrive.drive(-1, .8);
}
else if (timeElapsed < 9.5)
{
arcadeDrive.drive(-.25, 0);
}
else if (timeElapsed > 11)
{
arcadeDrive.drive(0, 0);
}
// Enable watchdog on driving again
arcadeDrive.setSafetyEnabled(true);
break;
}
}
@Override
public void teleopInit(){
}
@Override
public void teleopPeriodic() {
arcadeDrive.setSafetyEnabled(true);
//-----------------------Driver Controller---------------------------------//
if(xbox1.getAButton()){
xbox1_value_x = xbox1.getX(Hand.kLeft) * 0.75;
xbox1_value_y = xbox1.getY(Hand.kLeft) * 0.75;
}
else{
xbox1_value_x = xbox1.getX(Hand.kLeft);
xbox1_value_y = xbox1.getY(Hand.kLeft);
}
arcadeDrive.arcadeDrive(xbox1_value_x, xbox1_value_y);
//-----------------------Manipulator Controller---------------------------------//
if(xbox2.getBButton()){
if(solenoid1_trigger != true){
solenoid1.set(DoubleSolenoid.Value.kForward);
solenoid1_trigger = true;
xbox2.setRumble(RumbleType.kRightRumble, 1);
Timer.delay(.5);
xbox2.setRumble(RumbleType.kRightRumble, 0);
}
else
{
solenoid1.set(DoubleSolenoid.Value.kReverse);
solenoid1_trigger = false;
Timer.delay(.5);
}}
else if(xbox2.getXButton()){
if(solenoid2_trigger != true){
solenoid2.set(DoubleSolenoid.Value.kForward);
solenoid2_trigger = true;
xbox2.setRumble(RumbleType.kRightRumble, 1);
Timer.delay(.5);
xbox2.setRumble(RumbleType.kRightRumble, 0);
}
else
{
solenoid2.set(DoubleSolenoid.Value.kReverse);
solenoid2_trigger = false;
Timer.delay(.5);
}
}
else if(xbox2.getYButton()){
if(solenoid3_trigger != true){
solenoid3.set(DoubleSolenoid.Value.kForward);
solenoid3_trigger = true;
xbox2.setRumble(RumbleType.kRightRumble, 1);
Timer.delay(.5);
xbox2.setRumble(RumbleType.kRightRumble, 0);
}
else
{
solenoid3.set(DoubleSolenoid.Value.kReverse);
solenoid3_trigger = false;
Timer.delay(.5);
}
}
if(xbox2.getBumper(Hand.kLeft) == true){
Spare.set(xbox2_value_triggerLeft);
}
else if (xbox2.getBumper(Hand.kRight) == true){
Spare.set(xbox2_value_triggerRight);
}
}
}
|
|
#12
|
|||
|
|||
|
Re: Timer.Delay stops motor movement?
I'm not sure that I can answer your autonomous behavior question, but I do have some suggestions that might help clean up some issues.
If you want to turn the motor safety feature on in teleop and off in autonomous, I would recommend that you move the invocation into the teleopInit() and autonomousInit() methods (and then remove the calls from your periodic methods). Code:
@Override
public void autonomousInit() {
autoStartTime = Timer.getFPGATimestamp();
autoSelected = (String) chooser.getSelected();
System.out.println("Auto selected: " + autoSelected);
Timer timer = new Timer();
timer.start();
arcadeDrive.setSafetyEnabled(false);
}
@Override
public void teleopInit() {
arcadeDrive.setSafetyEnabled(true);
}
Code:
if (2.5 < timeElapsed && timeElapsed < 5) {
arcadeDrive.drive(1, 0);
} else if (timeElapsed < 7) {
arcadeDrive.drive(0.75, -.6);
solenoid2.set(DoubleSolenoid.Value.kForward);
} else if (timeElapsed < 9) {
solenoid2.set(DoubleSolenoid.Value.kReverse);
arcadeDrive.drive(-1, -.8);
} else if (timeElapsed < 11) {
arcadeDrive.drive(-.25, 0);
} else if (timeElapsed > 12) {
arcadeDrive.drive(0, 0);
arcadeDrive.setSafetyEnabled(true);
}
Finally, you really want to avoid any use of Timer.delay() in the teleop portion of your robot. If the driver happens to be moving the robot at 10 ft/sec and presses a button that fires off one of your Timer.delay(0.5) calls, the robot will move 5 feet before the operator will have a chance to control it again (hopefully the motor safety will kick in and stop the robot if this condition occurs). You want to avoid features like gamepad rumble if they will disable the ability to drive the robot. For an iterative base robot, you will need to keep track of the state of your different events. One way to do this is with small helper classes. For example, the following Rumbler class keeps track of the rumbling state of a gamepad and turns it off after the appropriate delay (provided you use the start() method to start it and periodically call its periodic() method): Code:
package org.usfirst.frc.team868.robot;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.XboxController;
import edu.wpi.first.wpilibj.GenericHID.RumbleType;
public class Rumbler {
private final XboxController gamepad;
private boolean rumbling;
private double startTime;
private double duration;
private RumbleType rtype;
public Rumbler(XboxController gamepad, double duration, RumbleType rtype) {
this.gamepad = gamepad;
this.rumbling = false;
this.startTime = 0;
this.duration = 0.5;
this.rtype = RumbleType.kRightRumble;
}
public Rumbler(XboxController gamepad) {
this(gamepad, 0.5, RumbleType.kRightRumble);
}
/**
* Start rumbling the gamepad.
*/
public void start() {
rumbling = true;
startTime = Timer.getFPGATimestamp();
}
/**
* Periodic check to see if we need to turn off rumbling (does not block).
*/
public void periodic() {
if (rumbling) {
double now = Timer.getFPGATimestamp();
if ((now - startTime) > duration) {
rumbling = false;
gamepad.setRumble(rtype, 0);
}
}
}
}
Code:
XboxController xbox2 = new XboxController(1); // Manipulator Xbox
// (xboxController)
// Used to trigger rumble feature on Manipulator gamepad
Rumbler rumble2 = new Rumbler(xbox2);
Then in your teleopPeriodic() you could make use of this and get rid of some of your timer delays: Code:
// -----------------------Manipulator
// Controller---------------------------------//
// Always update state of rumble on gamepad
rumble2.periodic();
if (xbox2.getBButton()) {
if (solenoid1_trigger != true) {
solenoid1.set(DoubleSolenoid.Value.kForward);
solenoid1_trigger = true;
// Turn on rumbling (periodic() call above will turn it off at the appropriate time)
rumble2.start();
} else {
solenoid1.set(DoubleSolenoid.Value.kReverse);
solenoid1_trigger = false;
Timer.delay(.5);
}
}
// ...
These kind of situations are why the command based robot framework was designed. Good luck. |
|
#13
|
||||
|
||||
|
Re: Timer.Delay stops motor movement?
pblankenbaker brings up many good points. As to why autonomous is doing nothing (actually, what do you mean by beyblades...I'm not familiar with that expression), I'm not sure. I am curious what you have done to figure it out yourself...have you tried putting a println statement in autonomousPeriodic that shows the value of the timeElapsed variable, which is the variable controlling the timed actions? I would also take a look at the value you got in autonomousInit for autoStartTime. I am not in front of a robot right now, but I'm wondering if your construction of a Timer object and the call to the start() method (in autonomousInit) has any effect on the values returned by Timer.getFPGATimestamp() [the documentation is unclear but makes me think that I'd definitely investigate that]. If that resets or modifies the values returned by the getFPGATimestamp method, then placing the call to start() after you get the autoStartTime might be what is ailing you. Perhaps that (calling the start() method) needs to be removed or placed before you get the autoStartTime value. Bottom line, do you know the values of autoStartTime and timeElapsed (which is based on autoStartTime)?
Another thing that looks odd to me (but is ok if it is working...I'm just curious) is your motor inversions on your drive train. You invert one motor only (the rear, right motor). Again, if everything drives ok then it works...but I'd love to understand how that makes sense. I'm guessing that my tired, addled brain is missing something there. Quote:
|
|
#14
|
||||
|
||||
|
Re: Timer.Delay stops motor movement?
Did you trying looking it up on the internet?
|
|
#15
|
||||
|
||||
|
Re: Timer.Delay stops motor movement?
I'm honestly embarrassed to admit that I didn't (I kind of assumed a weird typo, which is a ridiculous assumption on my part). Now that I have looked it up, I am guessing that the robot just spun in circles...which is what pblankenbaker pointed out should happen given the conditional structure.
|
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|