2023-02-08 00:35:10 -07:00
|
|
|
// Copyright (c) FIRST and other WPILib contributors.
|
|
|
|
|
// Open Source Software; you can modify and/or share it under the terms of
|
|
|
|
|
// the WPILib BSD license file in the root directory of this project.
|
|
|
|
|
|
|
|
|
|
package frc4388.robot.commands;
|
|
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.FileNotFoundException;
|
2023-02-11 12:44:51 -07:00
|
|
|
import java.util.ArrayList;
|
2023-02-08 00:35:10 -07:00
|
|
|
import java.util.Scanner;
|
|
|
|
|
import edu.wpi.first.math.geometry.Translation2d;
|
|
|
|
|
import edu.wpi.first.wpilibj2.command.CommandBase;
|
|
|
|
|
import frc4388.robot.subsystems.SwerveDrive;
|
2023-02-14 19:00:09 -07:00
|
|
|
import frc4388.utility.UtilityStructs.TimedOutput;
|
2023-02-08 00:35:10 -07:00
|
|
|
|
|
|
|
|
public class JoystickPlayback extends CommandBase {
|
2023-02-11 15:21:44 -07:00
|
|
|
private final SwerveDrive swerve;
|
2023-02-25 12:51:23 -07:00
|
|
|
private String filename;
|
|
|
|
|
private int mult = 1;
|
2023-02-11 15:21:44 -07:00
|
|
|
private Scanner input;
|
2023-02-14 19:00:09 -07:00
|
|
|
private final ArrayList<TimedOutput> outputs = new ArrayList<>();
|
2023-02-11 15:21:44 -07:00
|
|
|
private int counter = 0;
|
|
|
|
|
private long startTime = 0;
|
|
|
|
|
private long playbackTime = 0;
|
|
|
|
|
private int lastIndex;
|
|
|
|
|
private boolean m_finished = false; // ! find a better way
|
2023-02-08 00:35:10 -07:00
|
|
|
|
|
|
|
|
/** Creates a new JoystickPlayback. */
|
2023-02-25 12:51:23 -07:00
|
|
|
public JoystickPlayback(SwerveDrive swerve, String filename, int mult) {
|
2023-02-11 15:21:44 -07:00
|
|
|
this.swerve = swerve;
|
2023-02-25 12:51:23 -07:00
|
|
|
this.filename = filename;
|
|
|
|
|
this.mult = mult;
|
|
|
|
|
|
2023-02-11 15:21:44 -07:00
|
|
|
addRequirements(this.swerve);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-25 12:51:23 -07:00
|
|
|
/** Creates a new JoystickPlayback. */
|
|
|
|
|
public JoystickPlayback(SwerveDrive swerve, String filename) {
|
|
|
|
|
this(swerve, filename, 1);
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-11 15:21:44 -07:00
|
|
|
// Called when the command is initially scheduled.
|
|
|
|
|
@Override
|
|
|
|
|
public void initialize() {
|
|
|
|
|
startTime = System.currentTimeMillis();
|
|
|
|
|
playbackTime = 0;
|
|
|
|
|
lastIndex = 0;
|
2023-02-11 11:51:13 -07:00
|
|
|
try {
|
2023-02-25 12:51:23 -07:00
|
|
|
input = new Scanner(new File("/home/lvuser/" + filename));
|
2023-02-11 12:44:51 -07:00
|
|
|
|
|
|
|
|
String line = "";
|
2023-02-11 15:21:44 -07:00
|
|
|
while (input.hasNextLine()) {
|
|
|
|
|
line = input.nextLine();
|
2023-02-25 12:30:20 -07:00
|
|
|
|
|
|
|
|
if (line.isEmpty() || line.isBlank() || line.equals("\n")) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-02-11 12:44:51 -07:00
|
|
|
|
|
|
|
|
String[] values = line.split(",");
|
2023-02-25 12:30:20 -07:00
|
|
|
System.out.println("values: " + values[0] + " " + values[1] + " " + values[2] + " " + values[3]);
|
2023-02-11 12:44:51 -07:00
|
|
|
|
|
|
|
|
var out = new TimedOutput();
|
2023-02-25 12:51:23 -07:00
|
|
|
out.leftX = Double.parseDouble(values[0]) * mult;
|
2023-02-11 12:44:51 -07:00
|
|
|
out.leftY = Double.parseDouble(values[1]);
|
|
|
|
|
out.rightX = Double.parseDouble(values[2]);
|
|
|
|
|
out.rightY = Double.parseDouble(values[3]);
|
|
|
|
|
|
2023-02-11 15:21:44 -07:00
|
|
|
out.timedOffset = Long.parseLong(values[4]);
|
2023-02-11 12:44:51 -07:00
|
|
|
|
2023-02-11 15:21:44 -07:00
|
|
|
outputs.add(out);
|
2023-02-11 12:44:51 -07:00
|
|
|
}
|
2023-02-11 15:21:44 -07:00
|
|
|
|
|
|
|
|
input.close();
|
2023-02-11 11:51:13 -07:00
|
|
|
} catch (FileNotFoundException e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
2023-02-08 00:35:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called every time the scheduler runs while the command is scheduled.
|
|
|
|
|
@Override
|
|
|
|
|
public void execute() {
|
2023-02-11 15:21:44 -07:00
|
|
|
if (counter == 0) {
|
|
|
|
|
startTime = System.currentTimeMillis();
|
|
|
|
|
playbackTime = 0;
|
|
|
|
|
} else {
|
|
|
|
|
playbackTime = System.currentTimeMillis() - startTime;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-11 12:44:51 -07:00
|
|
|
// skip to reasonable time frame
|
|
|
|
|
// too tired to write comment: ask daniel thomas; it goes to the thing until it's bigger than the other thing
|
|
|
|
|
{
|
2023-02-11 15:21:44 -07:00
|
|
|
int i = lastIndex == 0 ? 1 : lastIndex;
|
|
|
|
|
while (i < outputs.size() && outputs.get(i).timedOffset < playbackTime) {
|
2023-02-11 12:44:51 -07:00
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
2023-02-11 15:21:44 -07:00
|
|
|
if (i >= outputs.size()) {
|
2023-02-11 12:44:51 -07:00
|
|
|
m_finished = true; // ! kind of a hack
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-02-11 15:21:44 -07:00
|
|
|
lastIndex = i;
|
2023-02-08 00:35:10 -07:00
|
|
|
}
|
|
|
|
|
|
2023-02-11 15:21:44 -07:00
|
|
|
TimedOutput lastOut = outputs.get(lastIndex - 1);
|
|
|
|
|
TimedOutput out = outputs.get(lastIndex);
|
|
|
|
|
|
|
|
|
|
double deltaTime = out.timedOffset - lastOut.timedOffset;
|
|
|
|
|
double playbackDelta = playbackTime - lastOut.timedOffset;
|
|
|
|
|
|
|
|
|
|
double lerpLX = lastOut.leftX + (out.leftX - lastOut.leftX) * (playbackDelta / deltaTime);
|
|
|
|
|
double lerpLY = lastOut.leftY + (out.leftY - lastOut.leftY) * (playbackDelta / deltaTime);
|
|
|
|
|
double lerpRX = lastOut.rightX + (out.rightX - lastOut.rightX) * (playbackDelta / deltaTime);
|
|
|
|
|
double lerpRY = lastOut.rightY + (out.rightY - lastOut.rightY) * (playbackDelta / deltaTime);
|
|
|
|
|
|
|
|
|
|
// this.swerve.driveWithInput(new Translation2d(out.leftX, out.leftY),
|
|
|
|
|
// new Translation2d(out.rightX, out.rightY),
|
|
|
|
|
// true);
|
|
|
|
|
|
|
|
|
|
this.swerve.driveWithInput( new Translation2d(lerpLX, lerpLY),
|
|
|
|
|
new Translation2d(lerpRX, lerpRY),
|
|
|
|
|
true);
|
2023-02-25 12:30:20 -07:00
|
|
|
|
2023-02-11 15:21:44 -07:00
|
|
|
counter++;
|
2023-02-08 00:35:10 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Called once the command ends or is interrupted.
|
|
|
|
|
@Override
|
2023-02-10 17:33:19 -07:00
|
|
|
public void end(boolean interrupted) {
|
2023-02-11 15:21:44 -07:00
|
|
|
input.close();
|
|
|
|
|
swerve.stopModules();
|
2023-02-10 17:33:19 -07:00
|
|
|
}
|
2023-02-08 00:35:10 -07:00
|
|
|
|
|
|
|
|
// Returns true when the command should end.
|
|
|
|
|
@Override
|
|
|
|
|
public boolean isFinished() {
|
2023-02-11 12:44:51 -07:00
|
|
|
return m_finished;
|
2023-02-08 00:35:10 -07:00
|
|
|
}
|
|
|
|
|
}
|