forked from acmerobotics/road-runner-quickstart
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathVisualOtoLocalizer.java
More file actions
120 lines (107 loc) · 5.8 KB
/
VisualOtoLocalizer.java
File metadata and controls
120 lines (107 loc) · 5.8 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
118
119
120
package org.firstinspires.ftc.teamcode;
import com.acmerobotics.roadrunner.DualNum;
import com.acmerobotics.roadrunner.Pose2d;
import com.acmerobotics.roadrunner.Time;
import com.acmerobotics.roadrunner.Twist2dDual;
import com.acmerobotics.roadrunner.Vector2d;
import com.acmerobotics.roadrunner.Vector2dDual;
import com.acmerobotics.roadrunner.ftc.Encoder;
import com.acmerobotics.roadrunner.ftc.FlightRecorder;
import com.acmerobotics.roadrunner.ftc.OverflowEncoder;
import com.acmerobotics.roadrunner.ftc.PositionVelocityPair;
import com.acmerobotics.roadrunner.ftc.RawEncoder;
import com.qualcomm.robotcore.hardware.DcMotorEx;
import com.qualcomm.robotcore.hardware.HardwareMap;
import com.qualcomm.hardware.sparkfun.SparkFunOTOS;
import org.firstinspires.ftc.robotcontroller.external.samples.SensorSparkFunOTOS;
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
import org.firstinspires.ftc.teamcode.messages.ThreeDeadWheelInputsMessage;
public class VisualOtoLocalizer {
public final SparkFunOTOS visualOto;
private SparkFunOTOS.Pose2D lastPos;
private boolean initialized;
public VisualOtoLocalizer(HardwareMap hardwareMap) {
// TODO: make sure your config has **motors** with these names (or change them)
// the encoders should be plugged into the slot matching the named motor
// see https://ftc-docs.firstinspires.org/en/latest/hardware_and_software_configuration/configuring/index.html
visualOto = hardwareMap.get(SparkFunOTOS.class, "sensor_otos");
visualOto.setLinearUnit(DistanceUnit.INCH);
// myOtos.setAngularUnit(AnguleUnit.RADIANS);
visualOto.setAngularUnit(AngleUnit.DEGREES);
SparkFunOTOS.Pose2D offset = new SparkFunOTOS.Pose2D(0, 0, 0);
visualOto.setOffset(offset);
// Here we can set the linear and angular scalars, which can compensate for
// scaling issues with the sensor measurements. Note that as of firmware
// version 1.0, these values will be lost after a power cycle, so you will
// need to set them each time you power up the sensor. They can be any value
// from 0.872 to 1.127 in increments of 0.001 (0.1%). It is recommended to
// first set both scalars to 1.0, then calibrate the angular scalar, then
// the linear scalar. To calibrate the angular scalar, spin the robot by
// multiple rotations (eg. 10) to get a precise error, then set the scalar
// to the inverse of the error. Remember that the angle wraps from -180 to
// 180 degrees, so for example, if after 10 rotations counterclockwise
// (positive rotation), the sensor reports -15 degrees, the required scalar
// would be 3600/3585 = 1.004. To calibrate the linear scalar, move the
// robot a known distance and measure the error; do this multiple times at
// multiple speeds to get an average, then set the linear scalar to the
// inverse of the error. For example, if you move the robot 100 inches and
// the sensor reports 103 inches, set the linear scalar to 100/103 = 0.971
visualOto.setLinearScalar(1.0);
visualOto.setAngularScalar(1.0);
// The IMU on the OTOS includes a gyroscope and accelerometer, which could
// have an offset. Note that as of firmware version 1.0, the calibration
// will be lost after a power cycle; the OTOS performs a quick calibration
// when it powers up, but it is recommended to perform a more thorough
// calibration at the start of all your OpModes. Note that the sensor must
// be completely stationary and flat during calibration! When calling
// calibrateImu(), you can specify the number of samples to take and whether
// to wait until the calibration is complete. If no parameters are provided,
// it will take 255 samples and wait until done; each sample takes about
// 2.4ms, so about 612ms total
visualOto.calibrateImu();
// Reset the tracking algorithm - this resets the position to the origin,
// but can also be used to recover from some rare tracking errors
visualOto.resetTracking();
// After resetting the tracking, the OTOS will report that the robot is at
// the origin. If your robot does not start at the origin, or you have
// another source of location information (eg. vision odometry), you can set
// the OTOS location to match and it will continue to track from there.
SparkFunOTOS.Pose2D currentPosition = new SparkFunOTOS.Pose2D(0, 0, 0);
visualOto.setPosition(currentPosition);
}
public Twist2dDual<Time> update() {
SparkFunOTOS.Pose2D pos = visualOto.getPosition();
SparkFunOTOS.Pose2D vel = visualOto.getVelocity();
//
if (!initialized) {
initialized = true;
lastPos = pos;
return new Twist2dDual<>(
Vector2dDual.constant(new Vector2d(0.0, 0.0), 2),
DualNum.constant(0.0, 2)
);
}
//
SparkFunOTOS.Pose2D deltaPos = new SparkFunOTOS.Pose2D(pos.x - lastPos.x, pos.y -lastPos.y, (pos.h-lastPos.h)%360);
//
Twist2dDual<Time> twist = new Twist2dDual<>(
new Vector2dDual<>(
new DualNum<Time>(new double[] {
deltaPos.x,
vel.x,
}),
new DualNum<Time>(new double[] {
deltaPos.y,
vel.y,
})
),
new DualNum<>(new double[] {
deltaPos.h,
vel.h,
})
);
lastPos = pos;
return twist;
}
}