def __init__(self, master_): if DMC.__instance is not None: raise Exception('This class is a singleton!') else: self.master = master_ self.motor_dmc = MotorDMC.get_instance() self.data_manager = self.master.data_manager self.info_logger = self.master.info_logger self.counterdown = CounterDown(master_) #@TODO change alti thress self.alti_thresshold = 10 # 10m DMC.__instance = self
def __init__(self, ground_ip): self.status_vector = dict() self.command_vector = dict() self.ground_ip = ground_ip self.info_logger = InfoLogger() self.data_logger = DataLogger() self.adcs_logger = AdcsLogger() #@TODO where antenna to start #self.adcs_logger.write_info(' {}, {}, {}, {}'.format(0, 0, 0, 0)) self.elink = elinkmanager.ELinkManager(self, self.ground_ip) self.thread_elink = None self.data_manager = DataManager(self, self.info_logger, self.data_logger) self.thread_data_manager = None self.dmc = dmc.DMC(self) self.thread_dmc = None self.heat = heat.HEAT(self) self.thread_heat = None self.adc = adc.ADC(self) self.thread_adc = None self.tx = tx.TX(self) self.thread_tx = None self.counterdown = CounterDown(self) self.paths = paths.Paths() GPIO.setmode(GPIO.BOARD) Master.__instance = self
def __init__(self, master_): if HEAT.__instance is not None: raise Exception("This class is a singleton!") else: self.master = master_ self.data_manager = self.master.data_manager self.info_logger = self.master.info_logger self.counterdown = CounterDown(master_) self.need_heating_A = False self.need_heating_B = False self.temp_thresshold = -20 self.mean_temp_A = self.temp_thresshold self.mean_temp_B = self.temp_thresshold self.max_size = 10 self.data_queue_A = queue.Queue(self.max_size) self.data_queue_B = queue.Queue(self.max_size) self.pin_heaterA = pins.Pins().pin_heaterA #pin for Heater A self.pin_heaterB = pins.Pins().pin_heaterB #pin for Heater B GPIO.setmode(GPIO.BOARD) GPIO.setup(self.pin_heaterA, GPIO.OUT) GPIO.output(self.pin_heaterA, GPIO.LOW) GPIO.setup(self.pin_heaterB, GPIO.OUT) GPIO.output(self.pin_heaterB, GPIO.LOW) HEAT.__instance = self
def __init__(self, master_): if ADC.__instance is not None: raise Exception('This class is a singleton!') else: """ GS: x- axis y-axis of SHADE Ground Station - static gps: x- axis y-axis of Gondola's current x,y-axis compass: data received from compass, degrees btwn North and Gondola 0,0 antenna_adc: object of antenna instance direction: clockwise (1) or anti-clockwise(0) for antenna base rotation difference: degrees which are needed for antenna base rotation """ self.master = master_ self.antenna_adc = Antenna() self.motor_adc = MotorADC.get_instance() self.motor_dmc = MotorDMC.get_instance() self.data_manager = self.master.data_manager self.info_logger = self.master.info_logger self.adcs_logger = self.master.adcs_logger self.counterdown = CounterDown(master_) self.info_logger.write_info('antenna at {}'.format(self.antenna_adc.position)) #@TODO GS gps data self.GS = [210631.24000000002, 678785.42] self.compass = 0 self.gps = self.GS self.direction = 1 self.difference = 0 self.valid_data = True ###color self.color_string = None self.stop_turn = False self.dir_init = 0 self.counter_done = 0 ### ADC.__instance = self
def __init__(self): self.status_vector = dict() self.command_vector = dict() self.info_logger = InfoLogger() self.data_logger = DataLogger() self.data_manager = DataManager(self, self.info_logger, self.data_logger) self.thread_data_manager = None self.heat = heat.HEAT_HAI(self) self.thread_heat = None self.counterdown = CounterDown(self) self.paths = paths.Paths() self.pin_powerB = pins.Pins( ).pin_powerB # @TODO change it in boot/config.txt GPIO.setmode(GPIO.BOARD) #GPIO.setup(self.pin_powerB, GPIO.OUT) Master.__instance = self
def __init__(self, ground_ip): self.status_vector = dict() self.command_vector = dict() self.ground_ip = ground_ip self.info_logger = InfoLogger() self.data_logger = DataLogger() self.adcs_logger = AdcsLogger() self.elink = elinkmanager.ELinkManager(self,self.ground_ip) self.thread_elink = None # self.data_manager = DataManager(self, self.info_logger, self.data_logger) # self.thread_data_manager = None self.tx = tx.TX(self) self.thread_tx = None self.counterdown = CounterDown(self) self.paths = paths.Paths() self.pin_powerB = pins.Pins().pin_powerB # @TODO change it in boot/config.txt #GPIO.setmode(GPIO.BOARD) #GPIO.setup(self.pin_powerB, GPIO.OUT) Master.__instance = self
def __init__(self, master_): if TX.__instance is not None: raise Exception('This class is a singleton!') else: self.master = master_ self.info_logger = self.master.info_logger self.counterdown = CounterDown(master_) self.sdr_process = None self.file_name_temperature = paths.Paths().tx_file self.file_name_predefined_data = paths.Paths().tx_file_pre_data self.file_img_spon = paths.Paths().tx_img_spon self.file_img_fam = paths.Paths().tx_img_fam self.TX_code_file = 'sdr_TX.py' self.TX_code_sin = 'sin_TX.py' self.TX_code_spon = 'img_TX.py' self.TX_code_fam = 'fam_TX.py' self.pin_led_tx = pins.Pins().pin_led_tx GPIO.setmode(GPIO.BOARD) GPIO.setup(self.pin_led_tx, GPIO.OUT) GPIO.output(self.pin_led_tx, GPIO.LOW)
class ADC: __instance = None def __init__(self, master_): if ADC.__instance is not None: raise Exception('This class is a singleton!') else: """ GS: x- axis y-axis of SHADE Ground Station - static gps: x- axis y-axis of Gondola's current x,y-axis compass: data received from compass, degrees btwn North and Gondola 0,0 antenna_adc: object of antenna instance direction: clockwise (1) or anti-clockwise(0) for antenna base rotation difference: degrees which are needed for antenna base rotation """ self.master = master_ self.antenna_adc = Antenna() self.motor_adc = MotorADC.get_instance() self.motor_dmc = MotorDMC.get_instance() self.data_manager = self.master.data_manager self.info_logger = self.master.info_logger self.adcs_logger = self.master.adcs_logger self.counterdown = CounterDown(master_) self.info_logger.write_info('antenna at {}'.format(self.antenna_adc.position)) #@TODO GS gps data self.GS = [210631.24000000002, 678785.42] self.compass = 0 self.gps = self.GS self.direction = 1 self.difference = 0 self.valid_data = True ###color self.color_string = None self.stop_turn = False self.dir_init = 0 self.counter_done = 0 ### ADC.__instance = self @staticmethod def get_instance(): if ADC.__instance is None: ADC(None) return ADC.__instance def start(self): self.info_logger.write_info('ADC: START ADC PROCESS') while not self.master.status_vector['DEP_SUCS'] and not self.master.status_vector['KILL']: self.info_logger.write_info('ADC: WAIT FOR DEP') sleep(self.counterdown.adc_time_checks_deploy) while not self.master.status_vector['KILL']: self.run_ADC_auto() self.run_ADC_manual() self.info_logger.write_info('ADC: END OF ADC PROCESS') #Auto mode of ADC def run_ADC_auto(self): self.info_logger.write_info('ADC: AUTO ADC') self.master.status_vector['ADC_MAN'] = 0 # 0 self.master.command_vector['ADC_MAN'] = 0 while not self.master.get_command('ADC_MAN') and not self.master.status_vector['KILL']: self.valid_data = True self.get_compass_data() self.get_gps_data() if self.valid_data: self.calc_new_position() c_step = self.convert_to_steps(self.difference) self.log_last_position_before(c_step) self.move_ADC_motor(c_step, self.direction) self.antenna_adc.update_position(self.difference, self.direction) self.log_last_position_after() else: self.info_logger.write_warning('ADC: NON ACTION: INVALID DATA') sleep(self.counterdown.adc_auto_time_runs) #time to run ADC algorithm def run_ADC_manual(self): while self.master.get_command('ADC_MAN') and not self.master.status_vector['KILL']: self.master.info_logger.write_info('ADC: IN ADC MAN') self.master.status_vector['ADC_MAN'] = 1 self.master.command_vector['ADC_AUTO'] = 0 # re-init self.master.command_vector['SET'] = 0 # re-init self.master.command_vector['SCAN'] = 0 # re-init self.master.command_vector['INIT'] = 0 # re-init choice = self.counterdown.countdown3(self.counterdown.adc_man_timeout_to_set_or_scan, 'SET', 'SCAN', 'INIT') if choice == 1: self.info_logger.write_info('ADC: IN SET') sleep(self.counterdown.adc_wait_auto_ends) try: steps = int(self.master.command_vector['SET']['steps']) self.go_to_zero() sleep(1) self.set_position(steps) except: self.info_logger.write_warning('ADC: INVALID STEP INPUT') elif choice == 2: self.info_logger.write_info('ADC: IN SCAN') self.go_to_zero() sleep(1) self.scan() elif choice == 3: self.info_logger.write_info('ADC: IN INIT') self.init_position() self.master.command_vector['SET'] = 0 # re-init self.master.command_vector['SCAN'] = 0 # re-init self.master.command_vector['INIT'] = 0 # re-init self.master.command_vector['ADC_AUTO'] = 0 # re-init self.master.command_vector['ADC_MAN'] = 0 # re-init self.info_logger.write_info('ADC: WAITING FOR ADC MAN OR AUTO') choice = self.counterdown.countdown2(self.counterdown.adc_man_time_breaks, 'ADC_AUTO', 'ADC_MAN') if choice == 2: self.info_logger.write_info('ADC: CONT ADC MAN') else: self.master.command_vector['ADC_MAN'] = 0 # re-init self.master.status_vector['ADC_MAN'] = 0 # re-init self.info_logger.write_info('ADC: BREAK ADC MAN') sleep(self.counterdown.adc_man_time_runs) def get_compass_data(self): if self.master.status_vector['COMPASS'] == 0: self.info_logger.write_warning('ADC: Invalid compass data') self.valid_data = False else: self.compass = float(self.data_manager.get_data("angle_c")) def get_gps_data(self): if self.master.status_vector["GPS"] == 0: self.info_logger.write_warning('ADC: Invalid gps data') self.valid_data = False else: x = self.data_manager.get_data("gps_x") * 10000 y = self.data_manager.get_data("gps_y") * 10000 self.gps = [x, y] def log_last_position_before(self, c_step): self.info_logger.write_info('ADC: STEPS\t {} TO DO'.format(c_step)) self.info_logger.write_info('ADC: DEGREES {} TO DO'.format(self.difference)) self.info_logger.write_info('ADC: ACT FROM: {} WITH {}'.format(self.antenna_adc.counter_for_overlap, self.direction)) def log_last_position_after(self): self.info_logger.write_info('ADC: DONE: {}'.format(self.antenna_adc.counter_for_overlap)) self.adcs_logger.write_info(' {}, {}, {}, {} '.format(self.antenna_adc.position, self.antenna_adc.counter_for_overlap, self.antenna_adc.theta_antenna_pointing, self.antenna_adc.theta)) self.antenna_adc.angle_plot = self.antenna_adc.theta_antenna_pointing def push_DMC_motor(self): self.motor_dmc.motor_push() self.info_logger.write_info('ADC: DMC MOTOR PUSH') def move_ADC_motor(self,counter_step,direction): self.motor_adc.act(counter_step, direction) self.info_logger.write_info('ADC: ADC MOTOR ROTATED') def pull_DMC_motor(self): self.motor_dmc.motor_pull() self.info_logger.write_info('ADC: DMC MOTOR PULL') def convert_to_steps(self, dif): if self.motor_adc.step_size != 0: c_step = int(dif * self.motor_adc.step_size) return c_step else: self.info_logger.write_warning('ADC: TRY division /0: check step size') return 0 def set_position(self, set_step): if 0 <= set_step <= (360*self.motor_adc.step_size): direction = 1 self.motor_adc.act(set_step, direction) self.antenna_adc.update_position(set_step/self.motor_adc.step_size, direction) self.info_logger.write_info('ADC: SET: ANTENNA AT {}'.format(self.antenna_adc.position)) self.adcs_logger.write_info(' {}, {}, {}, {} '.format(self.antenna_adc.position, self.antenna_adc.counter_for_overlap, self.antenna_adc.position + self.compass, self.antenna_adc.theta)) self.antenna_adc.angle_plot = self.antenna_adc.position + self.compass else: self.info_logger.write_warning('ADC: Invalid SET_STEP') def scan(self): direction = 1 steps_per_time = 70 # 70steps - 20 degress times_per_scan = 18 for x in range(0,times_per_scan): self.motor_adc.act(steps_per_time, direction) self.antenna_adc.update_position(20, direction) self.info_logger.write_info('ADC: SCAN: ANTENNA AT {}'.format(self.antenna_adc.position)) self.log_last_position_after() direction = 0 for x in range(0,times_per_scan): self.motor_adc.act(steps_per_time, direction) self.antenna_adc.update_position(20, direction) self.info_logger.write_info('ADC: SCAN: ANTENNA AT {}'.format(self.antenna_adc.position)) self.log_last_position_after() def go_to_zero(self): if self.antenna_adc.counter_for_overlap > 0: direction = 0 else: direction = 1 c_steps = self.convert_to_steps(self.antenna_adc.counter_for_overlap) self.motor_adc.act(c_steps, direction) self.antenna_adc.position = 0 self.antenna_adc.counter_for_overlap = 0 self.adcs_logger.write_info( ' {}, {}, {}, {} '.format(self.antenna_adc.position, self.antenna_adc.counter_for_overlap, self.antenna_adc.theta_antenna_pointing, self.antenna_adc.theta)) self.antenna_adc.angle_plot = self.antenna_adc.theta_antenna_pointing def calc_new_position(self): #calc GEOMETRY thresshold = 0.001 dx = abs(self.GS[0] - self.gps[0]) dy = abs(self.gps[1] - self.GS[1]) if dx < thresshold: # in same yy' axis if self.GS[1] < self.gps[1]: theta = 180 else: theta = 0 else: if dy == 0: dy = thresshold fi = math.atan(dx/dy) * 180 / math.pi if self.GS[0] < self.gps[0] and self.GS[1] < self.gps[1]: theta = 180 + fi #quartile = 1 elif self.GS[0] < self.gps[0] and self.GS[1] > self.gps[1]: #OLD theta = 180 - fi #quartile = 2 theta = 360 - fi #quartile = 2 elif self.GS[0] > self.gps[0] and self.GS[1] > self.gps[1]: theta = fi #quartile = 3 else: #OLD theta = 360 - fi # quartile = 4 theta = 180 - fi # quartile = 4 # end calc GEOMETRY self.antenna_adc.theta = theta self.antenna_adc.theta_antenna_pointing = (self.antenna_adc.position + self.compass) % 360 self.adcs_logger.write_info(' {}, {}, {}, {} '.format(self.antenna_adc.position, self.antenna_adc.counter_for_overlap, self.antenna_adc.theta_antenna_pointing, self.antenna_adc.theta)) self.antenna_adc.angle_plot = self.antenna_adc.theta_antenna_pointing if self.antenna_adc.theta_antenna_pointing < self.antenna_adc.theta: dif1 = self.antenna_adc.theta - self.antenna_adc.theta_antenna_pointing dif2 = 360 - dif1 if dif1 <= dif2: if self.antenna_adc.check_isinoverlap(dif1, +1): # clockwise self.difference = dif2 self.direction = 0 # ani-clockwise else: self.difference = dif1 self.direction = 1 # clockwise else: if self.antenna_adc.check_isinoverlap(dif2, -1): # anti-clockwise self.difference = dif1 self.direction = 1 # clockwise else: self.difference = dif2 self.direction = 0 # anti-clockwise else: dif2 = self.antenna_adc.theta_antenna_pointing - self.antenna_adc.theta dif1 = 360 - dif2 if dif1 <= dif2: if self.antenna_adc.check_isinoverlap(dif1, +1): # clockwise self.difference = dif2 self.direction = 0 # ani-clockwise else: self.difference = dif1 self.direction = 1 # clockwise else: if self.antenna_adc.check_isinoverlap(dif2, -1): # anti-clockwise self.difference = dif1 self.direction = 1 # clockwise else: self.difference = dif2 self.direction = 0 # anti-clockwise self.info_logger.write_info('ADC: Difference {} Direction {}'.format( self.difference, self.direction)) def get_color_data(self): if self.master.status_vector["INFRARED"] == 0 : self.info_logger.write_warning('ADC: Invalid color data') else: self.color_string = self.data_manager.get_data("color") #@TODO mod it to work def init_position(self): #clean overlaps if self.antenna_adc.counter_for_overlap > 360: self.motor_adc.act(315, 0) # anti-clockwise self.antenna_adc.update_position(315 / self.motor_adc.step_size, 0) # anti-clockwise elif self.antenna_adc.counter_for_overlap < -360: self.motor_adc.act(315, 1) # clockwise self.antenna_adc.update_position(315 / self.motor_adc.step_size, 1) # clockwise # find direction if self.antenna_adc.counter_for_overlap < 0: self.dir_init = 1 else: self.dir_init = 0 self.stop_turn = False self.counter_done = 0 to_act_one = False #thread_act = Thread(target=self.threaded_function_act) #thread_act.start() while not self.stop_turn and not self.master.status_vector['KILL'] and self.master.status_vector['INFRARED']: self.get_color_data() if (self.color_string == "WHITE"): self.info_logger.write_info("ADC: WHITE") self.info_logger.write_info("ADC: ZERO POSITION IS SET") if to_act_one: self.stop_turn = True to_act_one = True elif (self.color_string == "RED"): self.info_logger.write_info("ADC: SAW RED") to_act_one = False elif (self.color_string == "BLUE"): self.info_logger.write_info("ADC: SAW BLUE") to_act_one = False elif (self.color_string == "BLACK"): self.info_logger.write_info("ADC: SAW BLACK") to_act_one = False if not self.stop_turn and not to_act_one: self.counter_done += 1 self.motor_adc.act_smooth(self.dir_init) elif to_act_one: sleep(4) self.motor_adc.act(1, self.dir_init) self.info_logger.write_info("ADC: NEXT STEP OF WHITE") if self.counter_done > 190: self.info_logger.write_info("ADC: CHANGE DIR_INIT") if self.dir_init == 0: self.dir_init = 1 else: self.dir_init = 0 self.counter_done = 0 sleep(2) if self.stop_turn: self.motor_adc.act(10,self.dir_init) self.antenna_adc.position = 0 self.antenna_adc.counter_for_overlap = 0 else: self.antenna_adc.update_position(self.counter_done*self.motor_adc.smooth_steps / self.motor_adc.step_size,self.dir_init) self.get_compass_data() self.adcs_logger.write_info(' {}, {}, {}, {} '.format(self.antenna_adc.position, self.antenna_adc.counter_for_overlap, self.antenna_adc.position + self.compass, self.antenna_adc.theta)) self.antenna_adc.angle_plot = self.antenna_adc.position + self.compass #def threaded_function_act(self): #while not self.stop_turn: #self.counter_done += 1 #self.motor_adc.act_smooth(self.dir_init)
class DMC: __instance = None def __init__(self, master_): if DMC.__instance is not None: raise Exception('This class is a singleton!') else: self.master = master_ self.motor_dmc = MotorDMC.get_instance() self.data_manager = self.master.data_manager self.info_logger = self.master.info_logger self.counterdown = CounterDown(master_) #@TODO change alti thress self.alti_thresshold = 10 # 10m DMC.__instance = self @staticmethod def get_instance(): if DMC.__instance is None: DMC(None) return DMC.__instance def start(self): self.master.info_logger.write_info('DMC: START DMC PROCESS') while not self.master.status_vector['DEP_CONF']: self.phase_zero() self.phase_ready_for_deploy() while not self.master.status_vector['DEP_SUCS']: self.phase_deploy() self.phase_sleep() self.master.status_vector['DMC_SLEEP'] = 0 while not self.master.status_vector['RET_CONF']: self.phase_check() self.phase_kill_before_retrieve() while not self.master.status_vector['RET_SUCS']: self.phase_retrieve() self.master.info_logger.write_info('DMC: END DMC PROCESS') def phase_zero(self): self.master.command_vector['DEP'] = 0 # re-init if a new cmd come self.info_logger.write_info('DMC: PHASE ZERO') self.counterdown.countdown1(self.counterdown.dmc_time_left_auto_deploy, 'DEP') self.master.status_vector['DEP_READY'] = 1 def phase_ready_for_deploy(self): self.master.command_vector['DEP_CONF'] = 0 # re-init if a new cmd come self.master.command_vector['DEP_AB'] = 0 # re-init if a new cmd come self.info_logger.write_info('DMC: PHASE READY DEP') choice = self.counterdown.countdown2(self.counterdown.dmc_timeout_cmd, 'DEP_CONF', 'DEP_AB') if choice == 2: self.master.command_vector['DEP'] = 0 # re-init if a new cmd come self.master.status_vector['DEP_READY'] = 0 self.counterdown.dmc_time_left_auto_deploy = 5*60 # ex. 5min else: self.master.status_vector['DEP_CONF'] = 1 def phase_deploy(self): self.info_logger.write_info('DMC: PHASE DEPLOY') # in that phase status_vector DEP_READY = 1 & DEP_CONF = 1 self.motor_dmc.motor_deploy() self.master.command_vector['DEP_SUCS'] = 0 # re-init if a new cmd come self.master.command_vector['DEP_RETRY'] = 0 # re-init if a new cmd come choice = self.counterdown.countdown2(self.counterdown.dmc_timeout_cmd, 'DEP_SUCS', 'DEP_RETRY') if choice == 2: self.info_logger.write_info('DMC: RETRY') self.motor_dmc.motor_retrieve() time.sleep(2) else: self.master.status_vector['DEP_SUCS'] = 1 def phase_sleep(self): self.info_logger.write_info('DMC: PHASE SLEEP') self.master.status_vector['DMC_SLEEP'] = 1 self.master.command_vector['DMC_AWAKE'] = 0 # re-init if a new cmd come GPIO.output(self.motor_dmc.pin_enable, GPIO.HIGH) self.counterdown.countdown1(self.counterdown.dmc_time_to_sleep, 'DMC_AWAKE') GPIO.output(self.motor_dmc.pin_enable, GPIO.LOW) self.master.command_vector['RET'] = 0 # re-init if a new cmd come def phase_check(self): self.info_logger.write_info('DMC: PHASE CHECK') time.sleep(self.counterdown.dmc_time_checks_altitude) altitude = self.data_manager.get_data('altitude') self.master.command_vector['RET_CONF'] = 0 # re-init if a new cmd come self.master.command_vector['RET_AB'] = 0 # re-init if a new cmd come if (self.master.status_vector['ALTIMETER'] and (altitude < self.alti_thresshold)) or self.master.get_command('RET'): self.master.status_vector['RET_READY'] = 1 self.info_logger.write_info('DMC: READY TO RETRIEVE') choice = self.counterdown.countdown2(self.counterdown.dmc_timeout_cmd, 'RET_CONF', 'RET_AB') if choice == 2: self.master.command_vector['RET'] = 0 # re-init if a new cmd come self.master.status_vector['RET_AB'] = 1 self.master.status_vector['RET_READY'] = 0 self.info_logger.write_info('DMC: RETRIEVE ABORT ') else: self.master.status_vector['RET_CONF'] = 1 self.info_logger.write_info('DMC: RETRIEVE CONFIRMED') def phase_kill_before_retrieve(self): self.info_logger.write_info('DMC: PHASE KILLING') self.master.status_vector['KILL'] = 1 time.sleep(self.counterdown.dmc_wait_others_to_killed) # wait master to kill or dmc kills def phase_retrieve(self): self.info_logger.write_info('DMC: PHASE RETRIEVE') self.motor_dmc.motor_retrieve() self.master.command_vector['RET_SUCS'] = 0 # re-init if a new cmd come self.master.command_vector['RET_RETRY'] = 0 # re-init if a new cmd come choice = self.counterdown.countdown2(self.counterdown.dmc_timeout_cmd, 'RET_SUCS', 'RET_RETRY') if choice == 2: self.info_logger.write_info('DMC: RET RETRY') self.motor_dmc.motor_deploy() else: self.master.status_vector['RET_SUCS'] = 1 self.info_logger.write_info('DMC: RET SUCS')