Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rolling comp #198

Merged
merged 24 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e5824be
decrease max auto velocity and acceleration
LucienMorey Mar 15, 2024
d1f1f8b
retune shooter lookup table
LucienMorey Mar 15, 2024
d3697f7
retune controller deadzone and throttle exponential
LucienMorey Mar 15, 2024
eb10d1c
increase auto speed and accel
LucienMorey Mar 15, 2024
9bed22b
reduce breathing speed
LucienMorey Mar 15, 2024
3de9b86
increase auto max accel
LucienMorey Mar 15, 2024
4fb09b2
require slower speed before shooting
LucienMorey Mar 15, 2024
8e656de
increase max chassis vel to 5 m/s
LucienMorey Mar 15, 2024
4beaae8
Updated south notes
Tsunami014 Mar 15, 2024
6a07081
Fixed centre5&4 note auto
Tsunami014 Mar 15, 2024
d06e7e7
Added safety point to help avoid bad starting positions
Tsunami014 Mar 15, 2024
dafb599
Redid the check for intended start pos!
Tsunami014 Mar 15, 2024
6e4459a
reduce autospeeds while debugging paths
LucienMorey Mar 15, 2024
d0a380a
prevent auto state machine from ever being done
LucienMorey Mar 15, 2024
1ce4901
bump up max vel and accel after testing auto
LucienMorey Mar 15, 2024
7af45f8
add new start pose for amp starting auto routines
LucienMorey Mar 15, 2024
bd9b0fa
retune 3m lookup
LucienMorey Mar 15, 2024
58a4820
increase minimum spacing to stage when planning paths
LucienMorey Mar 15, 2024
f332a10
add missing starting location to 5 note auto routine
LucienMorey Mar 15, 2024
59ad1fe
remove old and incorrect comments
LucienMorey Mar 15, 2024
4cfd9dd
add extra waypoint for centre auto paths to help misalignment in pickup
LucienMorey Mar 16, 2024
b9044db
decrease vision angle covariance
LucienMorey Mar 16, 2024
847724a
add additional chassis feedback for imu angle
LucienMorey Mar 16, 2024
fd6f08b
Remapped the slow down button from X to right bumper
Tsunami014 Mar 16, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 37 additions & 17 deletions autonomous/autonomous.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ def __init__(self) -> None:
Path([NotePositions.amp], face_target=True),
Path([PathPositions.avoid_wall, NotePositions.amp], face_target=True),
]
super().__init__(note_paths, shoot_paths)
start_pose = Pose2d(
TeamPoses.RED_TEST_POSE.translation(),
rotation_to_red_speaker(TeamPoses.RED_TEST_POSE.translation()),
)
super().__init__(note_paths, shoot_paths, start_pose)


class PodiumSpeakerAmp(AutoBase):
Expand Down Expand Up @@ -72,11 +76,9 @@ def __init__(self) -> None:
Path([NotePositions.amp], face_target=True),
Path([PathPositions.avoid_wall, NotePositions.amp], face_target=True),
]
# Start pose only needs to be on the correct half of the field,
# so choose the subwoofer
start_pose = Pose2d(
TeamPoses.RED_TEST_POSE.translation(),
rotation_to_red_speaker(TeamPoses.RED_TEST_POSE.translation()),
TeamPoses.RED_AMP_START_POSE.translation(),
rotation_to_red_speaker(TeamPoses.RED_AMP_START_POSE.translation()),
)
super().__init__(note_paths, shoot_paths, start_pose)

Expand All @@ -99,8 +101,8 @@ def __init__(self) -> None:
# Start pose only needs to be on the correct half of the field,
# so choose the subwoofer
start_pose = Pose2d(
TeamPoses.RED_TEST_POSE.translation(),
rotation_to_red_speaker(TeamPoses.RED_TEST_POSE.translation()),
TeamPoses.RED_AMP_START_POSE.translation(),
rotation_to_red_speaker(TeamPoses.RED_AMP_START_POSE.translation()),
)
super().__init__(note_paths, shoot_paths, start_pose)

Expand All @@ -124,8 +126,6 @@ def __init__(self) -> None:
face_target=True,
),
]
# Start pose only needs to be on the correct half of the field,
# so choose the subwoofer
start_pose = Pose2d(
TeamPoses.RED_TEST_POSE.translation(),
rotation_to_red_speaker(TeamPoses.RED_TEST_POSE.translation()),
Expand Down Expand Up @@ -160,8 +160,6 @@ def __init__(self) -> None:
face_target=True,
),
]
# Start pose only needs to be on the correct half of the field,
# so choose the subwoofer
start_pose = Pose2d(
TeamPoses.RED_TEST_POSE.translation(),
rotation_to_red_speaker(TeamPoses.RED_TEST_POSE.translation()),
Expand All @@ -175,18 +173,29 @@ class Centre5Centre4(AutoBase):

def __init__(self) -> None:
note_paths = [
Path([NotePositions.Centre5], face_target=False),
Path(
[
PathPositions.avoid_starting_faults,
PathPositions.avoid_stage_S,
NotePositions.Centre5,
],
face_target=False,
),
Path(
[
PathPositions.avoid_stage_S,
PathPositions.enforce_pickup_angle,
NotePositions.Centre4,
],
face_target=False,
),
]

shoot_paths = [
Path([ShootingPositions.source_side], face_target=True),
Path(
[PathPositions.avoid_stage_S, ShootingPositions.source_side],
face_target=True,
),
Path(
[
PathPositions.avoid_stage_S,
Expand All @@ -195,7 +204,7 @@ def __init__(self) -> None:
face_target=True,
),
]
sim_start_pos = Translation2d(15.4, 2.94)
sim_start_pos = ShootingPositions.source_side
rotation = rotation_to_red_speaker(sim_start_pos)
sim_start_pose = Pose2d(sim_start_pos, rotation)
super().__init__(note_paths, shoot_paths, sim_start_pose)
Expand All @@ -207,10 +216,18 @@ class Centre5Centre4Centre3(AutoBase):

def __init__(self) -> None:
note_paths = [
Path([NotePositions.Centre5], face_target=False),
Path(
[
PathPositions.avoid_starting_faults,
PathPositions.avoid_stage_S,
NotePositions.Centre5,
],
face_target=False,
),
Path(
[
PathPositions.avoid_stage_S,
PathPositions.enforce_pickup_angle,
NotePositions.Centre4,
],
face_target=False,
Expand All @@ -226,7 +243,10 @@ def __init__(self) -> None:
]

shoot_paths = [
Path([ShootingPositions.source_side], face_target=True),
Path(
[PathPositions.avoid_stage_S, ShootingPositions.source_side],
face_target=True,
),
Path(
[
PathPositions.avoid_stage_S,
Expand All @@ -243,7 +263,7 @@ def __init__(self) -> None:
face_target=True,
),
]
sim_start_pos = Translation2d(15.4, 2.94)
sim_start_pos = ShootingPositions.source_side
rotation = rotation_to_red_speaker(sim_start_pos)
sim_start_pose = Pose2d(sim_start_pos, rotation)
super().__init__(note_paths, shoot_paths, sim_start_pose)
12 changes: 5 additions & 7 deletions autonomous/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,13 +152,11 @@ def drive_and_shoot(self, state_tm: float, initial_call: bool) -> None:
if self.is_close_enough_to_shoot():
self.note_manager.try_shoot()

if self.note_manager.has_just_fired() or (
self.is_at_goal() and not self.note_manager.has_note()
):
if len(self.shoot_paths_working_copy) != 0:
self.next_state("pick_up")
else:
self.done()
if (
self.note_manager.has_just_fired()
or (self.is_at_goal() and not self.note_manager.has_note())
) and len(self.shoot_paths_working_copy) != 0:
self.next_state("pick_up")

def drive_on_trajectory(self, trajectory_tm: float):
if not self.trajectory:
Expand Down
6 changes: 5 additions & 1 deletion components/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,10 @@ def __init__(self) -> None:
def get_velocity(self) -> ChassisSpeeds:
return self.kinematics.toChassisSpeeds(self.get_module_states())

@feedback
def imu_rotation(self) -> float:
return self.imu.getAngle()

def get_module_states(
self,
) -> tuple[
Expand All @@ -315,7 +319,7 @@ def setup(self) -> None:
self.get_module_positions(),
initial_pose,
stateStdDevs=(0.05, 0.05, 0.01),
visionMeasurementStdDevs=(0.4, 0.4, 50),
visionMeasurementStdDevs=(0.4, 0.4, 0.03),
)
self.field_obj = self.field.getObject("fused_pose")
self.set_pose(initial_pose)
Expand Down
2 changes: 1 addition & 1 deletion components/led.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
Hsv = tuple[int, int, int]

FLASH_SPEED = 2
BREATHE_SPEED = 4
BREATHE_SPEED = 0.5
RAINBOW_SPEED = 8
MORSE_SPEED = 0.2

Expand Down
12 changes: 6 additions & 6 deletions components/shooter.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ class ShooterComponent:
70,
70,
76,
76,
77,
78,
78,
90,
0,
)
FLYWHEEL_ANGLE_LOOKUP = (
0.96,
0.96,
0.95,
0.95,
0.80,
0.61,
0.50,
0.615,
0.495,
0.45,
MIN_INCLINE_ANGLE,
)
Expand Down
4 changes: 2 additions & 2 deletions controllers/shooter.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class Shooter(StateMachine):

data_log: DataLog

SPEED_LIMIT = tunable(1)
SPINNING_SPEED_LIMIT = tunable(1)
SPEED_LIMIT = tunable(0.1)
SPINNING_SPEED_LIMIT = tunable(0.1)

def __init__(self):
self.range = 0.0
Expand Down
30 changes: 18 additions & 12 deletions robot.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from utilities.game import is_red
from utilities.scalers import rescale_js
from utilities.functions import clamp
from utilities.position import on_same_side_of_stage, y_close_to_stage
from utilities.position import distance_between


class MyRobot(magicbot.MagicRobot):
Expand All @@ -39,14 +39,16 @@ class MyRobot(magicbot.MagicRobot):

status_lights: LightStrip

max_speed = magicbot.tunable(4) # m/s
max_speed = magicbot.tunable(5) # m/s
lower_max_speed = magicbot.tunable(2) # m/s
max_spin_rate = magicbot.tunable(4) # m/s
lower_max_spin_rate = magicbot.tunable(2) # m/s
inclination_angle = tunable(0.0)
vision_port: VisualLocalizer
vision_starboard: VisualLocalizer

START_POS_TOLERANCE = 1

def createObjects(self) -> None:
self.data_log = wpilib.DataLogManager.getLog()

Expand All @@ -71,7 +73,7 @@ def createObjects(self) -> None:
)

def teleopInit(self) -> None:
pass
self.field.getObject("Intended start pos").setPoses([])

def teleopPeriodic(self) -> None:
if self.climber.should_lock_mechanisms():
Expand All @@ -84,13 +86,13 @@ def teleopPeriodic(self) -> None:
# Set max speed
max_speed = self.max_speed
max_spin_rate = self.max_spin_rate
if self.gamepad.getXButton():
if self.gamepad.getRightBumper():
max_speed = self.lower_max_speed
max_spin_rate = self.lower_max_spin_rate

# Driving
drive_x = -rescale_js(self.gamepad.getLeftY(), 0.1) * max_speed
drive_y = -rescale_js(self.gamepad.getLeftX(), 0.1) * max_speed
drive_x = -rescale_js(self.gamepad.getLeftY(), 0.05, 2.5) * max_speed
drive_y = -rescale_js(self.gamepad.getLeftX(), 0.05, 2.5) * max_speed
drive_z = (
-rescale_js(self.gamepad.getRightX(), 0.1, exponential=2) * max_spin_rate
)
Expand Down Expand Up @@ -204,6 +206,7 @@ def disabledPeriodic(self) -> None:
if (
not self.vision_port.sees_target()
and not self.vision_starboard.sees_target()
and not self.isSimulation()
):
self.status_lights.no_vision()
else:
Expand All @@ -213,11 +216,14 @@ def disabledPeriodic(self) -> None:
intended_start_pose = selected_auto.get_starting_pose()
current_pose = self.chassis.get_pose()
if intended_start_pose is not None:
if on_same_side_of_stage(intended_start_pose, current_pose):
if y_close_to_stage(current_pose):
self.status_lights.too_close_to_stage()
else:
self.status_lights.rainbow()
self.field.getObject("Intended start pos").setPose(
intended_start_pose
)
if (
distance_between(intended_start_pose, current_pose)
< self.START_POS_TOLERANCE
):
self.status_lights.rainbow()
else:
self.status_lights.invalid_start()
else:
Expand All @@ -226,7 +232,7 @@ def disabledPeriodic(self) -> None:
self.status_lights.missing_start_pose()

def autonomousInit(self) -> None:
pass
self.field.getObject("Intended start pos").setPoses([])


if __name__ == "__main__":
Expand Down
20 changes: 8 additions & 12 deletions utilities/position.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def __init__(self, waypoints: list[Translation2d], face_target: bool):
self.final_heading = 0


stage_tolerance = 0.35
stage_tolerance = 0.4


class NotePositions:
Expand Down Expand Up @@ -66,30 +66,26 @@ class ShootingPositions:
amp_speaker_bounce = Translation2d(
14.7, (NotePositions.amp.y + NotePositions.speaker.y) / 2
)
source_side = Translation2d(14.7, 2.8)
source_side = Translation2d(15.556, 4.034)


class TeamPoses:
RED_TEST_POSE = Pose2d(15.1, 5.5, math.pi)
BLUE_TEST_POSE = field_flip_pose2d(RED_TEST_POSE)
BLUE_PODIUM = Pose2d(Translation2d(2.992, 4.08455), Rotation2d(math.pi))
RED_PODIUM = field_flip_pose2d(BLUE_PODIUM)
RED_AMP_START_POSE = Pose2d(15.9, 6.7, math.pi)


def on_same_side_of_stage(intended_start_pose: Pose2d, current_pose: Pose2d) -> bool:
return not (
(intended_start_pose.y > TeamPoses.BLUE_PODIUM.y)
^ (current_pose.y > TeamPoses.BLUE_PODIUM.y)
)


def y_close_to_stage(pose: Pose2d) -> bool:
return abs(pose.y - TeamPoses.BLUE_PODIUM.y) < 0.9
def distance_between(intended_start_pose: Pose2d, current_pose: Pose2d) -> float:
return (intended_start_pose.translation() - current_pose.translation()).norm()


class PathPositions:
stage_transition_N = Translation2d(11.4, 4.5)
stage_transition_S = Translation2d(11.4, 3.74)
stage_transition_S_entry = Translation2d(13.0, 2.5)
avoid_wall = Translation2d(10.80, 6.55)
avoid_stage_S = Translation2d(10.66, 1.40)
avoid_stage_S = Translation2d(11.66, 1.40)
avoid_starting_faults = Translation2d(14.429, 2.946)
enforce_pickup_angle = Translation2d(9.6, 1.6)
Loading