Go to Post For me, this is the most powerful message of FIRST, that people can come together and work together to achieve so much, and leave old rivalries, grudges, and hard feelings behind. When people talk about culture change, this is what I hope for. - Aren Siekmeier [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 02-18-2016, 05:56 PM
SandySandySand SandySandySand is offline
Registered User
AKA: Chayanne
FRC #2560 (Robodog)
Team Role: Programmer
 
Join Date: Feb 2016
Rookie Year: 2015
Location: Missouri
Posts: 1
SandySandySand is an unknown quantity at this point
Gyro Value to Motor-Need Help

Hello there, I am a first year programmer with my team and we are working in Java this year, for the first time.(We are using Command-Based, instead of going for the Iterative Robot API.) We have recently looked into using a gyro for this year's autonomous mode and are having trouble. We are able to get a reading of the angle, but no matter what we try we can not modify the motor speed using this newly found angle we have. I have included the code we are using. We have tried 2 different methods to fix this problem. (The first method the code that we have commented out.) Any help is appreciated. Thank you, friends.

Code:
 protected void execute() {
    	//double heading = Robot.gyro.getRawAngle();
        //double motorPower = getSafeTan(heading);
        //Robot.drivetrain.arcadeDrive(0, motorPower);
    	double correction = 0.03;
    	double a =Robot.gyro.getRawAngle()*correction;
    	Robot.drivetrain.drive(0, a);
    }
Code:
public double getSafeTan(double heading)
    {
    	double safeAngle = heading / 45.0;
    	//now safeAngle can be NaN or -56 or some crazy useless number. 
    	//We have elected to just attempt basic corrections in that case.
    	if(safeAngle > 1)
    	{
    		safeAngle = 1;
    	}
    	
    	if(safeAngle < -1)
    	{
    		safeAngle = -1;
    	}
    	
    	if(safeAngle > 1 || safeAngle < -1)
    	{
    		safeAngle = 0;
    	}
    	
    	return safeAngle;
    }
Reply With Quote
  #2   Spotlight this post!  
Unread 02-19-2016, 01:14 AM
mehnadnerd mehnadnerd is offline
Registered User
AKA: Brendan
FRC #1458 (Red Tie Robotics)
Team Role: Programmer
 
Join Date: Feb 2016
Rookie Year: 2009
Location: Danville
Posts: 5
mehnadnerd is an unknown quantity at this point
Re: Gyro Value to Motor-Need Help

I don't see anything obviously wrong. Looking at your code, I don't think it will correct for NaN errors though. By outputting your values to SmartDashboard with code like
Code:
SmartDashboard.putNumber("Raw Gyro Angle",Robot.gyro.getRawAngle())
, you can see what is going on.
Reply With Quote
  #3   Spotlight this post!  
Unread 02-19-2016, 02:45 AM
mmaunu's Avatar
mmaunu mmaunu is offline
Registered User
FRC #2485 (W.A.R. Lords)
Team Role: Mentor
 
Join Date: Mar 2013
Rookie Year: 2010
Location: San Diego, CA
Posts: 86
mmaunu is a jewel in the roughmmaunu is a jewel in the roughmmaunu is a jewel in the roughmmaunu is a jewel in the rough
Re: Gyro Value to Motor-Need Help

When you first start up, your gyro angle might be zero because that is what it defaults to typically. So if you get your gyro angle and multiply by your .03 you get 0 for motor power. Instead of multiplying the gyros angle by some number like .03, typically you want to subtract the difference between a desired angle and the gyro angle and then multiply by that .03. For example, if you wanted to turn 90 degrees, you would take .03 times (90 - gyro.getAngle()). After finding this product, you might want to check to see if it is greater than 1 and then set it equal to 1 if it is.
__________________
2014 Las Vegas (Winners with 987, 2478; Excellence in Engineering)
2014 San Diego (Finalists with 987, 3250; Quality Award)
2013 Inland Empire (Winners with 1538, 968; Excellence in Engineering Award)
2013 San Diego (Finalists with 2984, 4322; Creativity Award)
2012 Las Vegas (Finalists with 2034, 3187; Quality Award)
Reply With Quote
  #4   Spotlight this post!  
Unread 02-19-2016, 04:42 AM
pblankenbaker pblankenbaker is offline
Registered User
FRC #0868
 
Join Date: Feb 2012
Location: Carmel, IN, USA
Posts: 102
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: Gyro Value to Motor-Need Help

It looks to me that you are in the process of creating a command that will rotate you robot a fixed amount and then stop and that you want to set the power used for the turn based on how far away you are from your final resting place.

This is often done with a PIDController and it appears to me you are on your way to making your own custom PIDController that uses just the "P" (proportional constant that you currently have set to 0.03).

Some general comments:
  • As mmaunu pointed out, you will want to compute the error (how far off you are from the final target) and use that value when determining the power to apply.
  • Make certain that your command's constructor requires() your drivetrain subsystem (I'm assuming that the drivetrain variable you referenced is a subsystem). If you fail to do this, expect nothing or strange things to happen when your command is run as other commands will likely be changing the drive power settings at the same time.
  • In your initialize() method, determine the final angle you expect your robot to end up at when done.
  • In your execute() method, determine the output power based on how far away you are from the final target point.
  • You may need to add a minimum power check (if your robot stops because the power output gets too low before reaching the target).
  • Don't forget to stop your motors in your end() and interrupted() methods.
You may find that you have "bounce" or "wiggle" as this approach is computing power output based purely as a proportion of the error. At some point in time, you may want to investigate the use of the PIDController class. It takes a bit of time to wrap your head around it, but it automates much of this process and the additional components it provides can make for much smoother operation.

Here is some rough code which demonstrates the above concepts.

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

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

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

public class RotateCommand extends Command {

	// Proportional constant to compute output power based on error (P of PID)
	private static final double P = 0.03;

	// What is the maximum power setting you want to limit your output to when
	// rotating
	private static final double MAX_POWER = 1.0;

	// How close we need to be to target angle to consider ourselves done
	private static final double TOLERANCE = 3.0;

	// How far to rotate
	private double relativeRotation;

	// Current target angle we are attempting to rotate to
	private double targetAngle;

	/**
	 * Construct a new instance to of the command to rotate a specific number of
	 * degrees.
	 * 
	 * @param relativeRotation
	 *            How many degrees to rotate (pass positive values for clockwise
	 *            rotation and negative for counter clockwise).
	 */
	public RotateCommand(double relativeRotation) {
		this.relativeRotation = relativeRotation;
		targetAngle = 0;

		// IMPORTANT! Do not leave this out! This command's constructor
		// MUST require the drive subsystem in order to control it. If
		// you skip this step, expect your robot to jitter or do nothing
		// when this command is run as other commands will also likely
		// be sending output to the drive motors
		requires(Robot.drivetrain);
	}

	@Override
	protected void initialize() {
		// Compute the angle we want to end up at when we are done
		targetAngle = Robot.gyro.getAngle() + relativeRotation;
	}

	@Override
	protected void execute() {
		// Determine how far off we are from where we want to be
		double error = computeError();

		// Compute power output as a proportion of the error (as
		// we get close to desired angle, power goes to 0)
		double power = error * P;

		// Make sure power applied is within range of [-MAX_POWER, +MAX_POWER]
		power = Math.max(-MAX_POWER, Math.min(+MAX_POWER, power));

		// NOTE: You may find that you need a MIN_POWER value as well (if
		// you robot stops before making all the way to the target angle)

		// Invoke subsystem command to apply computed rotation power
		Robot.drivetrain.drive(0, power);
	}

	/**
	 * Compute how far away we are from where we want to be.
	 * 
	 * @return Negative degrees if we need to rotate counter clockwise and
	 *         positive values if we need to rotate clockwise.
	 */
	private double computeError() {
		double error = targetAngle - Robot.gyro.getAngle();
		return error;
	}

	@Override
	protected boolean isFinished() {
		// Done once we have rotated enough that our error is in range
		double error = computeError();
		boolean done = (Math.abs(error) <= TOLERANCE);
		return done;
	}

	@Override
	protected void end() {
		// Turn off motors when we are done
		Robot.drivetrain.drive(0, 0);
	}

	@Override
	protected void interrupted() {
		// Do normal clean up (turn off motors)
		end();
	}

}

Last edited by pblankenbaker : 02-19-2016 at 05:20 AM.
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 08:59 AM.

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