【问题标题】:Using an arraylist for a state machine将数组列表用于状态机
【发布时间】:2015-12-14 04:11:40
【问题描述】:

我希望能够将案例添加到枚举变量状态机中,例如数组列表。我这样做是通过创建一个数组列表并使用大小来告诉它有多少个案例并使用 for 循环相应地执行它们。问题是它会在我的方法调用完成之前进入下一个案例。我怎样才能让程序在不使用时间延迟的情况下等待方法完成,因为时间可能因不同情况而异。案例和方法在loop()方法的代码底部。

package com.qualcomm.ftcrobotcontroller.opmodes;

import com.qualcomm.hardware.HiTechnicNxtCompassSensor;
import com.qualcomm.robotcore.eventloop.opmode.OpMode;
import com.qualcomm.robotcore.hardware.DcMotor;
import com.qualcomm.robotcore.hardware.DcMotorController;
import com.qualcomm.robotcore.util.ElapsedTime;

import java.util.ArrayList;

/**
 * Created by Robotics on 12/11/2015.
 */
public class RobotAction extends OpMode {

    //HiTechnicNxtCompassSensor compassSensor;
    //double compassvalue = compassSensor.getDirection();
    double compassvalue;
    double lastcompassvalue;

    DcMotor rightdrive;
    DcMotor leftdrive;
    final double fullpower = 1;

    double angle;
    double distance;

    final double wheelediameter = 4.0;
    final double circumference = wheelediameter * Math.PI;
    final double gearratio = 1;
    final double countsperrotation = 1440;


    double wheelrotations = distance / circumference;
    double motorrotations = wheelrotations * gearratio;
    double encodercounts = motorrotations * countsperrotation;

    int currentpositionright;

    int step;

    ElapsedTime time;

    String status;
    String action;

    public enum RelativePosition {North, NorthEast, East, SouthEast, South, SouthWest, West, NorthWest}
    RelativePosition relativeposition;

    private void Action(double angle, int compassvalue, double encodercounts, RelativePosition relativeposition) {

        action = "running";

        lastcompassvalue = compassvalue;

        switch(relativeposition) {


            case North:
                currentpositionright = rightdrive.getCurrentPosition();

                if (rightdrive.getCurrentPosition() < encodercounts) {
                    rightdrive.setTargetPosition((int) (encodercounts + 1));
                    leftdrive.setTargetPosition((int) (encodercounts + 1));

                    rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                    leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                    rightdrive.setDirection(DcMotor.Direction.REVERSE);
                    rightdrive.setPower(.5);
                    leftdrive.setPower(.5);

                }
                else {
                    rightdrive.setPower(0);
                    leftdrive.setPower(0);
                    rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                }
                break;

            case NorthEast:
                currentpositionright = rightdrive.getCurrentPosition();

                if (compassvalue > lastcompassvalue - (90-angle)) {
                    rightdrive.setDirection(DcMotor.Direction.FORWARD);
                    rightdrive.setPower(fullpower);
                    leftdrive.setPower(fullpower);
                }
                else {
                    if(rightdrive.getCurrentPosition() < encodercounts) {
                        rightdrive.setTargetPosition((int) encodercounts + 1);
                        leftdrive.setTargetPosition((int) encodercounts + 1);

                        rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                        rightdrive.setDirection(DcMotor.Direction.REVERSE);
                        rightdrive.setPower(fullpower);
                        leftdrive.setPower(fullpower);
                    }
                    else {
                        rightdrive.setPower(0);
                        leftdrive.setPower(0);
                        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    }
                }

                break;

            case East:
                currentpositionright = rightdrive.getCurrentPosition();

                if (compassvalue > lastcompassvalue - 90) {
                    rightdrive.setDirection(DcMotor.Direction.FORWARD);
                    rightdrive.setPower(fullpower);
                    leftdrive.setPower(fullpower);
                }
                else {
                    if(rightdrive.getCurrentPosition() < encodercounts) {
                        rightdrive.setTargetPosition((int) encodercounts + 1);
                        leftdrive.setTargetPosition((int) encodercounts + 1);

                        rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                        rightdrive.setDirection(DcMotor.Direction.REVERSE);
                        rightdrive.setPower(fullpower);
                        leftdrive.setPower(fullpower);
                    }
                    else {
                        rightdrive.setPower(0);
                        leftdrive.setPower(0);
                        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    }
                }

                break;

            case SouthEast:
                currentpositionright = rightdrive.getCurrentPosition();

                if (compassvalue > lastcompassvalue - (90+angle)) {
                    rightdrive.setDirection(DcMotor.Direction.FORWARD);
                    rightdrive.setPower(fullpower);
                    leftdrive.setPower(fullpower);
                }
                else {
                    if(rightdrive.getCurrentPosition() < encodercounts) {
                        rightdrive.setTargetPosition((int) encodercounts);
                        leftdrive.setTargetPosition((int) encodercounts);

                        rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                        rightdrive.setDirection(DcMotor.Direction.REVERSE);
                        rightdrive.setPower(fullpower);
                        leftdrive.setPower(fullpower);
                    }
                    else {
                        rightdrive.setPower(0);
                        leftdrive.setPower(0);
                        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    }
                }

                break;

            case South:
                currentpositionright = rightdrive.getCurrentPosition();

                if (compassvalue > lastcompassvalue - 180) {
                    rightdrive.setDirection(DcMotor.Direction.FORWARD);
                    rightdrive.setPower(fullpower);
                    leftdrive.setPower(fullpower);
                }
                else {
                    if(rightdrive.getCurrentPosition() < encodercounts) {
                        rightdrive.setTargetPosition((int) encodercounts + 1);
                        leftdrive.setTargetPosition((int) encodercounts + 1);

                        rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                        rightdrive.setDirection(DcMotor.Direction.REVERSE);
                        rightdrive.setPower(fullpower);
                        leftdrive.setPower(fullpower);
                    }
                    else {
                        rightdrive.setPower(0);
                        leftdrive.setPower(0);
                        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    }
                }

                break;

            case SouthWest:
                currentpositionright = rightdrive.getCurrentPosition();

                if (compassvalue < lastcompassvalue + (90+angle) ) {
                    rightdrive.setPower(fullpower);
                    leftdrive.setDirection(DcMotor.Direction.REVERSE);
                    leftdrive.setPower(fullpower);
                }
                else {
                    if(rightdrive.getCurrentPosition() < encodercounts) {
                        rightdrive.setTargetPosition((int) encodercounts + 1);
                        leftdrive.setTargetPosition((int) encodercounts + 1);

                        rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                        rightdrive.setPower(fullpower);
                        leftdrive.setDirection(DcMotor.Direction.FORWARD);
                        leftdrive.setPower(fullpower);
                    }
                    else {
                        rightdrive.setPower(0);
                        leftdrive.setPower(0);
                        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    }
                }

                break;

            case West:
                currentpositionright = rightdrive.getCurrentPosition();

                if (compassvalue < lastcompassvalue + 90) {
                    rightdrive.setPower(fullpower);
                    leftdrive.setDirection(DcMotor.Direction.REVERSE);
                    leftdrive.setPower(fullpower);
                }
                else {
                    if(rightdrive.getCurrentPosition() < encodercounts) {
                        rightdrive.setTargetPosition((int) encodercounts + 1);
                        leftdrive.setTargetPosition((int) encodercounts + 1);

                        rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                        rightdrive.setPower(fullpower);
                        leftdrive.setDirection(DcMotor.Direction.FORWARD);
                        leftdrive.setPower(fullpower);
                    }
                    else {
                        rightdrive.setPower(0);
                        leftdrive.setPower(0);
                        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    }
                }

                break;

            case NorthWest:
                currentpositionright = rightdrive.getCurrentPosition();

                if (compassvalue < lastcompassvalue + (90-angle)) {
                    rightdrive.setPower(fullpower);
                    leftdrive.setDirection(DcMotor.Direction.REVERSE);
                    leftdrive.setPower(fullpower);
                }
                else {
                    if(rightdrive.getCurrentPosition() < encodercounts) {
                        rightdrive.setTargetPosition((int) encodercounts + 1);
                        leftdrive.setTargetPosition((int) encodercounts + 1);

                        rightdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RUN_TO_POSITION);

                        rightdrive.setPower(fullpower);
                        leftdrive.setDirection(DcMotor.Direction.FORWARD);
                        leftdrive.setPower(fullpower);
                    }
                    else {
                        rightdrive.setPower(0);
                        leftdrive.setPower(0);
                        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
                    }
                }

                break;
        }
        action = "done";
    }

    private final ArrayList<Integer> Step = new ArrayList<>();

    @Override
    public void init() {

        rightdrive = hardwareMap.dcMotor.get("right_drive");
        leftdrive = hardwareMap.dcMotor.get("left_drive");

        rightdrive.setDirection(DcMotor.Direction.REVERSE);

        leftdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);
        rightdrive.setChannelMode(DcMotorController.RunMode.RESET_ENCODERS);


        step = 1;
        Step.add(step);
        //compassSensor = (HiTechnicNxtCompassSensor) hardwareMap.compassSensor.get("compass");
        compassvalue = 0;

        relativeposition = RelativePosition.North;

        distance = 12;

        angle = 60;



    }

    public void start() {
        status = "Running";

        time = new ElapsedTime();
        time.reset();

    }

    @Override
    public void loop() {

        telemetry.addData("Status", status);
        double currenttime = time.time();

        int size = Step.size();
        for (int i=0; i<size; i++) {
            int element = Step.get(i);

            switch (element) {
                case 1:

                    Action(angle, (int) compassvalue,encodercounts,relativeposition);

                    step++;
                    Step.add(step);

                    break;
                case 2:

                    rightdrive.setPower(0);
                    leftdrive.setPower(0);

                    status = "Done";

            }
        }


    }
}

【问题讨论】:

  • 尽量只保留相关代码;那里有很多可以取出的代码。更容易阅读!
  • 我很抱歉我尝试了几种不同的方法来尝试自己解决这个问题。我可能在调试过程中留下了一些东西。

标签: java android arraylist state-machine robotics


【解决方案1】:

我想到的第一件事是,一个简单的解决方案是使用一个通用的全局布尔值作为标志来检查该方法是否仍在运行。当然,这是基于我的假设,即一次您只有一个方法可以等待,因为根据您的问题,在第一个方法完成之前,您不想运行另一种方法执行。

编辑:

在程序运行时,在开始执行方法之前将布尔值设置为 true。

然后,每次方法开始执行时,将其设置为 false,然后在从您的方法返回之前,将其设置回 true。在发出方法调用的循环中,只需在调用另一个方法之前检查该变量即可。

【讨论】:

  • 所以基本上有一个布尔值,在函数开头设置为true,然后在最后设置为false?我对 java 编程很陌生,这是我的第一个扩展程序,这只是整个事情的一部分。
  • @5108AmishElectricians 进行了编辑以更详细地解释。希望对您有所帮助。
  • 我今天会尝试一下,然后报告结果。
猜你喜欢
  • 2011-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-28
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 2011-11-04
相关资源
最近更新 更多