Skip to content

Commit f27f400

Browse files
committed
Add LocalisationSubsystem
1 parent de186d6 commit f27f400

File tree

2 files changed

+151
-0
lines changed

2 files changed

+151
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package org.firstinspires.ftc.teamcode.lib.subsystems;
2+
3+
import com.qualcomm.hardware.sparkfun.SparkFunOTOS;
4+
import com.qualcomm.robotcore.hardware.HardwareMap;
5+
6+
import org.firstinspires.ftc.robotcore.external.Telemetry;
7+
import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection;
8+
import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
9+
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
10+
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
11+
import org.firstinspires.ftc.robotcore.external.navigation.Position;
12+
import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
13+
import org.firstinspires.ftc.vision.VisionPortal;
14+
import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
15+
import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
16+
17+
import java.util.List;
18+
19+
public class LocalisationSubsystem {
20+
private static final boolean USE_WEBCAM = true;
21+
private SparkFunOTOS OTOSSensor;
22+
private Telemetry telemetry;
23+
private AprilTagProcessor aprilTag;
24+
private VisionPortal visionPortal;
25+
HardwareMap hardwareMap;
26+
27+
28+
// CAMERA Position / YPR
29+
private Position cameraPosition = new Position(DistanceUnit.METER,
30+
0, 0, 0, 0);
31+
32+
// pitch was init'd as -90 in demo, but set to 0 here for now (-90 made no sense)
33+
private YawPitchRollAngles cameraOrientation = new YawPitchRollAngles(AngleUnit.DEGREES,
34+
0, -90, 0, 0);
35+
36+
37+
// ROBOT X, Y and HDG
38+
public double robotX;
39+
public double robotY;
40+
public double robotH;
41+
42+
43+
44+
public LocalisationSubsystem(HardwareMap hardwareMap, Telemetry telemetry) {
45+
this.telemetry = telemetry;
46+
this.hardwareMap = hardwareMap;
47+
48+
configureAprilTag();
49+
50+
OTOSSensor = hardwareMap.get(SparkFunOTOS.class, "sensor_otos");
51+
configureOTOS();
52+
53+
telemetry.addLine("Localisation Subsystem Configured");
54+
telemetry.update();
55+
}
56+
57+
public void periodic() {
58+
List<AprilTagDetection> freshDetections = aprilTag.getFreshDetections();
59+
60+
if (!freshDetections.isEmpty()) {
61+
// we cannot assume that there is only one detection, but we do know the last one is the latest. therefore, by going through all of them, we can know we are up to date.
62+
for (AprilTagDetection detection : freshDetections) {
63+
// as shown by demo code - no "Obelisk" tags can be used for positioning
64+
if (!detection.metadata.name.contains("Obelisk")) {
65+
robotX = detection.robotPose.getPosition().x;
66+
robotY = detection.robotPose.getPosition().y;
67+
robotH = detection.robotPose.getOrientation().getYaw(AngleUnit.DEGREES);
68+
}
69+
}
70+
71+
// update the OTOS's position data
72+
updateOTOS();
73+
telemetry.addData("AprilUpdate", true);
74+
} else {
75+
// navigate off OTOS
76+
positionFromOTOS();
77+
telemetry.addData("AprilUpdate", false);
78+
}
79+
80+
telemetry.addData("RobotX", robotX);
81+
telemetry.addData("RobotY", robotY);
82+
telemetry.addData("RobotHDG", robotH);
83+
telemetry.update();
84+
}
85+
86+
private void updateOTOS() {
87+
SparkFunOTOS.Pose2D currentPosition = new SparkFunOTOS.Pose2D(
88+
robotX,
89+
robotY,
90+
robotH
91+
);
92+
OTOSSensor.setPosition(currentPosition);
93+
}
94+
95+
private void positionFromOTOS() {
96+
SparkFunOTOS.Pose2D currentPosition = OTOSSensor.getPosition();
97+
robotX = currentPosition.x;
98+
robotY = currentPosition.y;
99+
robotH = currentPosition.h;
100+
}
101+
102+
private void configureOTOS() {
103+
// UNIT CALIBRATION
104+
OTOSSensor.setLinearUnit(DistanceUnit.METER);
105+
OTOSSensor.setAngularUnit(AngleUnit.DEGREES);
106+
107+
// OFFSET ON ROBOT -- todo: find exact values, need robot physically
108+
SparkFunOTOS.Pose2D offset = new SparkFunOTOS.Pose2D(0, 0, 0); // h is for heading, probably
109+
OTOSSensor.setOffset(offset);
110+
111+
// SCALAR CALIBRATION -- todo: find exact values, need robot physically
112+
OTOSSensor.setLinearScalar(1.0);
113+
OTOSSensor.setAngularScalar(1.0);
114+
115+
// CALIBRATE IMU
116+
OTOSSensor.calibrateImu();
117+
OTOSSensor.resetTracking();
118+
119+
// starting position, will be updated by april tag positioning.
120+
SparkFunOTOS.Pose2D currentPosition = new SparkFunOTOS.Pose2D(0, 0, 0);
121+
OTOSSensor.setPosition(currentPosition);
122+
123+
telemetry.addLine("OTOS Configured");
124+
telemetry.update();
125+
}
126+
127+
128+
private void configureAprilTag() {
129+
// april tag processor
130+
aprilTag = new AprilTagProcessor.Builder()
131+
.setCameraPose(cameraPosition, cameraOrientation)
132+
.build();
133+
134+
// vision portal
135+
VisionPortal.Builder builder = new VisionPortal.Builder();
136+
137+
// NOTE: USE_WEBCAM is set at top of class. idk what to set it, so it is currently true as the example code used that.
138+
if (USE_WEBCAM) {
139+
builder.setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"));
140+
} else {
141+
builder.setCamera(BuiltinCameraDirection.FRONT); // used to be BACK in e.g. code
142+
}
143+
144+
// enable the processor
145+
builder.addProcessor(aprilTag);
146+
visionPortal = builder.build();
147+
telemetry.addLine("April Tag Process Configured");
148+
telemetry.update();
149+
}
150+
}

TeamCode/src/main/java/org/firstinspires/ftc/teamcode/lib/subsystems/SubsystemBase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ public abstract class SubsystemBase {
99
* continuously, such as updating telemetry, or PID controllers.
1010
*/
1111
public void periodic() {
12+
1213
}
1314
}

0 commit comments

Comments
 (0)