Skip to content
This repository was archived by the owner on Sep 14, 2019. It is now read-only.

Commit 410b219

Browse files
committed
add AutoUtils.java
for autonomous functions like parseScriptFile(). also modified Autonomous, RunScript, and Robot to make them better
1 parent 3b86061 commit 410b219

4 files changed

Lines changed: 238 additions & 18 deletions

File tree

Robot2018/src/org/usfirst/frc/team199/Robot2018/Robot.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11

22
package org.usfirst.frc.team199.Robot2018;
33

4+
import java.util.ArrayList;
5+
import java.util.Map;
6+
7+
import org.usfirst.frc.team199.Robot2018.autonomous.AutoUtils;
48
import org.usfirst.frc.team199.Robot2018.subsystems.Climber;
59
import org.usfirst.frc.team199.Robot2018.subsystems.ClimberAssist;
610
import org.usfirst.frc.team199.Robot2018.subsystems.IntakeEject;
711
import org.usfirst.frc.team199.Robot2018.subsystems.Lift;
812

913
import edu.wpi.first.wpilibj.IterativeRobot;
14+
import edu.wpi.first.wpilibj.Preferences;
1015
import edu.wpi.first.wpilibj.command.Command;
1116
import edu.wpi.first.wpilibj.command.Scheduler;
12-
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
1317
import edu.wpi.first.wpilibj.smartdashboard.SendableChooser;
1418
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
1519

@@ -27,6 +31,8 @@ public class Robot extends IterativeRobot {
2731
public static final IntakeEject intakeEject = new IntakeEject();
2832
public static final Lift lift = new Lift();
2933
public static OI oi;
34+
35+
public static Map<String, ArrayList<String[]>> autoScripts;
3036

3137
Command autonomousCommand;
3238
SendableChooser<Command> chooser = new SendableChooser<>();
@@ -40,6 +46,8 @@ public void robotInit() {
4046
oi = new OI();
4147
// chooser.addObject("My Auto", new MyAutoCommand());
4248
SmartDashboard.putData("Auto mode", chooser);
49+
50+
autoScripts = AutoUtils.parseScriptFile(Preferences.getInstance().getString("autoscripts", ""));
4351
}
4452

4553
/**
@@ -66,7 +74,7 @@ public void disabledPeriodic() {
6674
*
6775
* You can add additional auto modes by adding additional commands to the
6876
* chooser code above (like the commented example) or additional comparisons
69-
* to the switch structure below with additional strings & commands.
77+
* to the switch structure below with additional strings &amp; commands.
7078
*/
7179
@Override
7280
public void autonomousInit() {
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
package org.usfirst.frc.team199.Robot2018.autonomous;
2+
3+
import java.util.ArrayList;
4+
import java.util.HashMap;
5+
import java.util.Map;
6+
7+
public class AutoUtils {
8+
9+
/**
10+
* Parses the inputted script file into a map of scripts
11+
*
12+
* @param scriptFile the script file to parse
13+
* @return a map, with the key being the script name, and the argument
14+
* being a list of arrays that are instruction-argument pairs
15+
*/
16+
public static Map<String, ArrayList<String[]>> parseScriptFile(String scriptFile) {
17+
Map<String, ArrayList<String[]>> autoScripts = new HashMap<String, ArrayList<String[]>>();
18+
19+
String lines[] = scriptFile.split("\\r?\\n");
20+
21+
ArrayList<String[]> currScript = new ArrayList<String[]>();
22+
String currScriptName = "";
23+
24+
int count = 0;
25+
for (String line : lines) {
26+
// remove comments
27+
line = line.substring(0, line.indexOf("#"));
28+
29+
// trim just to make it neater
30+
line = line.trim();
31+
32+
// if there's no instruction on this line, skip
33+
if (line.equals("")) {
34+
continue;
35+
}
36+
37+
// if current line is a label, store the previous script and make a new empty one
38+
if (line.endsWith(":")) {
39+
autoScripts.put(currScriptName, currScript);
40+
currScript = new ArrayList<String[]>();
41+
currScriptName = line.substring(0, line.length() - 1);
42+
} else {
43+
44+
// first separate the command into instruction and args
45+
String instruction;
46+
String args;
47+
48+
int separator = line.indexOf(' ');
49+
if (separator == -1) {
50+
instruction = line;
51+
args = "";
52+
} else {
53+
instruction = line.substring(0, separator);
54+
args = line.substring(separator + 1);
55+
}
56+
57+
// if it's valid, put it into the script
58+
if (isValidCommand(instruction, args, count)) {
59+
String[] command = {instruction, args};
60+
currScript.add(command);
61+
}
62+
}
63+
count++;
64+
}
65+
66+
// puts the last script in
67+
autoScripts.put(currScriptName, currScript);
68+
69+
return autoScripts;
70+
}
71+
72+
73+
/**
74+
* Validates the command inputted to see if it's AAA compliant
75+
*
76+
* @param instruction the instruction/command name
77+
* @param args the arguments provided to the instruction. A blank String if none
78+
* @param lineNumber the lineNumber in the script file. used for logging warnings
79+
* @return if the command is valid
80+
*/
81+
public static boolean isValidCommand (String instruction, String args, int lineNumber) {
82+
// moveto takes in a set of points, and the last arg can be a number
83+
if (instruction.equals("moveto")) {
84+
if (args == "") {
85+
logWarning(lineNumber, "The command `moveto` requires at least one argument.");
86+
return false;
87+
}
88+
89+
String[] splitArgs = args.split(" ");
90+
for (int i = 0; i < splitArgs.length - 1; i++) {
91+
if (!isPoint(splitArgs[i])) {
92+
logWarning(lineNumber, "The arguments for command `moveto` should be points formatted like this: "
93+
+ "`(x,y)`.");
94+
return false;
95+
}
96+
}
97+
98+
if (!isDouble(splitArgs[splitArgs.length - 1]) && !isPoint(splitArgs[splitArgs.length - 1])) {
99+
logWarning(lineNumber, "The last argument for command `moveto` should be a number, or a point "
100+
+ "formatted like this: `(x,y)`.");
101+
return false;
102+
}
103+
}
104+
105+
// turn can take a number or point
106+
else if (instruction.equals("turn")) {
107+
if (args.contains(" ")) {
108+
logWarning(lineNumber, "Command `turn` only accepts one argument.");
109+
return false;
110+
}
111+
112+
if (!isDouble(args) && !isPoint(args)) {
113+
logWarning(lineNumber, "The argument for command `turn` should be a number or a point formatted like "
114+
+ "this: `(x,y)`.");
115+
return false;
116+
}
117+
}
118+
119+
// move and wait can take only a number
120+
else if (instruction.equals("move") || instruction.equals("wait")) {
121+
if (args.contains(" ")) {
122+
logWarning(lineNumber, "Command `move` only accepts one argument.");
123+
return false;
124+
}
125+
126+
if (!isDouble(args)) {
127+
logWarning(lineNumber, "The argument for command `move` should be a number.");
128+
return false;
129+
}
130+
}
131+
132+
// switch, scale, exchange, intake, and end all don't have any args
133+
else if (instruction.equals("switch") || instruction.equals("scale") || instruction.equals("exchange")
134+
|| instruction.equals("intake") || instruction.equals("end")) {
135+
if (!args.equals("")) {
136+
logWarning(lineNumber, "Command `" + instruction + "` does not accept any arguments.");
137+
return false;
138+
}
139+
}
140+
141+
// Jump only takes one argument
142+
else if (instruction.equals("jump")) {
143+
if (args.contains(" ")) {
144+
logWarning(lineNumber, "Command `jump` only accepts one argument.");
145+
return false;
146+
}
147+
}
148+
149+
// if it's not even a valid instruction
150+
else {
151+
logWarning(lineNumber, "`" + instruction + "` is not a valid command.");
152+
return false;
153+
}
154+
155+
// if everything is all good
156+
return true;
157+
}
158+
159+
/**
160+
* Helper method used by isValidCommand() to log warnings for non-valid commands.
161+
*
162+
* @param lineNumber the line number in the script file
163+
* @param message the message to log
164+
*/
165+
private static void logWarning (int lineNumber, String message) {
166+
System.err.println("[WARNING] Line " + lineNumber + ": " + message);
167+
}
168+
169+
/**
170+
* Helper method used by isValidCommand() to check if an argument is a
171+
* point, characterized by parentheses on the left and right, with two
172+
* numbers separated by a comma, with no whitespace in between.
173+
*
174+
* @param s the argument
175+
* @return if the argument is a point
176+
*/
177+
private static boolean isPoint (String s) {
178+
// checks if it starts and ends with parentheses
179+
if (!s.startsWith("(") || !s.endsWith(")"))
180+
return false;
181+
182+
// checks that there's one, and only one comma (like this phrase)
183+
int indexOfComma = s.indexOf(',');
184+
int count = 0;
185+
while (indexOfComma != -1) {
186+
count++;
187+
indexOfComma = s.indexOf(',', indexOfComma + 1);
188+
}
189+
if (count != 1)
190+
return false;
191+
192+
193+
// really ugly, but just checks if the stuff between the parentheses are numbers
194+
if (!isDouble(s.substring(s.indexOf('('), s.indexOf(',')))
195+
|| !isDouble(s.substring(s.indexOf(',') + 1, s.indexOf(')'))))
196+
return false;
197+
198+
return true;
199+
}
200+
201+
/**
202+
* Helper method used by isValidCommand() used to check if an argument is
203+
* able to be converted into a double
204+
*
205+
* @param s the argument
206+
* @return if the argument is a double
207+
*/
208+
private static boolean isDouble (String s) {
209+
try {
210+
Double.parseDouble(s);
211+
} catch (Exception e) {
212+
return false;
213+
}
214+
return true;
215+
}
216+
}

Robot2018/src/org/usfirst/frc/team199/Robot2018/commands/Autonomous.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.usfirst.frc.team199.Robot2018.commands;
22

3-
import java.util.ArrayList;
43
import java.util.Map;
54

65
import edu.wpi.first.wpilibj.command.CommandGroup;

Robot2018/src/org/usfirst/frc/team199/Robot2018/commands/RunScript.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package org.usfirst.frc.team199.Robot2018.commands;
22

33
import java.util.ArrayList;
4-
import java.util.Arrays;
5-
import java.util.Map;
64

75
import org.usfirst.frc.team199.Robot2018.Robot;
86

@@ -15,24 +13,22 @@
1513
public class RunScript extends CommandGroup implements RunScriptInterface {
1614

1715
public RunScript(String scriptName) {
18-
// make sure to uncomment this when autoScripts is written
19-
ArrayList<String> script = new ArrayList<String>(); // Robot.autoScripts.getOrDefault(scriptName, new ArrayList<String>());
16+
ArrayList<String[]> script = Robot.autoScripts.getOrDefault(scriptName, new ArrayList<String[]>());
2017

2118
outerloop:
22-
for(String cmd : script) {
23-
String[] cmdParts = cmd.split(" ");
24-
String cmdName = cmdParts[0];
25-
String[] cmdArgs = Arrays.copyOfRange(cmdParts, 1, cmdParts.length);
19+
for(String[] cmd : script) {
20+
String cmdName = cmd[0];
21+
String cmdArgs = cmd[1];
2622

27-
switch (cmdParts[0]) {
23+
switch (cmdName) {
2824
case "moveto":
29-
addSequential(new AutoMoveTo(cmdArgs));
25+
addSequential(new AutoMoveTo(cmdArgs.split(" ")));
3026
break;
3127
case "turn":
32-
addSequential(new AutoTurn(Double.parseDouble(cmdArgs[0])));
28+
addSequential(new AutoTurn(Double.parseDouble(cmdArgs)));
3329
break;
3430
case "move":
35-
addSequential(new AutoMove(Double.parseDouble(cmdArgs[0])));
31+
addSequential(new AutoMove(Double.parseDouble(cmdArgs)));
3632
break;
3733
case "switch":
3834
addSequential(new EjectToSwitch());
@@ -44,18 +40,19 @@ public RunScript(String scriptName) {
4440
addSequential(new EjectToExchange());
4541
break;
4642
case "wait":
47-
addSequential(new WaitCommand(Double.parseDouble(cmdArgs[0])));
43+
addSequential(new WaitCommand(Double.parseDouble(cmdArgs)));
4844
break;
4945
case "intake":
5046
addSequential(new IntakeCube());
5147
break;
5248
case "jump":
53-
addSequential(new RunScript(cmdArgs[0]));
49+
addSequential(new RunScript(cmdArgs));
5450
break;
5551
case "end":
5652
break outerloop;
5753
default:
58-
System.out.println("`" + cmdParts[0] + "`" + " is not a valid command name. Check AAA Reference.");
54+
// this should never happen since AutoUtils already validates the script.
55+
System.err.println("[ERROR] `" + cmdName + "` is not a valid command name.");
5956
}
6057
}
6158
}

0 commit comments

Comments
 (0)