Skip to content
This repository has been archived by the owner on Feb 9, 2024. It is now read-only.

Commit

Permalink
v3.0.11 alpha
Browse files Browse the repository at this point in the history
*    Double the streaming image size
*    Set MOABIAN version on install
*    Use click for args and black because
*    Shorten info screen
*    MANUAL to JOYSTICK, CLASSIC to PID
*    Use the new pad 8 byte function
*    Isolate GPIO setup for SIGINT handling
*    Deprecate run.py as entry point
*    Add a nice __repr__ for EnvState
*    No longer need to make some *.py executable
*    Grabbing the GPIO pin forces a firmware reset. This takes at least 1
     second. If the user hits ctrl-c, gracefully handle the exception.
  • Loading branch information
scotstan committed Mar 8, 2021
1 parent ec36cea commit 806e731
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 129 deletions.
2 changes: 1 addition & 1 deletion bin/splash
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ gpu_t="$(vcgencmd measure_temp | cut -d '=' -f 2)"
cpu_t1k=$(cat /sys/class/thermal/thermal_zone0/temp)
cpu_t=$(printf %.1f "$((10**3 * $cpu_t1k / 1000))e-3")
temps="$cpu_t° C"
moabian_version="3.0.0"
moabian_version="${MOABIAN:-3.0.0}"
fw_version="$([ -e ~/moab/bin/fwversion ] && ~/moab/bin/fwversion | awk '{print $NF}')"

#
Expand Down
Binary file modified fw/v3.bin
Binary file not shown.
1 change: 1 addition & 0 deletions os/files/etc/environment
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MOABIAN=3.0.11
3 changes: 3 additions & 0 deletions os/setup
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ function layer-classic-moabian
## Remove files from v2.5 (now in ~/moab/bin
rm -f /usr/local/lib/libbcm2835*
rm -f /usr/local/bin/{splash,diagnose,oled}

## /etc/environment file sets MOABIAN=3.x.x for all users
install -pvm 644 files/etc/* /etc
}


Expand Down
21 changes: 15 additions & 6 deletions sw/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,25 @@ def __iter__(self):

@dataclass
class EnvState:
x: float
y: float
vel_x: float
vel_y: float
sum_x: float
sum_y: float
x: float = 0.
y: float = 0.
vel_x: float = 0.
vel_y: float = 0.
sum_x: float = 0.
sum_y: float = 0.

def __iter__(self):
return iter(astuple(self))

def __repr__(self):
return self.__str__()

def __str__(self):
a = f"x,y ({self.x:.3f}, {self.y:.3f}) "
b = f"ẋ,ẏ ({self.vel_x:.3f}, {self.vel_y:.3f}) "
c = f"Δx,Δy {self.sum_x:.3f}, {self.sum_y:.3f})"
return a + b +c


def high_pass_filter(frequency, fc=50):
x_dot_cstate = 0
Expand Down
117 changes: 39 additions & 78 deletions sw/hat.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,6 @@ def _get_sw_version():
return ver_triplet


def setupGPIO():
gpio.setwarnings(False)
gpio.setmode(gpio.BCM)
# Setting pin direction, in our case, reboots Moab!
gpio.setup(
[GpioPin.HAT_EN, GpioPin.HAT_RESET],
gpio.OUT,
)
time.sleep(1.0)


def _xy_offsets(
x: float,
y: float,
Expand Down Expand Up @@ -156,11 +145,11 @@ def plate_angles_to_servo_positions(


# Return an exact 8 byte numpy array
def pad_message(*args, **kwargs):
l = [*args][:8]
p = (8 - len(l)) * [0]
def pad(*args, **kwargs):
data = [*args][:8]
pads = (8 - len(data)) * [0]
dtype = kwargs.pop("dtype", np.int8)
return np.array(l + p, dtype)
return np.array(data + pads, dtype)


class Hat:
Expand Down Expand Up @@ -188,19 +177,29 @@ def open(self):
self.spi = spidev.SpiDev()
self.spi.open(0, 0)
self.spi.max_speed_hz = 100000
except:
except Exception as e:
# possible that ctrl-C was caught here
raise IOError(f"Could not open `/dev/spidev{spi_bus}.{spi_device}`.")

# Attempt to setup the GPIO pins
try:
setupGPIO()
gpio.setwarnings(False)
gpio.setmode(gpio.BCM)
# Setting pin direction, in our case, reboots Moab!
gpio.setup(
[GpioPin.HAT_EN, GpioPin.HAT_RESET],
gpio.OUT,
)
time.sleep(1.0)
except KeyboardInterrupt:
raise
except:
raise IOError(f"Could not setup GPIO pins")

def close(self):
def close(self, text="OFF"):
self.display_string(text)
if self.spi is not None:
self.spi.close()
gpio.cleanup()

def __enter__(self):
self.open()
Expand Down Expand Up @@ -247,30 +246,15 @@ def get_buttons(self) -> Tuple[bool, bool, float, float]:

def noop(self):
"""Send a NOOP. Useful for if you just want to read buttons."""
self.transceive(
np.array(
[SendCommand.NOOP, 0, 0, 0, 0, 0, 0, 0],
dtype=np.int8,
)
)
self.transceive(pad(SendCommand.NOOP))

def enable_servos(self):
""" Set the plate to track plate angles. """
self.transceive(
np.array(
[SendCommand.SERVO_ENABLE, 0, 0, 0, 0, 0, 0, 0],
dtype=np.int8,
)
)
self.transceive(pad(SendCommand.SERVO_ENABLE))

def disable_servos(self):
""" Disables the power to the servos. """
self.transceive(
np.array(
[SendCommand.SERVO_DISABLE, 0, 0, 0, 0, 0, 0, 0],
dtype=np.int8,
)
)
self.transceive(pad(SendCommand.SERVO_DISABLE))

def set_angles(self, plate_x: float, plate_y: float):
# If set_plate_angles flag is set, use the plate to servo conversion on
Expand All @@ -280,12 +264,7 @@ def set_angles(self, plate_x: float, plate_y: float):
# Take into account offsets when converting from degrees to values sent to hat
plate_x, plate_y = _xy_offsets(plate_x, plate_y, self.servo_offsets)
plate_x, plate_y = -plate_x, -plate_y
self.transceive(
np.array(
[SendCommand.SET_PLATE_ANGLES, plate_x, plate_y, 0, 0, 0, 0, 0],
dtype=np.uint8,
)
)
self.transceive(pad(SendCommand.SET_PLATE_ANGLES, plate_x, plate_y))

else:
s1, s2, s3 = plate_angles_to_servo_positions(-plate_x, -plate_y)
Expand Down Expand Up @@ -315,18 +294,14 @@ def set_servos(self, servo1: float, servo2: float, servo3: float):
servo3_centi_degrees_low_byte = servo3_centi_degrees & 0x00FF

self.transceive(
np.array(
[
SendCommand.SET_SERVOS,
servo3_centi_degrees_high_byte,
servo3_centi_degrees_low_byte,
servo1_centi_degrees_high_byte,
servo1_centi_degrees_low_byte,
servo2_centi_degrees_high_byte,
servo2_centi_degrees_low_byte,
0,
],
dtype=np.uint8,
pad(
SendCommand.SET_SERVOS,
servo3_centi_degrees_high_byte,
servo3_centi_degrees_low_byte,
servo1_centi_degrees_high_byte,
servo1_centi_degrees_low_byte,
servo2_centi_degrees_high_byte,
servo2_centi_degrees_low_byte,
)
)

Expand Down Expand Up @@ -385,8 +360,8 @@ def set_icon_text(self, icon_idx: Icon, text_idx: Text):
2: ("POWER_OFF", False),
3: ("ERROR", True),
4: ("CALIBRATE", True),
5: ("MANUAL", True),
6: ("CLASSIC", True),
5: ("JOYSTICK", True),
6: ("PID", True),
7: ("BRAIN", True),
8: ("CUSTOM 1", True),
9: ("CUSTOM 2", True),
Expand Down Expand Up @@ -416,12 +391,7 @@ def display_string_icon(self, text: str, icon_idx: Icon):
self._copy_buffer(text)

# After sending copying to the fw buffer, display the buffer as a long string
self.transceive(
np.array(
[SendCommand.DISPLAY_BIG_TEXT_ICON, icon_idx, 0, 0, 0, 0, 0, 0],
dtype=np.int8,
)
)
self.transceive(pad(SendCommand.DISPLAY_BIG_TEXT_ICON, icon_idx))

def display_string(self, text: str):
assert len(text) <= 15, "String is too long to diplay without scrolling."
Expand All @@ -437,12 +407,8 @@ def display_string(self, text: str):
self._copy_buffer(text)

# After sending copying to the fw buffer, display the buffer as a long string
self.transceive(
np.array(
[SendCommand.DISPLAY_BIG_TEXT, 0, 0, 0, 0, 0, 0, 0],
dtype=np.int8,
)
)
self.transceive(pad(SendCommand.DISPLAY_BIG_TEXT))


def display_long_string(self, text: str):
# reset the text/icon index optimization hack
Expand All @@ -453,18 +419,13 @@ def display_long_string(self, text: str):
self._copy_buffer(text)

# After sending copying to the fw buffer, display the buffer as a long string
self.transceive(
np.array(
[SendCommand.DISPLAY_SMALL_TEXT_SCROLLING, 0, 0, 0, 0, 0, 0, 0],
dtype=np.int8,
)
)
self.transceive(pad(SendCommand.DISPLAY_SMALL_TEXT_SCROLLING))


def print_info_screen(self):
sw_major, sw_minor, sw_bug = _get_sw_version()
ip1, ip2, ip3, ip4 = _get_host_ip()
self.display_long_string(
f"PROJECT MOAB\n"
f"SW VERSION\n{sw_major}.{sw_minor}.{sw_bug}\n"
f"IP ADDRESS:\n{ip1}.{ip2}.{ip3}.{ip4}"
f"VER: {sw_major}.{sw_minor}.{sw_bug}\n"
f"IP : {ip1}.{ip2}.{ip3}.{ip4}\n"
)
Empty file modified sw/hexyl.py
100755 → 100644
Empty file.
Loading

0 comments on commit 806e731

Please sign in to comment.