Использование массива для конечного автомата
Я хотел иметь возможность добавлять случаи в конечный автомат переменных перечисления, как список массивов. Я сделал это, создав список массивов и используя размер, чтобы указать количество дел и выполнить их соответствующим образом с помощью цикла 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";
}
}
}
}
1 ответ
Первое, о чем я думаю, наивное решение - использовать общий глобальный логический параметр в качестве флага, чтобы проверить, работает ли метод по-прежнему. Конечно, это основано на моем предположении, что одновременно у вас будет только один метод, которого вы будете ждать, поскольку, в соответствии с вашим вопросом, вы не хотите запускать другой метод, пока первый не будет завершен с его выполнение.
Редактировать:
Установите булево значение true при запуске программы перед началом выполнения метода.
Затем каждый раз, когда метод начинает выполняться, задайте для него значение false, а затем, прежде чем вернуться из метода, установите для него значение true. В вашем цикле, который вызывает вызовы методов, просто проверьте эту переменную перед вызовом другого метода.