This article is part of this article. First, please take a look at this.
FIRST At first.
Although I mentioned that it is related to Main, there is a reason (not so much) that it is related to Robot.java. The point is that Robot.java plays the role of Main.
It's a sober and important part.
The most important thing is to ** do not malfunction (unintended behavior) **.
I think the next important thing is ** not to put a load on the robot **.
The robot is doing loop processing. If you write the code normally, if there is some input, it will be in the form of issuing a command to the motor etc. at the moment when the input is input, isn't it? However, this method causes problems (sometimes).
For example ...
Let's implement a place to operate the suspension with a controller!
python
setSpeed(controller.getX());
I want to move the suspension automatically when climbing a step. I have to make various judgments because I move various parts and make it step by step. Add if else to setSpeed ()!
python
setSpeed(controller.getX());
(Omission)
if(controller.is_cimbMode) {
if(is_liftup){
(Omission)
if(is_advance) {
setSpeed(1);
}
}
Here is the first wall. If this is left as it is, the input to the motor will repeat the input from the controller and 1 in a short time.
It doesn't work well in the first place If you do it with a lift, it will put a lot of strain on the robot. (It may be easier to understand if you think of headbanging) Therefore, even if you try to deal with it with if else, it becomes complicated + it becomes quite difficult to understand how the work is done. just like this,,,
python
if(controller.is_climbMode) {
if(is_StopperOn && !is_liftMoving) {
setSpeed(0.3);
Timer.reset();
Timer.start();
}else if(is_liftUp && Timer.get() > 1) {
setSpeed(1);
}else {
setSpeed(0);
}
}else if(controller.hoge) {
if(fuga) {
setSpeed(-0.7);
}else {
setSpeed(0);
}
}else {
setSpeed(controller.getX());
If this is just the suspension, it will be mass-produced in various places ...: wave:
Here I came up with
Let's make various judgments and confirm the situation before moving ...
When. According to the mentor (leader), it's called State Bot
.
・ Controller part ・ Part to climb a step ・ Hoge part It can be divided like this.
It is OK if you decide the priority of the content to be executed and write the processing with high priority later in code
I want some class to fix the situation, so the created class is State
However, it is better to initialize the fields of each loop State
.
This is because a value that has been manipulated once may not change unless it is manipulated again. You can attach it with else etc., but for the time being.
Also, I created a class called Const
to collect constants there.
The merit is ** it is easy to change the value later + it is easy to understand what the value is **
Postscript (2019/3/17): I feel like I forgot something important Basically, the operation will stop when you take your hand off the controller! Even with PID control, be sure to stop when the button is no longer pressed.
Also, the suspension is a stick operation, and the others are button operations.
ʻWrite in a class that inherits the IterativeRobot` class. (The execution is getting better.) Basically, we will override the function of Iterative Robot. (Strictly speaking, the lsrIterativeRobotBase function inherited by IterativeRobot)
You can see the contents by tapping or clicking the triangle. (It seems that IE and Edge cannot be used)
A little about the encoder setDistancePerPulse
.
An encoder is a machine that measures how much a motor rotates, but I will explain that method because it is slightly related to the program. (I think there is a better explanation if you search on the net)
There is a light and a light receiving part in the encoder, and there is a slit type partition with a gap between them at regular intervals, and it counts each time the partition rotates and the light is blocked. Based on the count number, we will estimate how much the robot has moved by multiplying the distance per rotation. The distance per rotation is determined by calculating or actually measuring the gear ratio. It is better to be asked theoretically. Let me omit the method here.
The Robot itself has only objects such as motor drivers, State variables are also summarized here. The meaning of each variable is summarized in each chapter.
variables.java
private State state;
/** Controller
*I made it a form to operate with two.
*/
private XboxController driver, operator;
/** Motors
*Spark on the left and right at your feet(Motor driver)But,
*Talon on the lift(This is also a motor driver), On the arm and on the step
*Victor SP on climbing feet(Motor driver)Declaration because there is
*
*If there is a similar motor driver such as using two motors in one place
*These motor drivers can be grouped together in a class called SpeedController.
*This time we haven't used it because it's physically summarized.
*/
private Spark driveLeft, driveRight;
private Talon liftMotor;
private VictorSP rollerMotor;
private VictorSP climbMotor;
/** Encoder, Gyro
*One encoder for each of the left and right feet and one for the lift(Measure the distance traveled
*The one who gets sick)And the guy who put together his feet.
*gyro(The one who can measure the rotation)Declare
*EncoderGroup is the original class
*/
private Encoder rightDriveEncoder, leftDriveEncoder;
private EncoderGroup driveEncoder;
private Encoder liftEncoder;
private ADXRS450_Gyro gyro;
/** Solenoid
*solenoid(What moves the air cylinder)Declare
*Used to fold your arms, grab a board, or climb a step
*/
private Solenoid armSolenoid, barSolenoid;
private Solenoid climbSolenoid;
/** Compressor
*compressor(The one who collects the air)Declare
*/
private Compressor compressor;
/** Timer for climb
*Timer used when climbing a step
*/
private Timer climbTimer;
/* SubModule
*Module when the robot is roughly divided
*Original class
*/
private Drive drive;
private Lift lift;
private Grabber grabber;
private Climb climb;
//Sensor for line tracing
// 0~3.The voltage rises when there is a 3V white line
//Unfortunately not implemented
//private AnalogInput rightFrontSensor,
// rightBackSensor,
// leftFrontSensor,
// leftBackSensor;
/** Camera
*The one attached to the elevator and the one attached to the frame for climbing the step.
*/
private CameraServer elevatorCamera, frameCamera;
/** NetWorkTable
*To receive the result of image processing
*This is also unimplemented
*/
private NetworkTable networkTable;
State from here
State.java
public enum DriveState {
kManual,
kLineTrace,
kCloseToLine
} //Mode switching: The latter two are not implemented
public DriveState driveState;
public double driveStraightSpeed, driveRotateSpeed; //Controller control value
public double driveStraightSetpoint, driveRotateSetpoint; //PID control target value
public boolean is_drivePIDOn; //Whether to control PID
public boolean is_lineTraceOn; //Whether to line trace
public boolean is_lowInputOn; //Whether to switch to low output mode
State.java
public double liftSpeed; //Controller control value
public double liftSetpoint; //PID control target value
public boolean is_liftPIDOn; //Whether to control PID
State.java
public enum CargoState {
kHold,
kRelease,
kDoNothing
}
public CargoState cargoState; //What to do with cargo
public boolean is_toHoldPanel; //Whether to hold the panel
public boolean is_toRetractArm; //Whether to store the arm
State.java
public enum ClimbSequence {
kDoNothing("kDoNothing"),
kLiftUp("kLiftUp"),
kLocking("kLocking"),
kAdvance("kAdvance"),
kUnlocking("kUnlocking"),
kLiftDown("kLiftDown");
String name;
ClimbSequence(String name) {
this.name = name;
}
} //For details, see the Climb part....String is for debugging
public ClimbSequence climbSequence = ClimbSequence.kDoNothing; //State during automatic climb
public boolean is_autoClimbOn; //Whether you are auto-climbing
public boolean is_lockingClimb; //Whether to put out a stopper
public boolean is_lockedClimb; //Whether the stopper is completely released
public double climbMotorSpeed; //The value of the frame motor at the time of crime
It is a constant. There is no time to enumerate (~~ copy ~~) here as above, so in Japanese.
Roughly divided
·port ** · Field dimensions ** ** ・ Robot dimensions ** ** ・ Other constants **
Four kinds of.
The port is the port where the motor driver etc. is stuck in roboRIO (Roborio).
According to this rule, the size of the field is the height at which the ball is put.
The dimensions of the robot may be Distance per pulse of encoder or a numerical value related to the robot.
Other constants are dead zone and PID coefficient.
I think it's easier to manage if you divide it roughly.
Automatic control for the first 15 seconds. It works fully automatically every year, but for some reason this year it is possible to control the controller using a camera. It's called Sandstorm ...
We used a camera to control the controller. All the processing is the same as Teleop, or rather, it calls teleopPeriodic ()
.
LAST Finally. Next, before we talk about undercarriage, let's talk about PID control.
Then!
Previous article ⇒ FIRST Next article ⇒ About PID control
Recommended Posts