Skip to content

Commit c61d501

Browse files
authored
Merge pull request #116 from Open-STEM/boardRefactor
Route per-board logic through Board.get_type()
2 parents 88a52f8 + 9d29432 commit c61d501

7 files changed

Lines changed: 44 additions & 38 deletions

File tree

XRPLib/board.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,26 @@ class Board:
77

88
_DEFAULT_BOARD_INSTANCE = None
99

10+
# Board identity. The one place a machine name is matched; everything else compares
11+
# against these constants (see get_type).
12+
XRP = 0
13+
BETA = 1
14+
NANO = 2
15+
_type = None
16+
17+
@classmethod
18+
def get_type(cls) -> int:
19+
"""
20+
Identify which XRP board this code is running on.
21+
22+
:return: One of Board.XRP, Board.BETA, or Board.NANO
23+
:rtype: int
24+
"""
25+
if cls._type is None:
26+
machine = sys.implementation._machine
27+
cls._type = cls.NANO if "NanoXRP" in machine else cls.BETA if "Beta" in machine else cls.XRP
28+
return cls._type
29+
1030
@classmethod
1131
def get_default_board(cls):
1232
"""
@@ -47,9 +67,9 @@ def are_motors_powered(self) -> bool:
4767
:return: Returns true if the batteries are connected and powering the motors, false otherwise
4868
:rytpe: bool
4969
"""
50-
if "NanoXRP" in sys.implementation._machine:
70+
if Board.get_type() == Board.NANO:
5171
return True
52-
72+
5373
threshold_voltage = 4.272
5474
return self.get_battery_voltage() > threshold_voltage
5575

@@ -141,7 +161,7 @@ def get_battery_voltage(self, vin_pin="BOARD_VIN_MEASURE") -> float:
141161
:rtype: float
142162
"""
143163

144-
if "NanoXRP" in sys.implementation._machine:
164+
if Board.get_type() == Board.NANO:
145165
# VIN pin on NanoXRP is also used for RM2.
146166
self.on_switch = ADC(Pin(vin_pin))
147167

XRPLib/dashboard.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from .rangefinder import Rangefinder
33
from .imu import IMU
44
from .reflectance import Reflectance
5+
from .board import Board
56
from .puppet import Puppet, VAR_TYPE_INT, VAR_TYPE_FLOAT, PERM_READ_ONLY
67

78
from machine import Timer, ADC, Pin
@@ -82,7 +83,7 @@ def __init__(self):
8283
self.imu = IMU.get_default_imu()
8384
self.rangefinder = Rangefinder.get_default_rangefinder()
8485
self.reflectance = Reflectance.get_default_reflectance()
85-
self.VoltageADC = ADC(Pin('BOARD_VIN_MEASURE'))
86+
self.board = Board.get_default_board()
8687
#self.CurrLADC = ADC(Pin('ML_CUR'))
8788
#self.CurrRADC = ADC(Pin('MR_CUR'))
8889
#self.Curr3ADC = ADC(Pin('M3_CUR'))
@@ -188,7 +189,7 @@ def _dashboard_update(self):
188189
self._puppet.set_variable('$reflectance.right', self.reflectance.get_right())
189190

190191
# Voltage
191-
voltage = self.VoltageADC.read_u16() / (1024*64/14)
192+
voltage = self.board.get_battery_voltage()
192193
self._puppet.set_variable('$voltage', voltage)
193194

194195
def start(self, rate_hz=3):

XRPLib/differential_drive.py

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from .timeout import Timeout
77
import time
88
import math
9-
from sys import implementation
109

1110
class DifferentialDrive:
1211

@@ -38,9 +37,9 @@ def __init__(self, left_motor: EncodedMotor, right_motor: EncodedMotor, imu: IMU
3837
:type rightMotor: EncodedMotor
3938
:param imu: The IMU of the robot. If None, the robot will not use the IMU for turning or maintaining heading.
4039
:type imu: IMU
41-
:param wheelDiam: The diameter of the wheels in inches. Defaults to 6 cm.
40+
:param wheelDiam: The diameter of the wheels in cm.
4241
:type wheelDiam: float
43-
:param wheelTrack: The distance between the wheels in inches. Defaults to 15.5 cm.
42+
:param wheelTrack: The distance between the wheels in cm.
4443
:type wheelTrack: float
4544
"""
4645

@@ -53,27 +52,18 @@ def __init__(self, left_motor: EncodedMotor, right_motor: EncodedMotor, imu: IMU
5352
# Resolve hardware defaults when the caller leaves the arg at its 0.0 sentinel;
5453
# honor any explicit non-zero value that is passed in.
5554
if wheel_diam == 0.0:
56-
if "NanoXRP" in implementation._machine:
57-
self.wheel_diam = 3.46
58-
else:
59-
self.wheel_diam = 6.0
55+
self.wheel_diam = 3.46 if Board.get_type() == Board.NANO else 6.0
6056
else:
6157
self.wheel_diam = wheel_diam
6258

6359
if wheel_track == 0.0:
64-
if "NanoXRP" in implementation._machine:
65-
self.wheel_track = 7.8
66-
else:
67-
self.wheel_track = 15.5
60+
self.wheel_track = 7.8 if Board.get_type() == Board.NANO else 15.5
6861
else:
6962
self.wheel_track = wheel_track
7063

7164
# Effort is raw PWM duty, so torque scales with pack voltage. Gains are tuned against
7265
# nominal_voltage and voltage_scale corrects the duty for the pack actually installed.
73-
if "NanoXRP" in implementation._machine:
74-
self.nominal_voltage = 4.2
75-
else:
76-
self.nominal_voltage = 6.0
66+
self.nominal_voltage = 4.2 if Board.get_type() == Board.NANO else 6.0
7767

7868
self.voltage_scale = 1.0
7969
self.update_voltage_compensation()
@@ -84,7 +74,7 @@ def __init__(self, left_motor: EncodedMotor, right_motor: EncodedMotor, imu: IMU
8474
self._holding_heading = False
8575

8676
if self.imu:
87-
if "NanoXRP" in implementation._machine:
77+
if Board.get_type() == Board.NANO:
8878
self.heading_pid = PID(kp=0.014, kd=0.001)
8979
else:
9080
self.heading_pid = PID(kp=0.064, kd=0.0045)
@@ -224,9 +214,9 @@ def _move(self, distance_target: float, heading_target: float, max_effort: float
224214
Shared translation/rotation controller for straight() and turn().
225215
"""
226216

227-
if "NanoXRP" in implementation._machine:
217+
if Board.get_type() == Board.NANO:
228218
if min_effort is None:
229-
min_effort = 0.10
219+
min_effort = 0.10
230220

231221
if distance_controller is None:
232222
distance_controller = PID(

XRPLib/encoded_motor.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from machine import Timer, Pin
44
from .controller import Controller
55
from .pid import PID
6-
from sys import implementation
6+
from .board import Board
77

88
class EncodedMotor:
99

@@ -25,10 +25,7 @@ def get_default_encoded_motor(cls, index:int = 1):
2525
:type index: int
2626
"""
2727

28-
if "Beta" in implementation._machine:
29-
MotorImplementation = SinglePWMMotor
30-
else:
31-
MotorImplementation = DualPWMMotor
28+
MotorImplementation = SinglePWMMotor if Board.get_type() == Board.BETA else DualPWMMotor
3229

3330
if index == 1:
3431
if cls._DEFAULT_LEFT_MOTOR_INSTANCE is None:
@@ -70,7 +67,7 @@ def __init__(self, motor, encoder: Encoder):
7067
self.brake_at_zero = False
7168

7269
self.target_speed = None
73-
if "NanoXRP" in implementation._machine:
70+
if Board.get_type() == Board.NANO:
7471
self.DEFAULT_SPEED_CONTROLLER = PID(
7572
kp=0.015,
7673
ki=0.06,

XRPLib/encoder.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
import machine
44
import rp2
55
import time
6-
from sys import implementation
6+
from .board import Board
77
import re
88

99
class Encoder:
10-
if "NanoXRP" in implementation._machine:
10+
if Board.get_type() == Board.NANO:
1111
_gear_ratio = (68/1)
1212
_counts_per_motor_shaft_revolution = 12
1313
else:

XRPLib/imu.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# Import wrapped in a try/except so that autodoc generation can process properly
1212
pass
1313
from machine import I2C, Pin, Timer, disable_irq, enable_irq
14-
from sys import implementation
14+
from .board import Board
1515
import time, math
1616

1717
class IMU():
@@ -30,7 +30,8 @@ def get_default_imu(cls):
3030
return cls._DEFAULT_IMU_INSTANCE
3131

3232
def __init__(self, scl_pin: int|str = "I2C_SCL_1", sda_pin: int|str = "I2C_SDA_1", addr=LSM_ADDR_PRIMARY):
33-
self._is_nanoxrp = "NanoXRP" in implementation._machine
33+
# Cached once at construction so the hard-IRQ update handler never calls get_type().
34+
self._is_nanoxrp = Board.get_type() == Board.NANO
3435

3536
# I2C values
3637
self.i2c = I2C(id=1, scl=Pin(scl_pin), sda=Pin(sda_pin), freq=400000)

XRPLib/motor.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from machine import Pin, PWM
2-
from sys import implementation
2+
from .board import Board
33

44
class SinglePWMMotor:
55

@@ -57,10 +57,7 @@ class DualPWMMotor:
5757

5858
def __init__(self, in1_pwm_forward: int|str, in2_pwm_backward: int|str, flip_dir:bool=False):
5959

60-
if "NanoXRP" in implementation._machine:
61-
self.flip_dir = not flip_dir
62-
else:
63-
self.flip_dir = flip_dir
60+
self.flip_dir = (not flip_dir) if Board.get_type() == Board.NANO else flip_dir
6461

6562
self._MAX_PWM = 65535 # Motor holds when actually at full power
6663

0 commit comments

Comments
 (0)