-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSmartShootCommand.java
More file actions
117 lines (97 loc) · 3.75 KB
/
Copy pathSmartShootCommand.java
File metadata and controls
117 lines (97 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// 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 frc.robot.commands;
import org.littletonrobotics.junction.Logger;
import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.wpilibj2.command.Command;
import frc.robot.Constants;
import frc.robot.subsystems.conveyor.Conveyor;
import frc.robot.subsystems.drive.Drive;
import frc.robot.subsystems.shooter.Shooter;
import frc.robot.subsystems.transfer.Transfer;
import frc.robot.util.SOTMUtil;
public class SmartShootCommand extends Command {
private final Shooter shooter;
private final Transfer transfer;
private final Conveyor conveyor;
private final Drive drive;
private double setpoint;
private double distance;
private Pose2d targetPose;
public double tolerance = 0.5;
// Below this fraction of target RPS, transfer/conveyor output is zero.
// Above 1.0, output is 100%. Linear interpolation in between.
private static final double MIN_VELOCITY_FRACTION = 0.90;
public SmartShootCommand(Drive drive, Shooter shooter, Transfer transfer, Conveyor conveyor) {
this.shooter = shooter;
this.transfer = transfer;
this.conveyor = conveyor;
this.drive = drive;
addRequirements(shooter, transfer, conveyor);
}
@Override
public void initialize() {
transfer.feeding = false;
transfer.feedTimer.reset();
}
@Override
public void execute() {
targetPose = Constants.FieldConstants.getAllianceHubPose();
SOTMUtil.ShotSolution shot = SOTMUtil.computeConvergedShot(
drive.getPose(),
drive.getFieldRelativeChassisSpeeds(),
targetPose,
shooter::getVelo);
distance = shot.distance();
setpoint = shot.setpoint();
Logger.recordOutput(getName() + "/targetPose", targetPose);
shooter.setBangBangSetpoint(setpoint - 0.4);
Logger.recordOutput(getName() + "/distance", distance);
Logger.recordOutput(getName() + "/setpoint", setpoint);
// Use average of both shooter sides for velocity ratio
double currentVelocity =
(shooter.getLeftShooterVelocity() + shooter.getRightShooterVelocity()) / 2.0;
double feedPower = computeFeedPower(currentVelocity, setpoint);
Logger.recordOutput(getName() + "/feedPower", feedPower);
Logger.recordOutput(getName() + "/velocityRatio", setpoint > 0 ? currentVelocity / setpoint : 0);
//If either shooter velocity is greater than the lower bound of the tolerance or feeding
if (shooter.getLeftShooterVelocity() > setpoint-tolerance
|| shooter.getRightShooterVelocity() > setpoint-tolerance || transfer.feeding) {
transfer.hasPreloaded = false;
transfer.feedTimer.start();
transfer.feeding = true;
transfer.setFeedPower(feedPower);
if (drive.aligned) {
transfer.setTransferDutyCycle(feedPower); //feedPower
conveyor.setLeftFunnelDutyCycle(-1.0);
} else {
transfer.setTransferDutyCycle(0);
conveyor.setLeftFunnelDutyCycle(-1.0);
}
} else {
transfer.setFeedPower(0);
}
}
private double computeFeedPower(double currentVelocity, double targetVelocity) {
if (targetVelocity <= 0) {
return 0;
}
double ratio = currentVelocity / targetVelocity;
return MathUtil.clamp((ratio - MIN_VELOCITY_FRACTION) / (1.0 - MIN_VELOCITY_FRACTION) * 2.5, 0.5, 1.0);
}
@Override
public void end(boolean interrupted) {
transfer.feeding = false;
transfer.feedTimer.reset();
transfer.setFeedPower(0);
transfer.setTransferDutyCycle(0);
conveyor.setLeftFunnelDutyCycle(0);
shooter.setDutyCycleSetpoint(0);
}
@Override
public boolean isFinished() {
return false;
}
}