Go to Post We're all such geeks...not that's that a bad thing. - IMDWalrus [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rate Thread Display Modes
  #1   Spotlight this post!  
Unread 05-02-2016, 17:49
fireXtract fireXtract is offline
MegaHertz_Lux
FRC #2847 (Mega Hertz)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: fmt
Posts: 42
fireXtract is an unknown quantity at this point
Threading?

I am running into the issue that I can not do other robot things while my kickBall method is running. I am using this way currently for threading, but it crashes as is. I have also tried using the kickBall method to call just kickThread.run(); but that doesn't let me do anything else while the servo is moving.

Code:
Thread kickThread = new Thread() {
		public void run() {
			int i = 0;
			for (; i < 20; i++) {
				if (i == 1) {
					setKickAngle(RobotMap.kickDefaultAngle);
					doneKicking = false;
				} else if (i == 4) {
					setKickAngle(RobotMap.kickHitAngle);
					doneKicking = false;
				} else if (i == 15) {
					setKickAngle(RobotMap.kickDefaultAngle);
					doneKicking = true;
				}
				Timer.delay(0.05);

			}
			doneKicking = true;

			kickThread.interrupt();
		}
	};

	public void autoKick() {
		if (!kickThread.isAlive() && kickThread.isInterrupted()) {
			kickThread.start();
		} else {
			kickThread.run();
		}
	}
Full code at my github
Thanks for any input you guys have!
Reply With Quote
  #2   Spotlight this post!  
Unread 06-02-2016, 07:12
pblankenbaker pblankenbaker is offline
Registered User
FRC #0868
 
Join Date: Feb 2012
Location: Carmel, IN, USA
Posts: 108
pblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of light
Re: Threading?

When you create a Thread in Java, you only need to use the start() method to start the thread running in the background (you do not need to call the Thread's run() method directly). Try the following changes:

Code:
         Thread kickThread = new Thread() {
		public void run() {
			int i = 0;
			for (; i < 20; i++) {
				if (i == 1) {
					setKickAngle(RobotMap.kickDefaultAngle);
					doneKicking = false;
				} else if (i == 4) {
					setKickAngle(RobotMap.kickHitAngle);
					doneKicking = false;
				} else if (i == 15) {
					setKickAngle(RobotMap.kickDefaultAngle);
					doneKicking = true;
				}
				Timer.delay(0.05);

			}
			doneKicking = true;

                        // CHANGE 1: Thread will terminate here, you don't need to try and have your thread interrupt itself
			// kickThread.interrupt();
		}
	};

	public void autoKick() {
                // CHANGE 2: You only need to start your thread once per kick,
                // its run() method will be done in the background
		if (!kickThread.isAlive()) {
			kickThread.start();
		}
	}
Reply With Quote
  #3   Spotlight this post!  
Unread 09-02-2016, 12:34
fireXtract fireXtract is offline
MegaHertz_Lux
FRC #2847 (Mega Hertz)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: fmt
Posts: 42
fireXtract is an unknown quantity at this point
Re: Threading?

Okay, I understand that we can leave the thread just running in the background, and the servo will move the first time we press the button, but I want to be able to press the button more than once per run of the robot. The way it is setup with your changed code I still run into the issue of only being able to kick the ball one time per power cycle. What can I do to fix that?

EDIT: Actually I pushed the code, and the second time I run the autoKick() method the code crashes with Illegal thread state errors.

Last edited by fireXtract : 09-02-2016 at 12:42.
Reply With Quote
  #4   Spotlight this post!  
Unread 09-02-2016, 14:06
pblankenbaker pblankenbaker is offline
Registered User
FRC #0868
 
Join Date: Feb 2012
Location: Carmel, IN, USA
Posts: 108
pblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of light
Re: Threading?

It looks like you forgot to remove the interrupt() invocation and check that the thread was not running before attempting to start it again.

However, it looks like you are now using the Command based framework in your robot project. In this case you should not need any threading to accomplish the automated task.

As a rough guess, it appears that you are automating the task of kicking the boulder and this task involves spinning up some shooter motors and using a servo to feed the boulder into the shooter. My guess is that you are trying to:
  • Move the servo back to keep the ball out of the "spinners".
  • Spin up your motors.
  • Move the servo into a "kick" position to push the boulder through the spinners.
  • Let the boulder pass through the spinners (wait a bit).
  • Stop the spinners
  • Return the servo to its default position

Using your existing Shooter subsystem, you should be able to create two new simple commands and one command group to accomplish this.

SetShooterSpeed - Simply sets the power on your shooter spinners and then quits (leaves the motors running).
SetKickerPosition - Sets the position of the shooter servo.
AutonKickCommand - Uses the two above commands and the built in WaitCommand to automate the entire sequence.

Here is a start of SetShooterSpeed.java:

Code:
package org.usfirst.frc.team2847.robot.commands;

import org.usfirst.frc.team2847.robot.Robot;

import edu.wpi.first.wpilibj.command.Command;

/**
 * Command that sets power to shooter wheels and leaves them running.
 */
public class SetShooterSpeed extends Command {
	double speed;

	public SetShooterSpeed(double speed) {
		requires(Robot.shooter);
		this.speed = speed;
	}

	// Called just before this Command runs the first time
	protected void initialize() {
		Robot.shooter.spinShooters(speed);
	}

	// Called repeatedly when this Command is scheduled to run
	protected void execute() {
	}

	// Make this return true when this Command no longer needs to run execute()
	protected boolean isFinished() {
		return true;
	}

	// Called once after isFinished returns true
	protected void end() {
		// Leave shooters running
		// Robot.shooter.spinShooters(0);
	}

	// Called when another command which requires one or more of the same
	// subsystems is scheduled to run
	protected void interrupted() {
		end();
	}
}
Here is SetKickerPosition:

Code:
package org.usfirst.frc.team2847.robot.commands;

import org.usfirst.frc.team2847.robot.Robot;

import edu.wpi.first.wpilibj.command.Command;

/**
 * Command that sets power to shooter wheels and leaves them running.
 */
public class SetKickerPosition extends Command {
	double angle;

	public SetKickerPosition(double angle) {
		requires(Robot.shooter);
		this.angle = angle;
	}

	// Called just before this Command runs the first time
	protected void initialize() {
		Robot.shooter.setKickAngle(angle);
	}

	// Called repeatedly when this Command is scheduled to run
	protected void execute() {
	}

	// Make this return true when this Command no longer needs to run execute()
	protected boolean isFinished() {
		return true;
	}

	// 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() {
		end();
	}
}
Finally, here is the command group that ties it all together:

Code:
package org.usfirst.frc.team2847.robot.commands;

import org.usfirst.frc.team2847.robot.RobotMap;

import edu.wpi.first.wpilibj.command.CommandGroup;
import edu.wpi.first.wpilibj.command.WaitCommand;

public class AutonKick extends CommandGroup {

	public AutonKick(double speed) {
		super("AutonKick " + speed);
		
		// Get .25 seconds for kicker to get into default position
		addSequential(new SetKickerPosition(RobotMap.kickDefaultAngle));
		addSequential(new WaitCommand(0.25));
		
		// Start spinning up shooters and give them 2 seconds to reach speed
		addSequential(new SetShooterSpeed(speed));
		addSequential(new WaitCommand(2.0));
		
		// Move kicker into kick position and give .5 second for boulder
		// to pass through
		addSequential(new SetKickerPosition(RobotMap.kickHitAngle));
		addSequential(new WaitCommand(0.5));
		
		// Stop shooter and return kicker to default position
		addSequential(new SetShooterSpeed(0));
		addSequential(new SetKickerPosition(RobotMap.kickDefaultAngle));
	}
}
NOTE: All of this is a "best guess", make sure you refactor it to how your robot is actually designed. Also, thanks for providing the github link. It made it much easier to review your code by being able to pull down a copy in Eclipse.

Hope that helps.
Reply With Quote
  #5   Spotlight this post!  
Unread 09-02-2016, 16:30
fireXtract fireXtract is offline
MegaHertz_Lux
FRC #2847 (Mega Hertz)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: fmt
Posts: 42
fireXtract is an unknown quantity at this point
Re: Threading?

Thank you! I was thinking quite narrow minded by thinking the only way I could do it was with threading! Thanks for showing me the way! One question, what does the super() thing do in the commandgroup? I use it in my PIDSubsystem to pass PID info, but what does it do in this case?

EDIT: I ended up doing this, the second parameter of the command can be used as a timeout ex. (addSequential(),1.5). I needed to do this so that the list doesn't get stuck in the SetShooterSpeedCommand as I don't have it exit unless its interrupted. This works as desired. Thanks for the help pblankenbaker!
Code:
	public KickNShootCommandGroup() {
		// super("KickNShootCommandGroup " + RobotMap.shootSpeed);

		// to get into default position
		addSequential(new SetKickerPositionCommand(RobotMap.kickDefaultAngle));

		// Start spinning up shooters and give them 2 seconds to reach speed
		addSequential(new SetShooterSpeedCommand(RobotMap.shootSpeed), 1.5);

		// Move kicker into kick position and give .5 second for boulder
		// to pass through
		addSequential(new SetKickerPositionCommand(RobotMap.kickHitAngle));
		addSequential(new WaitCommand(0.7));

		// Stop shooter and return kicker to default position

		addSequential(new SetKickerPositionCommand(RobotMap.kickDefaultAngle));
		addParallel(new SetShooterSpeedCommand(0), 0.5);
	}

Last edited by fireXtract : 09-02-2016 at 16:57. Reason: code
Reply With Quote
  #6   Spotlight this post!  
Unread 09-02-2016, 17:13
pblankenbaker pblankenbaker is offline
Registered User
FRC #0868
 
Join Date: Feb 2012
Location: Carmel, IN, USA
Posts: 108
pblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of lightpblankenbaker is a glorious beacon of light
Re: Threading?

The super(String) invocation just calls the CommandGroup's constructor (which is a Command object itself) that takes a string parameter. This parameter sets the name to associate with the command. It is not required (the default constructor will) work.

Setting the name on the Command objects can sometimes be useful when debugging. For example, if you add the line after your shooter subsystem is created, the smart dashboard will display the command that is currently active on it:

Code:
SmartDashboard.putData("Shooter", Robot.shooter);
Reply With Quote
  #7   Spotlight this post!  
Unread 11-02-2016, 10:47
fireXtract fireXtract is offline
MegaHertz_Lux
FRC #2847 (Mega Hertz)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: fmt
Posts: 42
fireXtract is an unknown quantity at this point
Re: Threading?

I have tried that and it works quite well! Thanks for the idea. I think in the past I used a thing that would just print the current subsystem but with no useful info like speed or angle. Thanks! I think you helped me also in 2014 with another post. You are a helpful dude.
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 12:38.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi