2222from wpimath .units import kilogram_square_meters
2323
2424from components .chassis import SwerveModule
25+ from components .intake import IntakeComponent
2526from components .wrist import WristComponent
2627from utilities import game
2728from utilities .functions import constrain_angle
@@ -78,6 +79,18 @@ def update(self, dt: float) -> None:
7879 )
7980
8081
82+ class SparkArmSim :
83+ def __init__ (self , mech_sim : SingleJointedArmSim , motor_sim : rev .SparkSim ) -> None :
84+ self .mech_sim = mech_sim
85+ self .motor_sim = motor_sim
86+
87+ def update (self , dt : float ) -> None :
88+ vbus = self .motor_sim .getBusVoltage ()
89+ self .mech_sim .setInputVoltage (self .motor_sim .getAppliedOutput () * vbus )
90+ self .mech_sim .update (dt )
91+ self .motor_sim .iterate (self .mech_sim .getVelocity (), vbus , dt )
92+
93+
8194# class ServoEncoderSim:
8295# def __init__(self, pwm, encoder):
8396# self.pwm_sim = PWMSim(pwm)
@@ -127,11 +140,33 @@ def __init__(self, physics_controller: PhysicsInterface, robot: MyRobot):
127140 ),
128141 ]
129142
143+ # Intake arm simulation
144+ intake_arm_gearbox = DCMotor .NEO (1 )
145+ self .intake_arm_motor = rev .SparkMaxSim (
146+ robot .intake_component .arm_motor , intake_arm_gearbox
147+ )
148+ self .intake_arm_encoder_sim = DutyCycleEncoderSim (
149+ robot .intake_component .encoder
150+ )
151+ self .intake_arm = SparkArmSim (
152+ SingleJointedArmSim (
153+ intake_arm_gearbox ,
154+ IntakeComponent .gear_ratio ,
155+ moi = 0.035579622 ,
156+ armLength = 0.22 ,
157+ minAngle = IntakeComponent .DEPLOYED_ANGLE ,
158+ maxAngle = IntakeComponent .RETRACTED_ANGLE ,
159+ simulateGravity = True ,
160+ startingAngle = IntakeComponent .RETRACTED_ANGLE ,
161+ ),
162+ self .intake_arm_motor ,
163+ )
164+
130165 wrist_gearbox = DCMotor .NEO (1 )
131- self . wrist_motor = rev .SparkMaxSim (robot .wrist .motor , wrist_gearbox )
166+ wrist_motor = rev .SparkMaxSim (robot .wrist .motor , wrist_gearbox )
132167 self .wrist_encoder_sim = AnalogEncoderSim (robot .wrist .wrist_encoder )
133168
134- self . wrist_sim = SingleJointedArmSim (
169+ wrist_sim = SingleJointedArmSim (
135170 wrist_gearbox ,
136171 WristComponent .wrist_gear_ratio ,
137172 moi = 0.295209215 ,
@@ -141,6 +176,7 @@ def __init__(self, physics_controller: PhysicsInterface, robot: MyRobot):
141176 simulateGravity = True ,
142177 startingAngle = WristComponent .MAXIMUM_DEPRESSION ,
143178 )
179+ self .wrist = SparkArmSim (wrist_sim , wrist_motor )
144180
145181 self .imu = robot .chassis .imu .sim_state
146182
@@ -166,7 +202,6 @@ def __init__(self, physics_controller: PhysicsInterface, robot: MyRobot):
166202 self .floor_intake = robot .floor_intake
167203 self .reef_intake = robot .reef_intake
168204 self .algae_shooter = robot .algae_shooter
169- self .wrist_component = robot .wrist
170205
171206 def update_sim (self , now : float , tm_diff : float ) -> None :
172207 # Enable the Phoenix6 simulated devices
@@ -214,13 +249,17 @@ def update_sim(self, now: float, tm_diff: float) -> None:
214249 self .vision_sim .update (self .physics_controller .get_pose ())
215250 self .vision_sim_counter = 0
216251
252+ # Update intake arm simulation
253+ self .intake_arm .update (tm_diff )
254+ self .intake_arm_encoder_sim .set (
255+ self .intake_arm .mech_sim .getAngle () + IntakeComponent .ARM_ENCODER_OFFSET
256+ )
257+
217258 # Update wrist simulation
218- self .wrist_sim .setInputVoltage (self .wrist_motor .getAppliedOutput () * 12.0 )
219- self .wrist_sim .update (tm_diff )
259+ self .wrist .update (tm_diff )
220260 self .wrist_encoder_sim .set (
221- self .wrist_sim .getAngle () + WristComponent .ENCODER_ZERO_OFFSET
261+ self .wrist . mech_sim .getAngle () + WristComponent .ENCODER_ZERO_OFFSET
222262 )
223- self .wrist_motor .iterate (self .wrist_sim .getVelocity (), vbus = 12.0 , dt = tm_diff )
224263
225264 # Simulate algae pick up
226265 if self .floor_intake .current_state == "intaking" :
0 commit comments