Go to Post So I thought to myself "Man, I wish I was a part of a large technically minded community... oh... right..." - BordomBeThyName [more]
Home
Go Back   Chief Delphi > CD-Media > Photos
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

photos

papers

everything



Sparto the Waldo

frasnow

By: frasnow
New: 22-03-2011 23:40
Updated: 22-03-2011 23:40
Views: 1844 times


Sparto the Waldo

Sparto is the control system for Team 997's arm. The position of potentiometers on the shoulder and elbow of Sparto are translated by software to the position of the shoulder and elbow of 997's robot. Also included on Sparto are buttons for controlling the gripper and a protected minibot deploy switch. Come check it out at the Autodesk Oregon Regional.

Recent Viewers

  • Guest

Discussion

view entire thread

Reply

23-03-2011 08:26

apalrd


Unread Re: pic: Sparto the Waldo

Now it just needs a mini-rack to score on (maybe with mini-tubes?)



23-03-2011 09:32

MrHance


Unread Re: pic: Sparto the Waldo

Great work!

Do you have a cad drawing or pdf drawings for your design.

In addition, do you also a a schematic of the controls and wiring.

This would be a great tool for any team to use for arm manipulator controls.



23-03-2011 10:45

RyanCahoon


Unread Re: pic: Sparto the Waldo

Quote:
Originally Posted by apalrd View Post
Now it just needs a mini-rack to score on (maybe with mini-tubes?)
Bagels? http://www.chiefdelphi.com/media/photos/36048



23-03-2011 11:57

Geek 2.0


Unread Re: pic: Sparto the Waldo

This makes me soooo happy. Great idea!



23-03-2011 13:00

PaW


Unread Re: pic: Sparto the Waldo

Very cool !!!

Let me guess... you also have a set of red bumpers?



23-03-2011 14:16

fsgond


Unread Re: pic: Sparto the Waldo

We almost did that this year. We had done something similarly in a previous year, and thought that maybe we should do it again. We used pre-set heights for each peg instead.



23-03-2011 15:31

frasnow


Unread Re: pic: Sparto the Waldo

Quote:
Originally Posted by MrHance View Post
Great work!

Do you have a cad drawing or pdf drawings for your design.

In addition, do you also a a schematic of the controls and wiring.

This would be a great tool for any team to use for arm manipulator controls.
Sorry, we don't have CAD or a schematic of it as of right now. You make an excellent point about the value in sharing this information. I can tell you it uses the Cypress I/O board we received in last year's kit. The potentiometers are wired to the analog inputs, and the buttons & minibot switch are connected to the digital inputs. FIRST has made the software for reading these inputs really easy, at least in Java, and probably the other languages.

Quote:
Originally Posted by PaW View Post
Very cool !!!

Let me guess... you also have a set of red bumpers?
The bumpers are hot glued on. We had planned to make bumper covers to match the ones on our robot, but I don't think they got done.



23-03-2011 15:38

dmitch


Unread Re: pic: Sparto the Waldo

How did you code this? We use C++ on our bot and it seems like what you would have to do is set the setpoint of a PID loop to the value of the analog inputs on the model. Could you post the code that you wrote for this? And does it require any programming on the Cypress module?



23-03-2011 15:59

apalrd


Unread Re: pic: Sparto the Waldo

If I were to program it, I would probably:

1. Take the inputs from the Cypress board (in Teleop.vi) and scale them to some sane units (degrees, radians, etc.), probably by taking the volts in, subtracting a known centerpoint (0 would probably be straight out or vertical, you pick but be consistent), and then multiplying the volts from center by a constant.

2. Send the scaled numbers off to another thread to be processed

3. Said other thread would take the units, and lookup the appropriate scaling on this robot (meaning, the competition or practice robot), and take the analog sensors on the robot and scale the inputs to the same units (with the same 0-point)

4. A P-controller would run in said thread, taking numbers of sane units from 1 and sensors of same sane units from 3 and determining the motor output for each joint. I have actually never used anything but P, because I have not yet found the need for any other terms.

If you do a lot of trig processing (maybe for gain scheduling or elsewhere), storing the value in radians makes everything cleaner. If you want to use stored positions (say, for autonomous), you can store them in radians, so if the sensor calibration changes, it doesn't affect any other code.



23-03-2011 20:59

frasnow


Unread Re: pic: Sparto the Waldo

Quote:
Originally Posted by dmitch View Post
How did you code this? We use C++ on our bot and it seems like what you would have to do is set the setpoint of a PID loop to the value of the analog inputs on the model. Could you post the code that you wrote for this? And does it require any programming on the Cypress module?
In the spirit of coopertition and code reviews, here you go. The code could use a few more comments. This didn't require any Cypress module programming other than the standard setup in the FIRST documentation.

Quote:
Originally Posted by apalrd View Post
Take the inputs from the Cypress board (in Teleop.vi) and scale them to some sane units
We scaled them to a percentage.

Code:
public class Arm {
    private CANJaguar m_shoulder;
    private CANJaguar m_elbow;
    private DriverStationEnhancedIO m_enhancedIO;
    private int m_shoulderWaldoChannel;
    private int m_elbowWaldoChannel;
    private double m_shoulderValue = 0;
    private double m_elbowValue = 0;
    
    // This is correct. The down value is greater than the up value on the Waldo.
    private static final double kDownShoulderVoltage = 2.7;
    private static final double kUpShoulderVoltage = 1.3;
    private static final double kRetractedElbowVoltage = 2.8;
    private static final double kExtendedElbowVoltage = 0.9;
    public static final double kDownShoulderPosition = 0.09;
    public static final double kUpShoulderPosition = 0.55;
    public static final double kRetractedElbowPosition = 0.084;
    public static final double kExtendedElbowPosition = 0.665;

    public static final double kElbowMinToBeCollecting = .4;
    public static final double kShoulderMinWhenElbowInCollecting = 0.155;

    private DriverStation m_ds = DriverStation.getInstance();

    public Arm(int shoulderCANDevice, int elbowCANDevice, int shoulderWaldoChannel, int elbowWaldoChannel) {
        try {
            m_shoulder = new CANJaguar(shoulderCANDevice, CANJaguar.ControlMode.kPosition);
            m_shoulder.setPositionReference(CANJaguar.PositionReference.kPotentiometer);
            m_shoulder.setPID(1000, 0, 100);
            m_shoulder.configPotentiometerTurns(1);
            m_shoulder.configSoftPositionLimits(kUpShoulderPosition, kDownShoulderPosition);
            m_shoulder.enableControl();

            m_elbow = new CANJaguar(elbowCANDevice, CANJaguar.ControlMode.kPosition);
            m_elbow.setPositionReference(CANJaguar.PositionReference.kPotentiometer);
            m_elbow.setPID(700, 0, 50);
            m_elbow.configPotentiometerTurns(1);
            m_elbow.configSoftPositionLimits(kExtendedElbowPosition, kRetractedElbowPosition);
            m_elbow.enableControl();
        } catch (CANTimeoutException e) {
            DriverStationPrinter.getInstance().println("CAN Arm Init Error!");
        }
        m_enhancedIO = DriverStation.getInstance().getEnhancedIO();
        m_shoulderWaldoChannel = shoulderWaldoChannel;
        m_elbowWaldoChannel = elbowWaldoChannel;
    }

    private void getValues() {
        try {
            m_shoulderValue = m_enhancedIO.getAnalogIn(m_shoulderWaldoChannel);
            m_shoulderValue -= kDownShoulderVoltage;
            m_shoulderValue /= (kUpShoulderVoltage - kDownShoulderVoltage);
            if (m_shoulderValue < 0) {
                m_shoulderValue = 0;
            }
            if (m_shoulderValue > 1) {
                m_shoulderValue = 1;
            }

            m_elbowValue = m_enhancedIO.getAnalogIn(m_elbowWaldoChannel);
            m_elbowValue -= kRetractedElbowVoltage;
            m_elbowValue /= (kExtendedElbowVoltage - kRetractedElbowVoltage);
            if (m_elbowValue < 0) {
                m_elbowValue = 0;
            }
            if (m_elbowValue > 1) {
                m_elbowValue = 1;
            }
        } catch (DriverStationEnhancedIO.EnhancedIOException e) {
            DriverStationPrinter.getInstance().println("Waldo Pos Read Error!");
        }
    }

    public void update() {
        getValues();
        double dMotorValueShoulder = m_shoulderValue;
        dMotorValueShoulder *= (kUpShoulderPosition - kDownShoulderPosition);
        dMotorValueShoulder += kDownShoulderPosition;

        double dMotorValueElbow = m_elbowValue;
        dMotorValueElbow *= (kExtendedElbowPosition - kRetractedElbowPosition);
        dMotorValueElbow += kRetractedElbowPosition;

        // Make sure that when the elbow is extended to collect that the shoulder stays
        // up enough to prevent the forarm from hitting the front of the robot.
        if ((dMotorValueElbow > kElbowMinToBeCollecting) && (dMotorValueShoulder < kShoulderMinWhenElbowInCollecting)){
            dMotorValueShoulder = kShoulderMinWhenElbowInCollecting;
        }

        try {
            m_shoulder.setX(dMotorValueShoulder);
            m_elbow.setX(dMotorValueElbow);
        } catch (CANTimeoutException e) {
            DriverStationPrinter.getInstance().println("CAN Arm Pos Error!");
        }
    }
    
    /*
     *
     * @param shoulderPosition The position value for the shoulder in motor counts.
     * @param elbowPosition The position value for the elbow in motor counts.
     */
    public void setAutonomousArmPositions(double shoulderPosition, double elbowPosition) {
        if (m_ds.isAutonomous()) {
            // Make sure the shoulder position is in range.
            if (shoulderPosition > kUpShoulderPosition) {
                shoulderPosition = kUpShoulderPosition;
            } else if (shoulderPosition < kDownShoulderPosition) {
                shoulderPosition = kDownShoulderPosition;
            }
            // Make sure the elbow position is in range.
            if (elbowPosition > kExtendedElbowPosition) {
                elbowPosition = kExtendedElbowPosition;
            } else if (elbowPosition < kRetractedElbowPosition) {
                elbowPosition = kRetractedElbowPosition;
            }

            // Set the positions.
            try {
                m_shoulder.setX(shoulderPosition);
                m_elbow.setX(elbowPosition);
            } catch (CANTimeoutException e) {
                DriverStationPrinter.getInstance().println("CAN Auto Arm Pos Error!");
            }
        }
    }

    /**
     * Updates the information on the SmartDashboard.
     */
    public void updateSmartDashboard() {
        try {
            SmartDashboard.log(m_shoulder.getPosition(), "Shoulder Position");
            SmartDashboard.log(m_elbow.getPosition(), "Elbow Position");
        } catch (CANTimeoutException e) {
            DriverStationPrinter.getInstance().println("CAN Get Arm Pos Error!");
        }
    }
}



23-03-2011 22:21

Dustin Shadbolt


Unread Re: pic: Sparto the Waldo

Hey frasnow,

Are you guys going to the Championships?



23-03-2011 22:39

frasnow


Unread Re: pic: Sparto the Waldo

Quote:
Originally Posted by dShad View Post
Hey frasnow,

Are you guys going to the Championships?
No plans yet. We'd need to qualify at the Oregon Regional first.



24-03-2011 06:26

kenavt


Unread Re: pic: Sparto the Waldo

My team had discussed making a control system like this, but we found that we didn't have the time, and a simple gamepad served adequately. However, I'm really glad to see one of these actually have been made! Nice work!



24-03-2011 08:53

4Sig


Unread Re: pic: Sparto the Waldo

wow this is really quite clever



24-03-2011 13:40

Mike Starke


Unread Re: pic: Sparto the Waldo

How bad is the delay from when you make a movement to when the robot executes it? We tried something like this in 2005, but the delay was horrible so we scrapped it.



28-03-2011 18:30

maclaren


Unread Re: pic: Sparto the Waldo

The delay is negligible if the arm is geared properly. Obviously you can move the model faster by hand then the motors on the arm can move it but if you move it in a smooth motion then it mimics the movement perfectly.



04-04-2012 17:11

Aaron691


Unread Re: pic: Sparto the Waldo

very cool would you mind taking some pictures of the side of it. like a picture of how the cypress broad is mounted



view entire thread

Reply
previous
next

Tags

loading ...



All times are GMT -5. The time now is 16:49.

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