|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools |
Rating:
|
Display Modes |
|
|
|
#1
|
||||
|
||||
|
May I Please Have Some Help?
Hey guys, I am a part of this club in my school, and we are taking place in the 2014 robotics competition. We can not test our code yet because we are waiting on our build team to finalize a design. However, we have some code written and were wondering if it would work in theory.
Thank you all so much, FriendzonedJim Code:
/*----------------------------------------------------------------------------*/
/* Copyright (c) FIRST 2008. All Rights Reserved. */
/* Open Source Software - may be modified and shared by FRC teams. The code */
/* must be accompanied by the FIRST BSD license file in the root directory of */
/* the project. */
/*----------------------------------------------------------------------------*/
package edu.wpi.first.wpilibj.templates;
import edu.wpi.first.wpilibj.Encoder;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.Relay;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Talon;
import edu.wpi.first.wpilibj.Timer;
/**
* 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 mainClass extends IterativeRobot {
/**
* This function is run when the robot is first started up and should be
* used for any initialization code.
*/
double angle = 41.6;
boolean ifLightButtonPushed = false;
Joystick driveStick = new Joystick(1);
Joystick controlStick = new Joystick(2);
RobotDrive mainDrive = new RobotDrive(1,2,3,4);
Talon pickupTalon = new Talon(3);
Talon launchTalon = new Talon(4);
Relay ledRing = new Relay(1);
Encoder pickupEncoder = new Encoder(1,2);
Encoder elasticEncoder = new Encoder(3,4);
public void robotInit() {
pickupEncoder.start();
}
/**
* This function is called periodically during autonomous
*/
public void autonomousPeriodic() {
}
public void autonomousContinuous() {
mainDrive.setSafetyEnabled(false);
mainDrive.drive(0.5,0.0);
Timer.delay(2.0);
mainDrive.drive(0.0,0.0);
}
/**
* This function is called periodically during operator control
*/
public void teleopPeriodic() {
mainDrive.arcadeDrive(driveStick);
if (controlStick.getRawButton(3)) {
if (pickupEncoder.get() < angle) {
pickupTalon.set(.5);
} else {
pickupTalon.set(0.0);
}
} else {
pickupTalon.set(0.0);
}
if (controlStick.getRawButton(1)) {
launchTalon.set(0.5);
} else {
launchTalon.set(0.0);
}
if (controlStick.getRawButton(4)) {
ifLightButtonPushed = !(ifLightButtonPushed);
}
if (ifLightButtonPushed) {
ledRing.set(Relay.Value.kOff);
}
}
/**
* This function is called periodically during test mode
*/
public void testPeriodic() {
}
}
|
|
#2
|
||||||
|
||||||
|
Re: May I Please Have Some Help?
Here's a few notes, based on what it seems like I would want to code to do. If you described what you wanted the robot to do, it would be much easier to review the code.
You're using PWM 3 & 4 for both RobotDrive and your Talons. This will crash immediately. elasticEncoder is never started or used. ledRing is never turned on. encoders do not necessarily return an angle directly. With the current code, the Pickup Talon will be on until the encoder counts 42 ticks. If you have a 250 count encoder, this will be about 60 degrees. If you have a 360 count encoder, you don't have to worry about it. There isn't a way to move the pickup in the opposite direction. The encoder will start at 0 when the robot is turned on. If your pickup isn't always in the same position when you turn on, you won't get the results you want The autonomous won't run. autonomousContinuous isn't called by the iterative framework anymore. The equivalent is autonomousPeriodic. However, you can't have delays in Periodic methods. Instead, save a time variable in autonomousInit, and then check in autonomousPeriodic if the desired time has elapsed. Last edited by Joe Ross : 28-01-2014 at 20:48. |
|
#3
|
||||
|
||||
|
Re: May I Please Have Some Help?
@Joe Ross thanks for the tip about the talons.. I'll be sure to change that. The LEDRing is controlled by a button on a joystick. This is the encoder we are using: http://www.andymark.com/product-p/am-0791.htm which looks like it has 360 steps. Our pickup system is like the robot in 3 days build except we are using a cim to control the angle instead of pneumatics. Thus, we are planning for it to start straight up, and then all we need to do is rotate it down a certain amount at the beginning of the match and leave it there.
Thanks for the autonomous tip. There is not a lot of information out there about autonomous mode with the iterativerobot template. The elastic encoder is going to measure how tightly our surgical tubing is winded up for our launch system. I have not implemented it because we are still not sure on the details of how our launch system works. @Woolly our pickup system is not an arm, but I will definitely look into how PID systems work. Last edited by FriendzonedJim : 28-01-2014 at 21:51. |
|
#4
|
|||
|
|||
|
Re: May I Please Have Some Help?
This is not a programming tip exactly. Unless your pickup is much more rugged than I think it might be, driving around with it extended is somewhat like leading with your chin in boxing. Having the pickup extend only when directly involved with the ball was deemed highly desirable for the preservation of the pickup frame. YMMV.
|
|
#5
|
|||
|
|||
|
Re: May I Please Have Some Help?
A quick review: I'm not sure, but I think you may need a time delay in your teleopPeriodic() function, and perhaps a while statement wrapping the whole thing.
I noticed that your pickup motor speed, at 50%, may be a bit high to maintain control of the ball. I'd start smaller, and build it up when the bot is built. Lastly, think about how you're using the pickup encoder. It's not giving you an angle with the get() method, it's giving you a count, and it's an int. Angle is a double. While that will work in Java, of course, unless you're very lucky with the robot gears, the count will not be the same as the angle. If I see something else, I'll let you know. |
|
#6
|
||||||
|
||||||
|
Re: May I Please Have Some Help?
Quote:
|
|
#7
|
||||
|
||||
|
Re: May I Please Have Some Help?
If you are trying to control a pickup arm to an angle, you will need to implement a PID controller that will requires understanding the PID class, or knowing enough about PID to slap together your own rudimentary solution.
EX. (I'm a Labview/Python programmer, don't expect this to be exact) Code:
double error = 0; //outside loop
double integrated_error = 0; // outside loop
double proportional_coeff = .025; //an example P value for a PI control (~1/41.6,)
double integral_coeff = 00025; //an example I value PI control
double angle = 41.6;
double enc_counts_to_angle_conv = PUT A VALUE HERE ;(Your encoder's counts per revolution / 360)
double pickup_power = 0; \\initialize pickup to a safe value
public static void Timer(); \\sets up a timer because the PI controller needs double loop_time = 0;
double last_loop_total = 0;
/** inside loop (teleop/autonomous periodic) */
start()
public static void start(); //start the timer
pickup_power = proportional_coeff * error + integral_coeff * integrated_error;
if (pickup_power >= 1) { pickup_power = 1;}
pickupTalon.set(pickup_power);
error = pickupEncoder.get() * enc_counts_to_angle_conv - angle; //get error in degrees
loop_time = ( public void get() - last_loop_total ) / 1000;
last_loop_get = public void get();
integrated_error += error * loop_time ;
In PID language, your angle is your setpoint. I didn't do it in this code, but to switch between having your arm in or out you would switch your setpoint between 0 and 41.6. PID documentation: http://robotics.francisparker.org/ja...ontroller.html Note that your integrated error will be based on a 50ms loop, lower your I coeff accordingly. Also, I forgot, you need to reset your integrated error once in a while. Like when you're within a certain tolerance of your setpoint. http://robotics.francisparker.org/ja...ibj/Timer.html Also, here's the timer class I was using for this example. Last edited by Woolly : 28-01-2014 at 21:26. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|