def init_sensors(self): self.radio = Radio() self.gom = Gomspace(self.parameters) self.gyro = GyroSensor() self.adc = ADC(self.gyro) self.rtc = RTC() # self.pressure_sensor = PressureSensor() # pass through self so need_to_burn boolean function # in pressure_sensor (to be made) can access burn queue""" # initialize the cameras, select a camera logger.info("Creating camera mux...") self.mux = camera.CameraMux() self.camera = camera.Camera() logger.info("Selecting a camera...") # select camera before reboot so that we will detect cam on reboot self.mux.selectCamera(random.choice([1, 2, 3]))
def check_radio(): try: Radio() except Exception as e: log_error(e) logger.error( "RADIO init Failed. Make sure radio/comms board connectors are correct" ) else: logger.info("RADIO initialization successful")
from communications.satellite_radio import Radio from communications.downlink import DownlinkHandler groundstation = Radio() dh = DownlinkHandler() print('Receiving...') while True: downlink = groundstation.receiveSignal() if downlink is not None: print('Downlink Received') print(dh.unpack_downlink(downlink))
from communications.satellite_radio import Radio from drivers.gom import Gomspace import utils.parameters as params from time import sleep radio = Radio() gom = Gomspace() electrolyzing = False interval = 3 # Number of seconds between each transmission repetitions = 5 # Number of total times you want to transmit the pattern downlink = bytes( input("Enter signal you want to downlink (e.g '\\x08\\x07\\x00\\x00)':"), encoding='utf-8') downlink = downlink.decode('unicode-escape').encode('ISO-8859-1') #––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––– # Enter Transmit Mode #Stop electrolyzing if gom.is_electrolyzing(): electrolyzing = True gom.set_electrolysis(False) print('Electrolyzers turned off') #Set RF receiving side to low gom.rf_receiving_switch(receive=False) print('RF Receiving set to low') #Turn off LNA gom.lna(False)
from communications.satellite_radio import Radio from communications.commands import CommandHandler from communications.downlink import DownlinkHandler import time # Setup ch = CommandHandler() dh = DownlinkHandler() groundstation = Radio() # Send command to get gyro/mag/acc data gmaCommand = ch.pack_command(1, 8, 7) groundstation.transmit(gmaCommand) print('GMA Command Transmitted') # Listen for response print('Receiving...') cycle = 1 while True: print('Receiving Cycle: ' + str(cycle)) downlink = groundstation.receiveSignal() if downlink is not None: print('Downlink Received:') data = dh.unpack_downlink(downlink)[-1] print('Gyro: ' + str(data['gyro1']) + ', ' + str(data['gyro2']) + ', ' + str(data['gyro3'])) break
from communications.satellite_radio import Radio #Initialize variables, nothing to modify on this end transmissionCounter = 0 radio = Radio() while True: message = radio.receiveSignal() if message is not None: print('Transmission #' + transmissionCounter + ' Received: ' + str(message))
class MainSatelliteThread(Thread): def __init__(self): super().__init__() logger.info("Initializing...") self.init_parameters() self.command_queue = Queue() self.downlink_queue = Queue() self.FMQueue = Queue() self.commands_to_execute = [] self.downlinks_to_execute = [] self.telemetry = Telemetry(self) self.burn_queue = Queue() self.reorientation_queue = Queue() self.reorientation_list = [] self.maneuver_queue = Queue() # maneuver queue self.opnav_queue = Queue() # determine state of opnav success # self.init_comms() self.command_handler = CommandHandler() self.downlink_handler = DownlinkHandler() self.command_counter = 0 self.downlink_counter = 0 self.command_definitions = CommandDefinitions(self) self.last_opnav_run = datetime.now() # Figure out what to set to for first opnav run self.log_dir = LOG_DIR self.logger = get_log() self.attach_sigint_handler() # FIXME self.need_to_reboot = False self.gom = None self.gyro = None self.adc = None self.rtc = None self.radio = None self.mux = None self.camera = None self.init_sensors() # Telemetry self.tlm = Telemetry(self) # Opnav subprocess variables self.opnav_proc_queue = Queue() self.opnav_process = Process() # define the subprocess if os.path.isdir(self.log_dir): self.flight_mode = RestartMode(self) else: os.makedirs(CISLUNAR_BASE_DIR, exist_ok=True) os.mkdir(LOG_DIR) self.flight_mode = BootUpMode(self) self.create_session = create_sensor_tables_from_path(DB_FILE) def init_comms(self): self.comms = CommunicationsSystem( queue=self.command_queue, use_ax5043=False ) self.comms.listen() def init_parameters(self): with open(PARAMETERS_JSON_PATH) as f: json_parameter_dict = load(f) try: for parameter in utils.parameters.__dir__(): if parameter[0] != '_': utils.parameters.__setattr__(parameter, json_parameter_dict[parameter]) except: raise Exception( 'Attempted to set parameter ' + str(parameter) + ', which could not be found in parameters.json' ) def init_sensors(self): try: self.gom = Gomspace() except: self.gom = None logger.error("GOM initialization failed") else: logger.info("Gom initialized") try: self.gyro = GyroSensor() except: self.gyro = None logger.error("GYRO initialization failed") else: logger.info("Gyro initialized") try: self.adc = ADC(self.gyro) self.adc.read_temperature() except: self.adc = None logger.error("ADC initialization failed") else: logger.info("ADC initialized") try: self.rtc = RTC() except: self.rtc = None logger.error("RTC initialization failed") else: logger.info("RTC initialized") try: self.nemo_manager = NemoManager(data_dir=NEMO_DIR, reset_gpio_ch=16) except: self.nemo_manager = None logger.error("NEMO initialization failed") else: logger.info("NEMO initialized") try: self.radio = Radio() except: self.radio = None logger.error("RADIO initialization failed") else: logger.info("Radio initialized") # initialize the Mux, select a camera try: self.mux = camera.CameraMux() self.mux.selectCamera(1) except: self.mux = None logger.error("MUX initialization failed") else: logger.info("Mux initialized") cameras_list = [0, 0, 0] # initialize cameras only if not a hard boot (or first boot) if not hard_boot() and os.path.isdir(self.log_dir): try: self.camera = camera.Camera() for i in [1, 2, 3]: try: self.mux.selectCamera(i) f, t = self.camera.rawObservation(f"initialization-{i}-{int(time())}") except Exception as e: logger.error(f"CAM{i} initialization failed") cameras_list[i - 1] = 0 else: logger.info(f"Cam{i} initialized") cameras_list[i - 1] = 1 if 0 in cameras_list: raise e except: self.camera = None logger.error(f"Cameras initialization failed") else: logger.info("Cameras initialized") else: self.need_to_reboot = True # make a bitmask of the initialized sensors for downlinking sensors = [self.gom, self.radio, self.gyro, self.adc, self.rtc, self.mux, self.camera] sensor_functioning_list = [int(bool(sensor)) for sensor in sensors] sensor_functioning_list.extend(cameras_list) sensor_bitmask = ''.join(map(str, sensor_functioning_list)) logger.debug(f"Sensors: {sensor_bitmask}") return int(sensor_bitmask, 2) def handle_sigint(self, signal, frame): self.shutdown() sys.exit(0) def attach_sigint_handler(self): signal.signal(signal.SIGINT, self.handle_sigint) def poll_inputs(self): self.flight_mode.poll_inputs() #Telemetry downlink if (datetime.today() - self.radio.last_telemetry_time).total_seconds()/60 >= params.TELEM_DOWNLINK_TIME: telemetry = self.command_definitions.gather_basic_telem() telem_downlink = ( self.downlink_handler.pack_downlink(self.downlink_counter, FMEnum.Normal.value, NormalCommandEnum.BasicTelem.value, **telemetry)) self.downlink_queue.put(telem_downlink) self.radio.last_telemetry_time = datetime.today() # Listening for new commands newCommand = self.radio.receiveSignal() if newCommand is not None: try: unpackedCommand = self.command_handler.unpack_command(newCommand) if unpackedCommand[0] == MAC: if unpackedCommand[1] == self.command_counter + 1: self.command_queue.put(bytes(newCommand)) self.command_counter += 1 else: logger.warning('Command with Invalid Counter Received. Counter: ' + str(unpackedCommand[1])) else: logger.warning('Unauthenticated Command Received') except: logger.error('Invalid Command Received') else: logger.debug('Not Received') def replace_flight_mode_by_id(self, new_flight_mode_id): self.replace_flight_mode(build_flight_mode(self, new_flight_mode_id)) def replace_flight_mode(self, new_flight_mode): self.flight_mode = new_flight_mode self.logger.info(f"Changed to FM#{self.flight_mode.flight_mode_id}") def update_state(self): fm_to_update_to = self.flight_mode.update_state() # only replace the current flight mode if it needs to change (i.e. dont fix it if it aint broken!) if fm_to_update_to is None: pass elif fm_to_update_to != NO_FM_CHANGE and fm_to_update_to != self.flight_mode.flight_mode_id: self.replace_flight_mode_by_id(fm_to_update_to) def clear_command_queue(self): while not self.command_queue.empty(): command = self.command_queue.get() logger.debug(f"Throwing away command: {command}") def reset_commands_to_execute(self): self.commands_to_execute = [] # Execute received commands def execute_commands(self): assert ( len(self.commands_to_execute) == 0 ), "Didn't finish executing previous commands" while not self.command_queue.empty(): self.commands_to_execute.append(self.command_queue.get()) self.flight_mode.execute_commands() def read_command_queue_from_file(self, filename="communications/command_queue.txt"): """A temporary workaround to not having radio board access""" # check if file exists if os.path.isfile(filename): text_file = open(filename, "r") for hex_line in text_file: self.command_queue.put(bytes.fromhex(hex_line)) text_file.close() # delete file os.remove(filename) # Run the current flight mode def run_mode(self): with self.flight_mode: self.flight_mode.run_mode() # Wrap in try finally block to ensure it stays live def run(self): """This is the main loop of the Cislunar Explorers and runs constantly during flight.""" try: while True: sleep(5) # TODO remove when flight modes execute real tasks self.poll_inputs() self.update_state() self.read_command_queue_from_file() self.execute_commands() # Set goal or execute command immediately self.run_mode() # Opnav subprocess management # TODO: This all needs to be moved to the OpNav Flight mode, and should not be in main!!! finally: # TODO handle failure gracefully if FOR_FLIGHT is True: self.replace_flight_mode_by_id(FMEnum.Safety.value) self.run() else: self.shutdown() def shutdown(self): if self.gom is not None: self.gom.all_off() if self.nemo_manager is not None: self.nemo_manager.close() logger.critical("Shutting down flight software")
def init_sensors(self): try: self.gom = Gomspace() except: self.gom = None logger.error("GOM initialization failed") else: logger.info("Gom initialized") try: self.gyro = GyroSensor() except: self.gyro = None logger.error("GYRO initialization failed") else: logger.info("Gyro initialized") try: self.adc = ADC(self.gyro) self.adc.read_temperature() except: self.adc = None logger.error("ADC initialization failed") else: logger.info("ADC initialized") try: self.rtc = RTC() except: self.rtc = None logger.error("RTC initialization failed") else: logger.info("RTC initialized") try: self.nemo_manager = NemoManager(data_dir=NEMO_DIR, reset_gpio_ch=16) except: self.nemo_manager = None logger.error("NEMO initialization failed") else: logger.info("NEMO initialized") try: self.radio = Radio() except: self.radio = None logger.error("RADIO initialization failed") else: logger.info("Radio initialized") # initialize the Mux, select a camera try: self.mux = camera.CameraMux() self.mux.selectCamera(1) except: self.mux = None logger.error("MUX initialization failed") else: logger.info("Mux initialized") cameras_list = [0, 0, 0] # initialize cameras only if not a hard boot (or first boot) if not hard_boot() and os.path.isdir(self.log_dir): try: self.camera = camera.Camera() for i in [1, 2, 3]: try: self.mux.selectCamera(i) f, t = self.camera.rawObservation(f"initialization-{i}-{int(time())}") except Exception as e: logger.error(f"CAM{i} initialization failed") cameras_list[i - 1] = 0 else: logger.info(f"Cam{i} initialized") cameras_list[i - 1] = 1 if 0 in cameras_list: raise e except: self.camera = None logger.error(f"Cameras initialization failed") else: logger.info("Cameras initialized") else: self.need_to_reboot = True # make a bitmask of the initialized sensors for downlinking sensors = [self.gom, self.radio, self.gyro, self.adc, self.rtc, self.mux, self.camera] sensor_functioning_list = [int(bool(sensor)) for sensor in sensors] sensor_functioning_list.extend(cameras_list) sensor_bitmask = ''.join(map(str, sensor_functioning_list)) logger.debug(f"Sensors: {sensor_bitmask}") return int(sensor_bitmask, 2)
from communications.satellite_radio import Radio from communications.commands import CommandHandler from flight_modes.flight_mode_factory import FLIGHT_MODE_DICT import time ch = CommandHandler() groundstation = Radio() commandCounter = 1 transmitInterval = 3 while True: commandInput = input('Enter command in the form "Mode ID,Command ID, Keyword Arguments" (e.g 2,3,delay=3,state=True):') commandArguments = commandInput.split(',') mode_id = int(commandArguments[0]) command_id = int(commandArguments[1]) kwargs = {} if len(commandArguments) > 2: argsList = commandArguments[2:] for i in range(len(argsList)): signIndex = argsList[i].index('=') argName = argsList[i][:signIndex] argValue = argsList[i][signIndex +1:] arg_type = FLIGHT_MODE_DICT[mode_id].command_arg_types[argName] if arg_type == 'int' or arg_type == 'short': argValue = int(argValue) elif arg_type == 'float' or arg_type == 'double': argValue = float(argValue)
from communications.satellite_radio import Radio from communications.commands import CommandHandler from communications.downlink import DownlinkHandler from flight_modes.flight_mode_factory import FLIGHT_MODE_DICT import time from utils.log import get_log logger = get_log() ch = CommandHandler() dh = DownlinkHandler() groundstation = Radio() commandCounter = 1 transmitInterval = 3 rx_wait_time = 20 # seconds while True: commandInput = input( 'Enter command in the form "Mode ID,Command ID, Keyword Arguments" (e.g 2,3,delay=3,state=True):' ) commandArguments = commandInput.split(',') mode_id = int(commandArguments[0]) command_id = int(commandArguments[1]) kwargs = {} if len(commandArguments) > 2: argsList = commandArguments[2:] for i in range(len(argsList)): signIndex = argsList[i].index('=')
class MainSatelliteThread(Thread): def __init__(self): super().__init__() logger.info("Initializing...") self.init_parameters() self.command_queue = Queue() self.downlink_queue = Queue() self.FMQueue = Queue() self.commands_to_execute = [] self.downlinks_to_execute = [] self.telemetry = Telemetry(self) self.burn_queue = Queue() self.reorientation_queue = Queue() self.reorientation_list = [] self.maneuver_queue = Queue() # maneuver queue # self.init_comms() self.command_handler = CommandHandler() self.downlink_handler = DownlinkHandler() self.command_counter = 0 self.downlink_counter = 0 self.command_definitions = CommandDefinitions(self) self.init_sensors() self.last_opnav_run = datetime.now() # Figure out what to set to for first opnav run self.log_dir = LOG_DIR self.logger = get_log() self.attach_sigint_handler() # FIXME if os.path.isdir(self.log_dir): self.flight_mode = RestartMode(self) else: os.makedirs(CISLUNAR_BASE_DIR) os.mkdir(LOG_DIR) self.flight_mode = BootUpMode(self) self.create_session = create_sensor_tables_from_path(DB_FILE) def init_comms(self): self.comms = CommunicationsSystem( queue=self.command_queue, use_ax5043=False ) self.comms.listen() def init_parameters(self): with open(PARAMETERS_JSON_PATH) as f: json_parameter_dict = load(f) self.parameters = json_parameter_dict # try: # for parameter in self.parameters.__dir__(): # if parameter[0] != '_': # self.parameters[parameter] = json_parameter_dict[parameter] # except: # raise Exception( # 'Attempted to set parameter ' + str(parameter) + # ', which could not be found in parameters.json' # ) def init_sensors(self): self.radio = Radio() self.gom = Gomspace(self.parameters) self.gyro = GyroSensor() self.adc = ADC(self.gyro) self.rtc = RTC() # self.pressure_sensor = PressureSensor() # pass through self so need_to_burn boolean function # in pressure_sensor (to be made) can access burn queue""" # initialize the cameras, select a camera logger.info("Creating camera mux...") self.mux = camera.CameraMux() self.camera = camera.Camera() logger.info("Selecting a camera...") # select camera before reboot so that we will detect cam on reboot self.mux.selectCamera(random.choice([1, 2, 3])) def handle_sigint(self, signal, frame): self.shutdown() sys.exit(0) def attach_sigint_handler(self): signal.signal(signal.SIGINT, self.handle_sigint) def poll_inputs(self): # self.tlm.poll() self.flight_mode.poll_inputs() # Telemetry downlink if (datetime.today() - self.radio.last_telemetry_time).total_seconds() / 60 >= self.parameters[ "TELEM_DOWNLINK_TIME"]: self.enter_transmit_safe_mode() telemetry = self.command_definitions.gather_basic_telem() telem_downlink = ( self.downlink_handler.pack_downlink(self.downlink_counter, FMEnum.Normal.value, NormalCommandEnum.BasicTelem.value, **telemetry)) self.downlink_queue.put(telem_downlink) # Listening for new commands newCommand = self.radio.receiveSignal() if newCommand is not None: try: unpackedCommand = self.command_handler.unpack_command(newCommand) if unpackedCommand[0] == MAC: if unpackedCommand[1] == self.command_counter + 1: print('hello') self.command_queue.put(bytes(newCommand)) self.command_counter += 1 else: print('Command with Invalid Counter Received. ' + 'Counter: ' + str(unpackedCommand[1])) else: print('Unauthenticated Command Received') except: print('Invalid Command Received') else: print('Not Received') def enter_transmit_safe_mode(self): # TODO: Make sure that everything else is turned off before transmitting pass def replace_flight_mode_by_id(self, new_flight_mode_id): self.replace_flight_mode(build_flight_mode(self, new_flight_mode_id)) def replace_flight_mode(self, new_flight_mode): self.flight_mode = new_flight_mode self.logger.info(f"Changed to FM#{self.flight_mode.flight_mode_id}") def update_state(self): fm_to_update_to = self.flight_mode.update_state() # only replace the current flight mode if it needs to change (i.e. dont fix it if it aint broken!) if fm_to_update_to is None: pass elif fm_to_update_to != NO_FM_CHANGE and fm_to_update_to != self.flight_mode.flight_mode_id: self.replace_flight_mode_by_id(fm_to_update_to) def clear_command_queue(self): while not self.command_queue.empty(): command = self.command_queue.get() print(f"Throwing away command: {command}") def reset_commands_to_execute(self): self.commands_to_execute = [] # Execute received commands def execute_commands(self): assert ( len(self.commands_to_execute) == 0 ), "Didn't finish executing previous commands" while not self.command_queue.empty(): self.commands_to_execute.append(self.command_queue.get()) self.flight_mode.execute_commands() def execute_downlinks(self): self.enter_transmit_safe_mode() while not self.downlink_queue.empty(): self.radio.transmit(self.downlink_queue.get()) self.downlink_counter += 1 sleep(self.parameters["DOWNLINK_BUFFER_TIME"]) def read_command_queue_from_file(self, filename="communications/command_queue.txt"): """A temporary workaround to not having radio board access""" # check if file exists if os.path.isfile(filename): text_file = open(filename, "r") for hex_line in text_file: self.command_queue.put(bytes.fromhex(hex_line)) text_file.close() # delete file os.remove(filename) # Run the current flight mode def run_mode(self): with self.flight_mode: self.flight_mode.run_mode() # Wrap in try finally block to ensure it stays live def run(self): """This is the main loop of the Cislunar Explorers and runs constantly during flight.""" try: while True: sleep(5) # TODO remove when flight modes execute real tasks self.poll_inputs() self.update_state() self.read_command_queue_from_file() self.execute_commands() # Set goal or execute command immediately self.execute_downlinks() self.run_mode() finally: self.replace_flight_mode_by_id(FMEnum.Safety.value) # TODO handle failure gracefully if FOR_FLIGHT is True: self.run() else: self.gom.all_off() def shutdown(self): self.gom.all_off() logger.critical("Shutting down...")
from communications .satellite_radio import Radio import time #Test constants radio = Radio() # Do not modify signal = b'\x08\x07\x00\x00' #Pattern you want to send interval = 3 # Number of seconds between each transmission repetitions = 10 # Number of total times you want to transmit the pattern for i in range(1, repetitions+1): radio.transmit(signal) print('Transmitted: ' + str(i)) time.sleep(interval)