Skip to content

Commit 092b991

Browse files
MooseCodingmoosecoding
andauthored
feat(nextftc): add feedback servos section
* Adding in Feedback Servos Section * First CRServo commit * I fixed the things Davis * Update differential.md * Removing CRservoEx thing * Update feedback-servos.md Co-authored-by: moosecoding <moosecoding@moosecoding.my.domain> Ref: #17
1 parent 080d3af commit 092b991

3 files changed

Lines changed: 216 additions & 2 deletions

File tree

src/nextftc/hardware/drivetrain-commands/differential.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ driverControlled()
142142
== Java
143143

144144
```java
145-
driverControlled = new MecanumDriverControlled(leftMotors, rightMotors, gamepadManager.gamepad1);
145+
driverControlled = new DifferentialTankDriverControlled(leftMotors, rightMotors, gamepadManager.gamepad1);
146146
driverControlled.schedule();
147147
```
148148

@@ -167,4 +167,4 @@ driverControlled.schedule();
167167

168168
:::
169169

170-
That's it! Now you are able to control your differential drivetrain using a gamepad.
170+
That's it! Now you are able to control your differential drivetrain using a gamepad.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Continuous Rotation Servos
2+
3+
`CRServoEx` wraps a `CRServo` exactly like a `ServoEx` wraps a `Servo` but implements `Powerable` instead of `Positionable`.
4+
5+
## Declarations
6+
7+
You can declare `CRServoEx` in the following manner, much like a normal `ServoEx`:
8+
9+
:::tabs key:code
10+
11+
== Kotlin
12+
13+
```kotlin
14+
val crServoEx: CRServoEx = CRServoEx("cr_servo_name")
15+
16+
// Alternatively
17+
val crServoEx: CRServoEx = CRServoEx { crServo }
18+
19+
// Alternatively
20+
val crServoEx: CRServoEx = CRServoEx(crServo)
21+
22+
```
23+
24+
== Java
25+
```java
26+
CRServoEx crServoEx = new CRServoEx("cr_servo_name");
27+
28+
// Alternatively
29+
CRServoEx crServoEx = new CRServoEx(() -> crServo);
30+
31+
// Alternatively
32+
CRServoEx crServoEx = new CRServoEx(crServo);
33+
34+
```
35+
36+
:::
37+
38+
Additionally you can pass a cache tolerance (default is 0.01), exactly like a normal servo.
39+
40+
:::tabs key:code
41+
42+
== Kotlin
43+
```kotlin
44+
var crServoEx = CRServoEx("cr_servo_name", cacheTolerance)
45+
var crServoEx = CRServoEx(cacheTolerance) { crServo }
46+
var crServoEx = CRServoEx(crServo, cacheTolerance)
47+
```
48+
== Java
49+
```java
50+
CRServoEx crServoEx = new CRServoEx("cr_servo_name", cacheTolerance);
51+
CRServoEx crServoEx = new CRServoEx(cacheTolerance, () -> crServo);
52+
CRServoEx crServoEx = new CRServoEx(crServo, cacheTolerance);
53+
```
54+
:::
55+
56+
## Usage
57+
58+
`CRServoEx` has only a `power` property to set or get the power of the motor. Like a `MotorEx` the power can vary from -1 to 1.
59+
60+
:::tabs key:code
61+
62+
== Kotlin
63+
64+
```kotlin
65+
crServoEx.power = 0.0 // To turn off
66+
crServoEx.power = -1.0 // To spin in reverse fully
67+
crServoEx.power = 0.5 // To spin forward partially
68+
```
69+
70+
== Java
71+
72+
```java
73+
crServoEx.setPower(0.0); // To turn off
74+
crServoEx.setPower(-1.0); // To spin in reverse fully
75+
crServoEx.setPower(0.5); // To spin forward partially
76+
```
77+
78+
:::
79+
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# Feedback Servos
2+
3+
Feedback servos can be one of two types: `FeedbackCRServoEx` or `FeedbackServoEx`. These wrap respectively a `CRServoEx` and a `ServoEx`. They allow you to read the position of the servo from the 4th analog pin.
4+
5+
## FeedbackServoEx
6+
7+
:::tabs key:code
8+
9+
== Kotlin
10+
11+
```kotlin
12+
val servo: FeedbackServoEx = FeedbackServoEx("analog-name", "servo-name", 0.01)
13+
14+
// Alternatively
15+
val servo: FeedbackServoEx = FeedbackServoEx {
16+
cacheTolerance = 0.01, // Or whatever you'd like to use
17+
feedbackFactory = { ActiveOpMode.hardwareMap.analogInput.get("analog-name") },
18+
servoFactory = { ActiveOpMode.hardwareMap.servo.get("servo-name") }
19+
}
20+
21+
// Alternatively
22+
val analogInput: AnalogInput = ActiveOpMode.hardwareMap.analogInput.get("analog-name")
23+
val servoFactory: Servo = ActiveOpMode.hardwareMap.servo.get("servo-name")
24+
val servo: FeedbackServoEx = FeedbackServoEx(analogInput, servoFactory, 0.01) // Using cache tolerance = 0.01
25+
```
26+
== Java
27+
```java
28+
FeedbackServoEx servo = new FeedbackServoEx("analog-name", "servo-name", 0.01);
29+
30+
// Alternatively
31+
FeedbackServoEx servo = new FeedbackServoEx(
32+
0.01, // Or your preferred cache tolerance
33+
() -> { ActiveOpMode.hardwareMap().analogInput.get("analog-name") },
34+
() -> { ActiveOpMode.hardwareMap().servo.get("servo-name") }
35+
);
36+
37+
// Alternatively
38+
AnalogInput analogInput = ActiveOpMode.hardwareMap().analogInput.get("analog-name");
39+
Servo servoFactory = ActiveOpMode.hardwareMap().servo.get("servo-name");
40+
FeedbackServoEx servo = new FeedbackServoEx(analogInput, servoFactory, 0.01);
41+
```
42+
==
43+
:::
44+
45+
The caching tolerance is the same for any normal `ServoEx` or other implementation.
46+
47+
48+
## FeedbackCRServoEx
49+
50+
:::tabs key:code
51+
52+
== Kotlin
53+
54+
```kotlin
55+
val servo: FeedbackCRServoEx = FeedbackCRServoEx("analog-name", "servo-name", 0.01)
56+
57+
// Alternatively
58+
val servo: FeedbackCRServoEx = FeedbackCRServoEx {
59+
cacheTolerance = 0.01, // Or whatever you'd like to use
60+
feedbackFactory = { ActiveOpMode.hardwareMap.analogInput.get("analog-name") },
61+
servoFactory = { ActiveOpMode.hardwareMap.crservo.get("servo-name") }
62+
}
63+
64+
// Alternatively
65+
val analogInput: AnalogInput = ActiveOpMode.hardwareMap.analogInput.get("analog-name")
66+
val servoFactory: CRServo = ActiveOpMode.hardwareMap.crservo.get("servo-name")
67+
val servo: FeedbackCRServoEx = FeedbackCRServoEx(analogInput, servoFactory, 0.01) // Using cache tolerance = 0.01
68+
```
69+
== Java
70+
```java
71+
FeedbackCRServoEx servo = new FeedbackCRServoEx("analog-name", "servo-name", 0.01);
72+
73+
// Alternatively
74+
FeedbackCRServoEx servo = new FeedbackCRServoEx(
75+
0.01, // Or your preferred cache tolerance
76+
() -> { ActiveOpMode.hardwareMap().analogInput.get("analog-name") },
77+
() -> { ActiveOpMode.hardwareMap().crservo.get("servo-name") }
78+
);
79+
80+
// Alternatively
81+
AnalogInput analogInput = ActiveOpMode.hardwareMap.analogInput.get("analog-name");
82+
CRServo servoFactory = ActiveOpMode.hardwareMap.crservo.get("servo-name");
83+
FeedbackCRServoEx servo = new FeedbackCRServoEx(analogInput, servoFactory, 0.01);
84+
```
85+
==
86+
:::
87+
88+
Same deal as `FeedbackServoEx` with caching.
89+
90+
## Features
91+
92+
Both `FeedbackCRServoEx` and `FeedbackServoEx` share the same `currentPosition` property This returns the current position of the servo in radians from 0 to 2 pi, and it is an absolute encoder so it will wrap over.
93+
94+
## Example Tracking
95+
96+
:::tabs key:code
97+
98+
== Kotlin
99+
```kotlin
100+
var totalAngle:Double = 0.0 // This is your angle of the servo
101+
var previousAngle:Double = 0.0 // This is the previous loop's servo position
102+
103+
fun updatePosition() {
104+
val currentAngle = servo.currentPosition
105+
var deltaAngle = currentAngle - previousAngle
106+
107+
if(deltaAngle > Math.PI) deltaAngle -= 2 * Math.PI
108+
else if (deltaAngle < -Math.PI) deltaAngle += 2 * Math.PI
109+
110+
totalAngle += deltaAngle
111+
previousAngle = currentAngle
112+
}
113+
```
114+
115+
== Java
116+
117+
```java
118+
double totalAngle = 0.0; // This is your angle of the servo
119+
double previousAngle = 0.0; // This is the previous loop's servo position
120+
121+
void updatePosition() {
122+
double currentAngle = servo.getCurrentPosition();
123+
double deltaAngle = currentAngle - previousAngle;
124+
125+
if (deltaAngle > Math.PI) deltaAngle -= 2 * Math.PI;
126+
else if (deltaAngle < -Math.PI) deltaAngle += 2 * Math.PI;
127+
128+
totalAngle += deltaAngle;
129+
previousAngle = currentAngle;
130+
}
131+
```
132+
==
133+
:::
134+
135+
This code would result in the tracked position of the servo (beyond 0 to 2 pi). This is incredibly useful for `FeedbackCRServoEx`. However be warned that the analog wrap may cause issues, but this is merely an example.

0 commit comments

Comments
 (0)