Skip to content

Commit

Permalink
Powersaving quick patch for in-flight OreSat
Browse files Browse the repository at this point in the history
The in-flight satellite is experiencing a power drain issue. We've
identified two quick hacks to cut down on power use here:
- Turn off the battery board except when we're about to beacon. This
  means disabling the OPD always_on handling
- Turn off the UHF radio until we're about to beacon. This means that
  TOT_OK will be low (bad) for most of the time, so we only need to
  clear it just before transmitting.
- Turn off UHF for EDL, and turn it off when it's done.
- Fix watchdog service being stopped
  • Loading branch information
ThirteenFish committed Sep 30, 2024
1 parent 02a56ab commit 323ee30
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 20 deletions.
4 changes: 2 additions & 2 deletions oresat_c3/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ def main():
app.od["hw_id"].value = get_hw_id(mock_hw)

state_service = StateService(config.fram_def, mock_hw)
radios_service = RadiosService(mock_hw)
beacon_service = BeaconService(config.beacon_def, radios_service)
radios_service = RadiosService(app.od["status"], mock_hw)
node_mgr_service = NodeManagerService(config.cards, mock_hw)
beacon_service = BeaconService(config.beacon_def, radios_service, node_mgr_service)
edl_service = EdlService(app.node, radios_service, node_mgr_service, beacon_service)

app.add_service(state_service) # add state first to restore state from F-RAM
Expand Down
8 changes: 6 additions & 2 deletions oresat_c3/services/beacon.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@
class BeaconService(Service):
"""Beacon Service."""

def __init__(self, beacon_def: dict, radios_service: RadiosService):
def __init__(self, beacon_def: dict, radios_service: RadiosService, n):
super().__init__()

self.n = n
self._beacon_def = beacon_def
self._radios_service = radios_service
self._ts = 0.0
Expand Down Expand Up @@ -64,10 +65,13 @@ def on_loop(self):
self.sleep(1)
return # do nothing

self.n.enable(0x18)
self.sleep(12)
if self._tx_enabled_obj.value and self._c3_state_obj.value == C3State.BEACON:
self.send()

self.sleep(self._delay_obj.value)
self.n.disable(0x18)
self.sleep(self._delay_obj.value - 12)

def send(self):
"""Send a beacon now."""
Expand Down
2 changes: 0 additions & 2 deletions oresat_c3/services/node_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,6 @@ def on_loop(self):
if self._loops % 10 == 0 and self._data[name].status == NodeState.NOT_FOUND:
self.opd[name].probe(True)

if info.opd_always_on and info.status == NodeState.OFF:
self.enable(name)

if info.status == NodeState.DEAD and self.opd[name].is_enabled:
self.opd[name].disable() # make sure this is disabled
Expand Down
36 changes: 23 additions & 13 deletions oresat_c3/services/radios.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from olaf import Gpio, Service, logger

from ..drivers.si41xx import Si41xx, Si41xxIfdiv
from .. import C3State


class RadiosService(Service):
Expand All @@ -21,10 +22,11 @@ class RadiosService(Service):
BUFFER_LEN = 1024
TOT_CLEAR_DELAY_MS = 10

def __init__(self, mock_hw: bool = False):
def __init__(self, s, mock_hw: bool = False):
super().__init__()

self._mock_hw = mock_hw
self.s = s
self.uhf = False

self._si41xx = Si41xx(
"LBAND_LO_nSEN",
Expand Down Expand Up @@ -75,10 +77,6 @@ def on_start(self):
self.enable()

def on_loop(self):
if not self.is_uhf_tot_okay:
logger.error("tot okay was low, resetting radios")
self.disable()
self.enable()
if not self.is_si41xx_locked:
logger.error("si41xx unlocked, resetting lband synth")
self._relock_count += 1
Expand All @@ -88,6 +86,8 @@ def on_loop(self):
recv = self._recv_edl_request()
if recv:
self.recv_queue.put(recv)
if self.uhf and not self.s.value == C3State.EDL:
self.uhf_off()

def on_stop(self):
self.disable()
Expand All @@ -98,29 +98,22 @@ def enable(self):
logger.info("enabling radios")
self._radio_enable_gpio.high()
self.sleep_ms(100)
self._uhf_enable_gpio.high()
self.sleep_ms(100)
self._lband_enable_gpio.high()
self.uhf_tot_clear()
self._si41xx.start()
self._relock_count += 1
self.node.od["lband"]["synth_relock_count"].value = self._relock_count.bit_length()
if not self._mock_hw:
self.node.daemons["uhf"].start()
self.node.daemons["lband"].start()

def disable(self):
"""Disable the radios."""

logger.info("disabling radios")
if not self._mock_hw:
self.node.daemons["uhf"].stop()
self.node.daemons["lband"].stop()
self._si41xx.stop()
self._lband_enable_gpio.low()
self.sleep_ms(100)
self._uhf_enable_gpio.low()
self.sleep_ms(100)
self._radio_enable_gpio.low()

def uhf_tot_clear(self):
Expand All @@ -145,15 +138,30 @@ def is_si41xx_locked(self) -> bool:
self.node.od["lband"]["synth_lock"].value = state
return state

def uhf_on(self):
self.uhf = True
self._uhf_enable_gpio.high()
self.node.daemons["uhf"].start()
self.sleep_ms(200)
self.uhf_tot_clear()

def uhf_off(self):
self.sleep_ms(100)
self.node.daemons["uhf"].stop()
self._uhf_enable_gpio.low()
self.uhf = False

def send_beacon(self, message: bytes):
"""Send a beacon."""

self.uhf_on()
try:
self._beacon_downlink_socket.sendto(message, self.BEACON_DOWNLINK_ADDR)
except Exception as e: # pylint: disable=W0718
logger.error(f"failed to send beacon message: {e}")

logger.debug(f'Sent beacon downlink packet: {message.hex(sep=" ")}')
self.uhf_off()

def _recv_edl_request(self) -> bytes:
"""Recieve an EDL packet."""
Expand All @@ -170,6 +178,8 @@ def _recv_edl_request(self) -> bytes:
def send_edl_response(self, message: bytes):
"""Send an EDL packet."""

if not self.uhf:
self.uhf_on()
try:
self._edl_downlink_socket.sendto(message, self.EDL_DOWNLINK_ADDR)
except Exception as e: # pylint: disable=W0718
Expand Down
1 change: 0 additions & 1 deletion oresat_c3/services/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ def _reset(self):

result = subprocess.run(
["systemctl", "stop", "oresat-c3-watchdog"],
shell=True,
check=False,
capture_output=True,
)
Expand Down

0 comments on commit 323ee30

Please sign in to comment.