[World's Largest Junior and Senior High School Robot Contest] About the program at FRC ~ Main related ~

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.

Program policy

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.

To do

ʻ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)

Main functions to override

You can see the contents by tapping or clicking the triangle. (It seems that IE and Edge cannot be used)

public void RobotInit() Initialization part when the robot is started The constructor of `Robot` doesn't change much. Assign an instance to a variable, set an initial value, or start a camera capture.

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.

public void TeleopInit() Initialization part when controlling the controller We didn't use it.
public void TeleopPeriodic() Function part at the time of controller control Most of the necessary information is described in [Program Policy](#Program Policy). Crime will be introduced in [Climb Article]().
public void autonomousInit() Initialization part when autonomous We didn't use it
public void autonomousPeriodic() Function part when autonomous This year is during Sand Storm. You are calling TeleopPeriodic ().

Variable list of class Robot (required)

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 that Robot itself has

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

Drive related
Undercarriage. All the tires are controlled 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
Lift relationship
The one that lifts the arm (described later). There is only height control.

State.java


    public double liftSpeed;    //Controller control value
    public double liftSetpoint;   //PID control target value
    public boolean is_liftPIDOn;    //Whether to control PID
Arm relationship
A place to grab a ball and shoot it or grab a board and attach it. It's named `Grabber`.

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
Climb relationship
Used for climbing the last step.

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

Contents of Const

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.

About autonomous (about control during Sandstorm)

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

[World's Largest Junior and Senior High School Robot Contest] About the program at FRC ~ Main related ~
[World's Largest Junior and Senior High School Robot Contest] About FRC Program ~ Grabber Related ~
[World's Largest Junior and Senior High School Robot Contest] About FRC Program ~ Lift Related ~
[World's Largest Junior and Senior High School Robot Contest] About FRC Program ~ Terms ~
[World's Largest High School Robot Contest] About FRC Program ~ About PID Control ~
About the program of the world's largest high school student Robocon FRC ~ Climb relations ~
A story of six junior and senior high school students making a service and taking first place in a programming school contest