Go to Post I will test first 'cause you cannot learn unless you break something first! - Andy Brockway [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 06-02-2015, 14:59
anthonygraff24 anthonygraff24 is offline
Registered User
FRC #2872 (CyberCats)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Long Island
Posts: 38
anthonygraff24 is an unknown quantity at this point
Slowing down the drive motors

My team is using the standard gearbox for our drive train and with two motors on each side the wheels move way too fast. I'm using the standard tank drive code with two joysticks for driving. The way it is now, unless the joystick is barely pushed forward the robot kindof goes out of control, there is a lot of torque, and the robot shakes too much for comfort. Is there a way to code the robot so that I can still use a standard tank drive but slow the motors down? I hope I'm being clear enough as to what the problem is but I can clarify if I'm not <3
Reply With Quote
  #2   Spotlight this post!  
Unread 06-02-2015, 15:00
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is offline
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,715
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: Slowing down the drive motors

Quote:
Originally Posted by anthonygraff24 View Post
My team is using the standard gearbox for our drive train and with two motors on each side the wheels move way too fast. I'm using the standard tank drive code with two joysticks for driving. The way it is now, unless the joystick is barely pushed forward the robot kindof goes out of control, there is a lot of torque, and the robot shakes too much for comfort. Is there a way to code the robot so that I can still use a standard tank drive but slow the motors down? I hope I'm being clear enough as to what the problem is but I can clarify if I'm not <3
Can you post your code so I can see how you are implementing the drive code currently? Please use code tags when doing this. To use a code tag place a [/code] at the end of the code and a [code] at the beginning.
Reply With Quote
  #3   Spotlight this post!  
Unread 06-02-2015, 15:09
gpetilli gpetilli is offline
Registered User
FRC #1559
 
Join Date: Jan 2009
Location: Victor, NY
Posts: 285
gpetilli is a name known to allgpetilli is a name known to allgpetilli is a name known to allgpetilli is a name known to allgpetilli is a name known to allgpetilli is a name known to all
Re: Slowing down the drive motors

There are several ways to slow it down in software. When you create the joysticks, you can specify to square the inputs, which helps give more sensitivity near zero commands. Other methods of changing the max voltage output or the gain do hurt the performance of the motors.

One mechanical method to get more control is to get new CIM gears from VEX - if you have 14T, they sell a 13T and if you are using a 12T, they sell an 11T. This will only give you a 10% reduction in top speed, but it will improve overall performance because the CIM motor is rotating faster for the same robot velocity. There are other threads that explain the difference better.
Reply With Quote
  #4   Spotlight this post!  
Unread 06-02-2015, 15:39
anthonygraff24 anthonygraff24 is offline
Registered User
FRC #2872 (CyberCats)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Long Island
Posts: 38
anthonygraff24 is an unknown quantity at this point
Re: Slowing down the drive motors

Quote:
Originally Posted by notmattlythgoe View Post
Can you post your code so I can see how you are implementing the drive code currently? Please use code tags when doing this. To use a code tag place a [/code] at the end of the code and a [code] at the beginning.
Code:
package org.usfirst.frc.team2872.robot;

import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Jaguar;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Talon;
import edu.wpi.first.wpilibj.Victor;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;

/**
 * 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.
 */
public class Robot extends IterativeRobot {
	RobotDrive myRobot;
	Joystick stick1;
	Joystick stick2;
	int autoLoopCounter;
	Victor Winch = new Victor(2);
	
    /**
     * This function is run when the robot is first started up and should be
     * used for any initialization code.
     */
    public void robotInit() {
    	myRobot = new RobotDrive(0,1);
    	stick1 = new Joystick(0);
    	stick2 = new Joystick(1);
    	Winch.set(-.15);
    }
    
    /**
     * This function is run once each time the robot enters autonomous mode
     */
    public void autonomousInit() {
    	autoLoopCounter = 0;
    }

    /**
     * This function is called periodically during autonomous
     */
    public void autonomousPeriodic() {
    	if(autoLoopCounter < 100) //Check if we've completed 100 loops (approximately 2 seconds)
		{
			myRobot.drive(-0.5, 0.0); 	// drive forwards half speed
			autoLoopCounter++;
			} else {
			myRobot.drive(0.0, 0.0); 	// stop robot
		}
    }
    
    /**
     * This function is called once each time the robot enters tele-operated mode
     */
    public void teleopInit(){
    	 Winch.set(-.15);
    }

    /**
     * This function is called periodically during operator control
     */
    
    
    public void teleopPeriodic() {
        myRobot.tankDrive(stick1,stick2);
        Winch.set(-.15);
        if(stick1.getRawButton(2))
        	Winch.set(.05);
        if(stick1.getRawButton(3))
        	Winch.set(-.5);
    }
    
    /**
     * This function is called periodically during test mode
     */
    public void testPeriodic() {
    	LiveWindow.run();
    }
    
}
Reply With Quote
  #5   Spotlight this post!  
Unread 06-02-2015, 15:45
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is offline
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,715
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: Slowing down the drive motors

Quote:
Originally Posted by anthonygraff24 View Post
Code:
package org.usfirst.frc.team2872.robot;

import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Jaguar;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Talon;
import edu.wpi.first.wpilibj.Victor;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;

/**
 * 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.
 */
public class Robot extends IterativeRobot {
	RobotDrive myRobot;
	Joystick stick1;
	Joystick stick2;
	int autoLoopCounter;
	Victor Winch = new Victor(2);
	
    /**
     * This function is run when the robot is first started up and should be
     * used for any initialization code.
     */
    public void robotInit() {
    	myRobot = new RobotDrive(0,1);
    	stick1 = new Joystick(0);
    	stick2 = new Joystick(1);
    	Winch.set(-.15);
    }
    
    /**
     * This function is run once each time the robot enters autonomous mode
     */
    public void autonomousInit() {
    	autoLoopCounter = 0;
    }

    /**
     * This function is called periodically during autonomous
     */
    public void autonomousPeriodic() {
    	if(autoLoopCounter < 100) //Check if we've completed 100 loops (approximately 2 seconds)
		{
			myRobot.drive(-0.5, 0.0); 	// drive forwards half speed
			autoLoopCounter++;
			} else {
			myRobot.drive(0.0, 0.0); 	// stop robot
		}
    }
    
    /**
     * This function is called once each time the robot enters tele-operated mode
     */
    public void teleopInit(){
    	 Winch.set(-.15);
    }

    /**
     * This function is called periodically during operator control
     */
    
    
    public void teleopPeriodic() {
        myRobot.tankDrive(stick1,stick2);
        Winch.set(-.15);
        if(stick1.getRawButton(2))
        	Winch.set(.05);
        if(stick1.getRawButton(3))
        	Winch.set(-.5);
    }
    
    /**
     * This function is called periodically during test mode
     */
    public void testPeriodic() {
    	LiveWindow.run();
    }
    
}
Change this line:
Code:
myRobot.tankDrive(stick1,stick2);
to this:
Code:
myRobot.tankDrive(stick1.getY() * 0.5, stick2.getY() * 0.5);
Then change the 0.5 to some scalar value depending on how much you want to scale it.
Reply With Quote
  #6   Spotlight this post!  
Unread 06-02-2015, 15:51
anthonygraff24 anthonygraff24 is offline
Registered User
FRC #2872 (CyberCats)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Long Island
Posts: 38
anthonygraff24 is an unknown quantity at this point
Re: Slowing down the drive motors

Quote:
Originally Posted by notmattlythgoe View Post
Change this line:
Code:
myRobot.tankDrive(stick1,stick2);
to this:
Code:
myRobot.tankDrive(stick1.getY() * 0.5, stick2.getY() * 0.5);
Then change the 0.5 to some scalar value depending on how much you want to scale it.
Awesome. Thank you so much!
Reply With Quote
  #7   Spotlight this post!  
Unread 06-02-2015, 15:56
cstelter cstelter is offline
Programming Mentor
AKA: Craig Stelter
FRC #3018 (Nordic Storm)
Team Role: Mentor
 
Join Date: Apr 2012
Rookie Year: 2012
Location: Mankato, MN
Posts: 77
cstelter will become famous soon enough
Re: Slowing down the drive motors

Quote:
Originally Posted by notmattlythgoe View Post
Change this line:
Code:
myRobot.tankDrive(stick1,stick2);
to this:
Code:
myRobot.tankDrive(stick1.getY() * 0.5, stick2.getY() * 0.5);
Then change the 0.5 to some scalar value depending on how much you want to scale it.
If your joystick has a throttle (any knob/lever that can be set and will stay at a value), you can read that value for the 0.5's above. A bit of math may be required-- the Extreme 3d our team uses goes -1 at the up position (what we think of as full throttle) and +1 at the bottom end so we use

double throttle=(-1*stick.getThrottle() + 1)/2;

This gives us a value between 0 and 1 depending on where the throttle is.

Depending on your stick, you may need to call getZ or some other mapping if you have a throttle. I can't say for sure-- we've only used the one joystick with this year's software.
Reply With Quote
  #8   Spotlight this post!  
Unread 06-02-2015, 16:19
PAR_WIG1350's Avatar
PAR_WIG1350 PAR_WIG1350 is offline
Registered User
AKA: Alan Wells
FRC #1350 (Rambots)
Team Role: Alumni
 
Join Date: Dec 2009
Rookie Year: 2009
Location: Rhode Island
Posts: 1,188
PAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond reputePAR_WIG1350 has a reputation beyond repute
Re: Slowing down the drive motors

If you raise the stick values to a power, instead of multiplying by a constant, you might be able to get more control at low speed without reducing the maximum speed. Typically, for this application, the value is squared or cubed.
Since all values are between -1 and 1, this actually reduces the value at all points. Just be careful about squaring negatives, you need to preserve the sign somehow.
__________________
Reply With Quote
  #9   Spotlight this post!  
Unread 06-02-2015, 16:21
GeeTwo's Avatar
GeeTwo GeeTwo is offline
Technical Director
AKA: Gus Michel II
FRC #3946 (Tiger Robotics)
Team Role: Mentor
 
Join Date: Jan 2014
Rookie Year: 2013
Location: Slidell, LA
Posts: 3,574
GeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond reputeGeeTwo has a reputation beyond repute
Re: Slowing down the drive motors

Quote:
Originally Posted by notmattlythgoe View Post
Change this line:
Code:
myRobot.tankDrive(stick1,stick2);
to this:
Code:
myRobot.tankDrive(stick1.getY() * 0.5, stick2.getY() * 0.5);
Then change the 0.5 to some scalar value depending on how much you want to scale it.
A simple way to still allow full top speed but give fine control at low speeds is to square the magnitude. You'll get 1/4 speed at half throw on your joystick, and full speed at full throw:

Code:
myRobot.tankDrive(stick1.getY() * Math.abs(stick1.getY()),
stick2.getY() * Math.abs(stick2.getY());
__________________

If you can't find time to do it right, how are you going to find time to do it over?
If you don't pass it on, it never happened.
Robots are great, but inspiration is the reason we're here.
Friends don't let friends use master links.
Reply With Quote
  #10   Spotlight this post!  
Unread 06-02-2015, 16:35
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is offline
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,715
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: Slowing down the drive motors

Quote:
Originally Posted by GeeTwo View Post
A simple way to still allow full top speed but give fine control at low speeds is to square the magnitude. You'll get 1/4 speed at half throw on your joystick, and full speed at full throw:

Code:
myRobot.tankDrive(stick1.getY() * Math.abs(stick1.getY()),
stick2.getY() * Math.abs(stick2.getY());
Correct. Only if you don't want to limit your top speed.
Reply With Quote
  #11   Spotlight this post!  
Unread 06-02-2015, 19:53
cstelter cstelter is offline
Programming Mentor
AKA: Craig Stelter
FRC #3018 (Nordic Storm)
Team Role: Mentor
 
Join Date: Apr 2012
Rookie Year: 2012
Location: Mankato, MN
Posts: 77
cstelter will become famous soon enough
Re: Slowing down the drive motors

Quote:
Originally Posted by notmattlythgoe View Post
Quote:
Originally Posted by GeeTwo View Post
A simple way to still allow full top speed but give fine control at low speeds is to square the magnitude. You'll get 1/4 speed at half throw on your joystick, and full speed at full throw:

Code:
myRobot.tankDrive(stick1.getY() * Math.abs(stick1.getY()),
stick2.getY() * Math.abs(stick2.getY());
Correct. Only if you don't want to limit your top speed.
Hmm. Unless I'm reading the RobotDrive code wrong:
Code:
public class RobotDrive implements MotorSafety {
    ...
    public void tankDrive(double leftValue, double rightValue, boolean squaredInputs) {

        if(!kTank_Reported) {
            UsageReporting.report(tResourceType.kResourceType_RobotDrive, getNumMotors(), tInstances.kRobotDrive_Tank);
            kTank_Reported = true;
        }

        // square the inputs (while preserving the sign) to increase fine control while permitting full power
        leftValue = limit(leftValue);
        rightValue = limit(rightValue);
        if(squaredInputs) {
            if (leftValue >= 0.0) {
                leftValue = (leftValue * leftValue);
            } else {
                leftValue = -(leftValue * leftValue);
            }
            if (rightValue >= 0.0) {
                rightValue = (rightValue * rightValue);
            } else {
                rightValue = -(rightValue * rightValue);
            }
        }
        setLeftRightMotorOutputs(leftValue, rightValue);
    }
    ...
    public void tankDrive(double leftValue, double rightValue) {
        tankDrive(leftValue, rightValue, true);
    }
It looks like tankDrive(double,double) squares the inputs by default. So doing what is suggested will ^4 the inputs. It will certainly have the advertised effect either way. But if your robot won't really move until you apply 0.4 for example, you have to get your joystick all the way out to ~0.8 before it moves.

The best plan is probably to do as Ether suggested and go piece-wise linear. Perhaps first find your sweet-spot for operating the robot (say 0.4-0.7) map your deadzone to ~10-20% less than the minimum power to drive your robot and then map 0.9 to be the maximum you want to drive and then map 1.0 to 1.0.

There are many ways to code an OI...

I'll mention that what our team sees as a way to not lose motor strength and yet drive very slowly is to use a feedback encoder system so you are asking the wheels to go 0.4 of their fastest rotation rather than 0.4 constant output voltage. This way a PID can apply full power to the wheels to get it going but quickly cut back power as you reach your requested rate. If you are moving very slowly and something gets in your way, you can apply the full power of your cims to overcome and if your wheels happen to slip the PID would likely compensate back down to the maximum power possible without overcoming friction.
Reply With Quote
  #12   Spotlight this post!  
Unread 10-02-2015, 13:50
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is offline
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,715
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: Slowing down the drive motors

Quote:
Originally Posted by cstelter View Post
Hmm. Unless I'm reading the RobotDrive code wrong:
Code:
public class RobotDrive implements MotorSafety {
    ...
    public void tankDrive(double leftValue, double rightValue, boolean squaredInputs) {

        if(!kTank_Reported) {
            UsageReporting.report(tResourceType.kResourceType_RobotDrive, getNumMotors(), tInstances.kRobotDrive_Tank);
            kTank_Reported = true;
        }

        // square the inputs (while preserving the sign) to increase fine control while permitting full power
        leftValue = limit(leftValue);
        rightValue = limit(rightValue);
        if(squaredInputs) {
            if (leftValue >= 0.0) {
                leftValue = (leftValue * leftValue);
            } else {
                leftValue = -(leftValue * leftValue);
            }
            if (rightValue >= 0.0) {
                rightValue = (rightValue * rightValue);
            } else {
                rightValue = -(rightValue * rightValue);
            }
        }
        setLeftRightMotorOutputs(leftValue, rightValue);
    }
    ...
    public void tankDrive(double leftValue, double rightValue) {
        tankDrive(leftValue, rightValue, true);
    }
It looks like tankDrive(double,double) squares the inputs by default. So doing what is suggested will ^4 the inputs. It will certainly have the advertised effect either way. But if your robot won't really move until you apply 0.4 for example, you have to get your joystick all the way out to ~0.8 before it moves.

The best plan is probably to do as Ether suggested and go piece-wise linear. Perhaps first find your sweet-spot for operating the robot (say 0.4-0.7) map your deadzone to ~10-20% less than the minimum power to drive your robot and then map 0.9 to be the maximum you want to drive and then map 1.0 to 1.0.

There are many ways to code an OI...

I'll mention that what our team sees as a way to not lose motor strength and yet drive very slowly is to use a feedback encoder system so you are asking the wheels to go 0.4 of their fastest rotation rather than 0.4 constant output voltage. This way a PID can apply full power to the wheels to get it going but quickly cut back power as you reach your requested rate. If you are moving very slowly and something gets in your way, you can apply the full power of your cims to overcome and if your wheels happen to slip the PID would likely compensate back down to the maximum power possible without overcoming friction.
You are absolutely correct, the tankDrive(x, y) method does square the input values already. So squaring them again would probably make the controls worse in this case.

Last edited by notmattlythgoe : 10-02-2015 at 13:59.
Reply With Quote
  #13   Spotlight this post!  
Unread 06-02-2015, 18:42
Ether's Avatar
Ether Ether is offline
systems engineer (retired)
no team
 
Join Date: Nov 2009
Rookie Year: 1969
Location: US
Posts: 8,043
Ether has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond reputeEther has a reputation beyond repute
Re: Slowing down the drive motors



Arguably the simplest and most flexible way to contour your joystick's output is to use a piecewise linear function for each axis.

Here's a simple example.



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 10:53.

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