Skip to content

Commit 39e85d9

Browse files
authored
Updating Defaults and Constants. Replace Mock Class Abstraction with MockHardware. (#19)
* Refactored `Flywheel` to accept motor name as a parameter. * Updated imports and constants usage across multiple modules. * Implemented new `Odometry` class; integrated into `ThreeWheelOdometry` for cleaner encoder handling. * Simplified `Odometry.reset()` to use direct `RunMode` reference. * Consolidated mock classes into `MockHardware`; reduced `hardware/` directory structure. * Refactored `Constants` and `Bot` hardware initialization. * Updated `BasicTeleop` and `TeleopDriver1` to use `setDrivePower` instead of `setDriveVelocity`. * Fixed import paths and updated odometry calculations. * Added build and deployment script; optimized Gradle properties and caching. * Enhanced CI build logging and APK assembly steps. * Added `.gitattributes` for better diff handling of Kotlin and Java files.
1 parent adfa322 commit 39e85d9

34 files changed

Lines changed: 597 additions & 581 deletions

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*.kt diff=kotlin
2+
*.java diff=java

.github/workflows/build.yml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,27 @@ jobs:
2121
java-version: '17'
2222
distribution: 'temurin'
2323

24+
- name: Cache Gradle
25+
uses: actions/cache@v4
26+
with:
27+
path: |
28+
~/.gradle/caches
29+
~/.gradle/wrapper
30+
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
31+
restore-keys: |
32+
gradle-${{ runner.os }}-
33+
2434
- name: Setup Gradle
2535
uses: gradle/actions/setup-gradle@v3
2636
with:
2737
cache-read-only: ${{ github.ref != 'refs/heads/master' }}
2838

2939
- name: Build and Test
30-
run: ./gradlew build --no-daemon
40+
run: ./gradlew build --info --stacktrace --no-daemon
3141

3242
- name: Build Debug APK
3343
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
34-
run: ./gradlew assembleDebug --no-daemon
44+
run: ./gradlew assembleDebug --info --stacktrace --no-daemon
3545

3646
- name: Upload APK
3747
if: github.event_name == 'push' && github.ref == 'refs/heads/master'

TeamCode/src/main/kotlin/pioneer/Bot.kt

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
package pioneer
22

33
import com.qualcomm.robotcore.hardware.HardwareMap
4-
import pioneer.hardware.impl.AprilTagImpl
5-
import pioneer.hardware.impl.BatteryMonitorImpl
6-
import pioneer.hardware.impl.CameraImpl
7-
import pioneer.hardware.impl.FlywheelImpl
8-
import pioneer.hardware.impl.LaunchServosImpl
9-
import pioneer.hardware.impl.MecanumBaseImpl
10-
import pioneer.hardware.interfaces.BatteryMonitor
11-
import pioneer.hardware.interfaces.Camera
12-
import pioneer.hardware.interfaces.Flywheel
13-
import pioneer.hardware.interfaces.LaunchServos
14-
import pioneer.hardware.interfaces.MecanumBase
15-
import pioneer.hardware.mock.AprilTagMock
16-
import pioneer.hardware.mock.BatteryMonitorMock
17-
import pioneer.hardware.mock.CameraMock
18-
import pioneer.hardware.mock.FlywheelMock
19-
import pioneer.hardware.mock.LaunchServosMock
20-
import pioneer.hardware.mock.MecanumBaseMock
4+
import pioneer.constants.Camera as CameraConstants
5+
import pioneer.hardware.AprilTag
6+
import pioneer.hardware.Camera
7+
import pioneer.hardware.BatteryMonitor
8+
import pioneer.hardware.Flywheel
9+
import pioneer.hardware.LaunchServos
10+
import pioneer.hardware.MockHardware
11+
import pioneer.hardware.MecanumBase
2112
import pioneer.localization.Localizer
2213
import pioneer.localization.localizers.LocalizerMock
2314
import pioneer.localization.localizers.Pinpoint
@@ -34,17 +25,17 @@ class Bot(
3425
hardwareMap: HardwareMap,
3526
) {
3627
// Basic hardware components
37-
var mecanumBase: MecanumBase = MecanumBaseMock()
28+
var mecanumBase: MecanumBase = MecanumBase(MockHardware())
3829
var localizer: Localizer = LocalizerMock()
39-
var batteryMonitor: BatteryMonitor = BatteryMonitorMock()
30+
var batteryMonitor: BatteryMonitor = BatteryMonitor(MockHardware())
4031

4132
// GoBilda starter bot specific components
42-
var flywheel: Flywheel = FlywheelMock()
43-
var launchServos: LaunchServos = LaunchServosMock()
33+
var flywheel: Flywheel = Flywheel(MockHardware())
34+
var launchServos: LaunchServos = LaunchServos(MockHardware())
4435

4536
// Other hardware components
46-
var aprilTagProcessor: AprilTagProcessor = AprilTagMock().processor
47-
var camera: Camera = CameraMock()
37+
var aprilTagProcessor: AprilTagProcessor = AprilTag().processor
38+
var camera: Camera = Camera(MockHardware())
4839

4940
// Path follower
5041
var follower = Follower(this)
@@ -53,25 +44,24 @@ class Bot(
5344
when (botType) {
5445
BotType.BASIC_MECANUM_BOT -> {
5546
// Initialize hardware components for Basic Mecanum Bot
56-
mecanumBase = MecanumBaseImpl(hardwareMap, Constants.Drive.MOTOR_CONFIG)
57-
batteryMonitor = BatteryMonitorImpl(hardwareMap)
47+
mecanumBase = MecanumBase(hardwareMap)
48+
batteryMonitor = BatteryMonitor(hardwareMap)
5849
}
5950

6051
BotType.GOBILDA_STARTER_BOT -> {
6152
// Initialize hardware components for GoBilda Starter Bot
62-
mecanumBase = MecanumBaseImpl(hardwareMap, Constants.Drive.MOTOR_CONFIG)
53+
mecanumBase = MecanumBase(hardwareMap)
6354
localizer = Pinpoint(hardwareMap)
64-
batteryMonitor = BatteryMonitorImpl(hardwareMap)
65-
flywheel = FlywheelImpl(hardwareMap)
66-
launchServos = LaunchServosImpl(hardwareMap)
67-
aprilTagProcessor = AprilTagImpl(
68-
Constants.Camera.POSITION_CM,
69-
Constants.Camera.ORIENTATION_RAD
55+
batteryMonitor = BatteryMonitor(hardwareMap)
56+
flywheel = Flywheel(hardwareMap)
57+
launchServos = LaunchServos(hardwareMap)
58+
aprilTagProcessor = AprilTag(
59+
CameraConstants.POSITION_CM,
60+
CameraConstants.ORIENTATION_RAD
7061
).processor
7162
camera =
72-
CameraImpl(
63+
Camera(
7364
hardwareMap,
74-
Constants.HardwareNames.WEBCAM,
7565
processors = arrayOf(aprilTagProcessor),
7666
)
7767
}
Lines changed: 89 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package pioneer
1+
package pioneer.constants
22

33
import com.acmerobotics.dashboard.config.Config
44
import com.qualcomm.hardware.gobilda.GoBildaPinpointDriver
@@ -10,129 +10,93 @@ import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles
1010
import pioneer.helpers.Pose
1111
import kotlin.math.PI
1212

13+
// -------- Odometry (3-wheel) --------
14+
object Odometry {
15+
// geometry (cm)
16+
const val TRACK_WIDTH_CM = 26.5
17+
const val FORWARD_OFFSET_CM = 15.1
18+
const val WHEEL_DIAMETER_CM = 4.8
19+
20+
// encoder
21+
const val TICKS_PER_REV = 2000.0
22+
}
23+
24+
// -------- Drivebase (mecanum) --------
25+
object Drive {
26+
// geometry (cm)
27+
const val TRACK_WIDTH_CM = 0.0
28+
const val WHEEL_BASE_CM = 0.0
29+
30+
// limits
31+
const val MAX_MOTOR_VELOCITY_TPS = 2500.0
32+
const val MAX_FWD_VEL_CMPS = 150.0
33+
const val MAX_STRAFE_VEL_CMPS = 125.0
34+
const val DEFAULT_POWER = 0.7
35+
36+
// Feedforward gains using Pose(x,y,theta)
37+
val kV = Pose(x = 0.006, y = 0.0052, theta = 0.025)
38+
val kA = Pose(x = 0.0, y = 0.0, theta = 0.0)
39+
val kS = Pose(x = 0.0, y = 0.0, theta = 0.0)
40+
41+
}
42+
43+
// -------- Pinpoint (odometry pods) --------
44+
object Pinpoint {
45+
// offsets from tracking point (mm): +forward, +left
46+
const val Y_POD_OFFSET_MM = -107.0
47+
const val X_POD_OFFSET_MM = 125.0
48+
49+
// encoder configuration. Y should increase left, X should increase forward
50+
val Y_ENCODER_DIRECTION = GoBildaPinpointDriver.EncoderDirection.REVERSED
51+
val X_ENCODER_DIRECTION = GoBildaPinpointDriver.EncoderDirection.REVERSED
52+
53+
val ENCODER_RESOLUTION = GoBildaPinpointDriver.GoBildaOdometryPods.goBILDA_SWINGARM_POD
54+
}
55+
56+
// -------- Follower (path following) --------
1357
@Config
14-
object Constants {
15-
object HardwareNames {
16-
// Drive motors
17-
const val DRIVE_LEFT_FRONT = "driveLF"
18-
const val DRIVE_LEFT_BACK = "driveLB"
19-
const val DRIVE_RIGHT_FRONT = "driveRF"
20-
const val DRIVE_RIGHT_BACK = "driveRB"
21-
22-
// Other motors
23-
const val FLYWHEEL = "flywheel"
24-
25-
// Odometry
26-
const val ODO_LEFT = "odoLeft"
27-
const val ODO_RIGHT = "odoRight"
28-
const val ODO_CENTER = "odoCenter"
29-
30-
// Pinpoint
31-
const val PINPOINT = "pinpoint"
32-
33-
// Servos
34-
const val LAUNCH_SERVO_L = "launchServoL"
35-
const val LAUNCH_SERVO_R = "launchServoR"
36-
37-
// Other
38-
const val WEBCAM = "Webcam 1"
39-
}
40-
41-
// -------- Odometry (3-wheel) --------
42-
object Odometry {
43-
// geometry (cm)
44-
const val TRACK_WIDTH_CM = 26.5
45-
const val FORWARD_OFFSET_CM = 15.1
46-
const val WHEEL_DIAMETER_CM = 4.8
47-
48-
// encoder
49-
const val TICKS_PER_REV = 2000.0
50-
const val TICKS_TO_CM: Double = (WHEEL_DIAMETER_CM * PI) / TICKS_PER_REV
51-
}
52-
53-
// -------- Drivebase (mecanum) --------
54-
object Drive {
55-
// geometry (cm)
56-
const val TRACK_WIDTH_CM = 0.0
57-
const val WHEEL_BASE_CM = 0.0
58-
59-
// limits
60-
const val MAX_MOTOR_VELOCITY_TPS = 2500.0
61-
const val MAX_FWD_VEL_CMPS = 150.0
62-
const val MAX_STRAFE_VEL_CMPS = 125.0
63-
const val DEFAULT_POWER = 0.7
64-
65-
// Feedforward gains using Pose(x,y,theta)
66-
val kV = Pose(x = 0.006, y = 0.0052, theta = 0.025)
67-
val kA = Pose(x = 0.0, y = 0.0, theta = 0.0)
68-
val kS = Pose(x = 0.0, y = 0.0, theta = 0.0)
69-
70-
// Motor configuration
71-
val MOTOR_CONFIG = mapOf(
72-
HardwareNames.DRIVE_LEFT_FRONT to DcMotorSimple.Direction.REVERSE,
73-
HardwareNames.DRIVE_LEFT_BACK to DcMotorSimple.Direction.REVERSE,
74-
HardwareNames.DRIVE_RIGHT_FRONT to DcMotorSimple.Direction.FORWARD,
75-
HardwareNames.DRIVE_RIGHT_BACK to DcMotorSimple.Direction.FORWARD
76-
)
77-
}
78-
79-
// -------- Pinpoint (odometry pods) --------
80-
object Pinpoint {
81-
// offsets from tracking point (mm): +forward, +left
82-
const val Y_POD_OFFSET_MM = -107.0
83-
const val X_POD_OFFSET_MM = 125.0
84-
85-
// encoder configuration. Y should increase left, X should increase forward
86-
val Y_ENCODER_DIRECTION = GoBildaPinpointDriver.EncoderDirection.REVERSED
87-
val X_ENCODER_DIRECTION = GoBildaPinpointDriver.EncoderDirection.REVERSED
88-
89-
val ENCODER_RESOLUTION = GoBildaPinpointDriver.GoBildaOdometryPods.goBILDA_SWINGARM_POD
90-
}
91-
92-
// -------- Follower (path following) --------
93-
object Follower {
94-
/** The threshold in cm to consider the target reached. */
95-
const val POSITION_THRESHOLD = 0.5
96-
97-
/** The threshold in radians to consider the target heading reached. */
98-
const val ROTATION_THRESHOLD = 0.01
99-
100-
/** The maximum drive velocity in cm per second. */
101-
const val MAX_DRIVE_VELOCITY = 100.0
102-
103-
/** The maximum drive acceleration in cm per second squared. */
104-
const val MAX_DRIVE_ACCELERATION = 50.0
105-
106-
/** The maximum centripetal acceleration that the robot can handle in cm/s^2. */
107-
const val MAX_CENTRIPETAL_ACCELERATION = (70.0 * 70.0) / 25.0
108-
109-
// X-axis PID coefficients for the trajectory follower
110-
@JvmField var X_KP = 0.0
111-
@JvmField var X_KI = 0.0
112-
@JvmField var X_KD = 0.0
113-
114-
// Y-axis PID coefficients for the trajectory follower
115-
@JvmField var Y_KP = 0.0
116-
@JvmField var Y_KI = 0.0
117-
@JvmField var Y_KD = 0.0
118-
}
119-
120-
object Camera {
121-
// Camera position constants (cm)
122-
private const val X_OFFSET_CM = 0.0
123-
private const val Y_OFFSET_CM = 0.0
124-
private const val Z_OFFSET_CM = 0.0
125-
126-
// Camera orientation constants (degrees)
127-
private const val DEG_TO_RAD = Math.PI / 180.0
128-
private const val YAW_DEG = 0.0
129-
private const val PITCH_DEG = 0.0
130-
private const val ROLL_DEG = 0.0
131-
132-
val POSITION_CM: Position
133-
get() = Position(DistanceUnit.CM, X_OFFSET_CM, Y_OFFSET_CM, Z_OFFSET_CM, 0)
134-
135-
val ORIENTATION_RAD: YawPitchRollAngles
136-
get() = YawPitchRollAngles(AngleUnit.RADIANS, YAW_DEG * DEG_TO_RAD, PITCH_DEG * DEG_TO_RAD, ROLL_DEG * DEG_TO_RAD, 0)
137-
}
58+
object Follower {
59+
/** The threshold in cm to consider the target reached. */
60+
const val POSITION_THRESHOLD = 0.5
61+
62+
/** The threshold in radians to consider the target heading reached. */
63+
const val ROTATION_THRESHOLD = 0.01
64+
65+
/** The maximum drive velocity in cm per second. */
66+
const val MAX_DRIVE_VELOCITY = 100.0
67+
68+
/** The maximum drive acceleration in cm per second squared. */
69+
const val MAX_DRIVE_ACCELERATION = 50.0
70+
71+
/** The maximum centripetal acceleration that the robot can handle in cm/s^2. */
72+
const val MAX_CENTRIPETAL_ACCELERATION = (70.0 * 70.0) / 25.0
73+
74+
// X-axis PID coefficients for the trajectory follower
75+
@JvmField var X_KP = 0.0
76+
@JvmField var X_KI = 0.0
77+
@JvmField var X_KD = 0.0
78+
79+
// Y-axis PID coefficients for the trajectory follower
80+
@JvmField var Y_KP = 0.0
81+
@JvmField var Y_KI = 0.0
82+
@JvmField var Y_KD = 0.0
83+
}
84+
85+
object Camera {
86+
// Camera position constants (cm)
87+
private const val X_OFFSET_CM = 0.0
88+
private const val Y_OFFSET_CM = 0.0
89+
private const val Z_OFFSET_CM = 0.0
90+
91+
// Camera orientation constants (degrees)
92+
private const val DEG_TO_RAD = PI / 180.0
93+
private const val YAW_DEG = 0.0
94+
private const val PITCH_DEG = 0.0
95+
private const val ROLL_DEG = 0.0
96+
97+
val POSITION_CM: Position
98+
get() = Position(DistanceUnit.CM, X_OFFSET_CM, Y_OFFSET_CM, Z_OFFSET_CM, 0)
99+
100+
val ORIENTATION_RAD: YawPitchRollAngles
101+
get() = YawPitchRollAngles(AngleUnit.RADIANS, YAW_DEG * DEG_TO_RAD, PITCH_DEG * DEG_TO_RAD, ROLL_DEG * DEG_TO_RAD, 0)
138102
}

TeamCode/src/main/kotlin/pioneer/hardware/impl/AprilTagImpl.kt renamed to TeamCode/src/main/kotlin/pioneer/hardware/AprilTag.kt

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package pioneer.hardware.impl
1+
package pioneer.hardware
22

33
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit
44
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit
@@ -7,20 +7,18 @@ import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles
77
import org.firstinspires.ftc.vision.apriltag.AprilTagGameDatabase
88
import org.firstinspires.ftc.vision.apriltag.AprilTagLibrary
99
import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor
10-
import pioneer.hardware.interfaces.AprilTag
1110

12-
class AprilTagImpl(
11+
class AprilTag(
1312
position: Position = Position(DistanceUnit.CM, 0.0, 0.0, 0.0, 0),
1413
orientation: YawPitchRollAngles = YawPitchRollAngles(AngleUnit.RADIANS, 0.0, 0.0, 0.0, 0),
15-
) : AprilTag {
16-
14+
) {
1715
private val library: AprilTagLibrary =
1816
AprilTagLibrary
1917
.Builder()
2018
.addTags(AprilTagGameDatabase.getCurrentGameTagLibrary())
2119
.build()
2220

23-
override val processor: AprilTagProcessor =
21+
val processor: AprilTagProcessor =
2422
AprilTagProcessor
2523
.Builder()
2624
.setTagLibrary(library)

0 commit comments

Comments
 (0)