01234567890123456789012345678901234567890123456789012345678901234567890123456789
618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765 | <----SKIPPED LINES----> # Ensures that the child can exit if the parent exits unexpectedly # docs.python.org/2/library/multiprocessing.html#multiprocessing.Queue.cancel_join_thread to_arduino_q.cancel_join_thread() to_parent_q.cancel_join_thread() # write_format: azimuth, altitude, R, G, & B intensity # read heartbeat: millis link = Serial( *SERVO_CONNECTION, read_timeout=7, error_pin=messageboard.GPIO_ERROR_ARDUINO_SERVO_CONNECTION, to_parent_q=to_parent_q, read_format='l', write_format='ffhhh', name='Servo') link.Open() last_flight = {} last_angles = (0, 0) flight, json_desc_dict, configuration, additional_attr = InitialMessageValues( to_arduino_q) next_read = 0 next_write = 0 now = GetNow(json_desc_dict, additional_attr) timing = [] flight_present = False while not shutdown.value: timing.append((time.time(), 2)) if not to_arduino_q.empty(): flight, json_desc_dict, configuration, additional_attr = to_arduino_q.get( block=False) if 'test_servos' in configuration: messageboard.RemoveSetting(configuration, 'test_servos') link.Write((0, 0, *LASER_RGB_OFF)) time.sleep(1) link.Write((90, 0, *LASER_RGB_OFF)) time.sleep(1) link.Write((180, 0, *LASER_RGB_OFF)) time.sleep(1) link.Write((270, 0, *LASER_RGB_OFF)) timing.append((time.time(), 3)) new_flight = DifferentFlights(flight, last_flight) timing.append((time.time(), 3.5)) if new_flight: Log('Flight changed from %s to %s' % ( messageboard.DisplayFlightNumber(last_flight), messageboard.DisplayFlightNumber(flight) ), ser=link) timing.append((time.time(), 4)) # Turn off laser so that line isn't traced while it moves to new position link.Write((*last_angles, *LASER_RGB_OFF)) last_flight = flight timing.append((time.time(), 5)) if time.time() >= next_read: link.Read() # simple ack message sent by servos next_read = time.time() + READ_DELAY_TIME timing.append((time.time(), 6)) now = GetNow(json_desc_dict, additional_attr) timing.append((time.time(), 7)) current_angles = AzimuthAltitude(flight, now) timing.append((time.time(), 8)) if current_angles and time.time() > next_write: if current_angles[1] >= configuration['minimum_altitude_servo_tracking']: Log('Flight #: %s current_angles: %s' % ( messageboard.DisplayFlightNumber(flight), str(current_angles))) messageboard.LogTimes(timing, threshold=0.2) flight_present = True laser_rgb = LaserRGBFlight(flight) timing = [(time.time(), 0)] link.Write((*current_angles, *laser_rgb)) last_angles = current_angles timing.append((time.time(), 1.1)) # flight no longer tracked; send one more command to turn off lasers elif flight_present: timing = [(time.time(), 1.2)] link.Write((*last_angles, *LASER_RGB_OFF)) flight_present = False next_write = time.time() + WRITE_DELAY_TIME else: timing = timing = [(time.time(), 1.3)] link.Close(SHUTDOWN_TEXT) LASER_RGB_OFF = (0, 0, 0) def LaserRGBFlight(flight): """Based on flight attributes, set the laser.""" if not flight: return LASER_RGB_OFF return 1, 0, 0 def DifferentFlights(f1, f2): """True if flights same except for persistent path; False if they differ. We cannot simply check if two flights are identical by checking equality of the dicts, because a few attributes are updated after the flight is first found: - the persistent_path is kept current - cached_* attributes may be updated - the insights are generated after flight first enqueued On the other hand, we cannot check if they are identical by looking just at the flight number, because flight numbers may be unknown. Thus, this checks all attributes except the persistent path. Returns: List of the different keys, excluding the persistent_path key. """ if f1 is None and f2 is None: return [] if f1 is None: return sorted(list(f2.keys())) if f2 is None: return sorted(list(f1.keys())) excluded_keys = ['persistent_path', 'insight_types'] different_attributes = [] for key in set(f1.keys()).union(set(f2.keys())): if key not in excluded_keys and not key.startswith(messageboard.CACHED_ELEMENT_PREFIX): if f1.get(key) != f2.get(key): different_attributes.append(key) return sorted(different_attributes) def FloatToAlphanumericStr(x, decimals, total_length, sign=True): """Formats a float as a string without a decimal point. Since the decimal point is controlled independently on the alphanumeric display, numbers that include decimals must be sent without the decimal point. This formats a float as %+5.2f, for example - but without the decimal. Args: x: Value to format. decimals: how many digits should follow the (absent) decimal point. total_length: desired total length of the resulting string-ified number (inclusive of the absent decimal point. sign: boolean indicating whether a sign should be included for positive numbers. Returns: String as specified - for instance, 0.4 might be formatted as ' +04'. """ sign_str = '' <----SKIPPED LINES----> |
01234567890123456789012345678901234567890123456789012345678901234567890123456789
618619620621622623624625626627628629630631632633634635636637 638639640 641642643644645646647648649650651652653654 655 656657658659660661 662663664665 666667668669 670671 672673 674675676677 678679 680681 682683684 685686687688 689690691692693694695696697698699700701702 703704705706 707708709710711712 713714715716717718719720721722723724725726727728729730731732 | <----SKIPPED LINES----> # Ensures that the child can exit if the parent exits unexpectedly # docs.python.org/2/library/multiprocessing.html#multiprocessing.Queue.cancel_join_thread to_arduino_q.cancel_join_thread() to_parent_q.cancel_join_thread() # write_format: azimuth, altitude, R, G, & B intensity # read heartbeat: millis link = Serial( *SERVO_CONNECTION, read_timeout=7, error_pin=messageboard.GPIO_ERROR_ARDUINO_SERVO_CONNECTION, to_parent_q=to_parent_q, read_format='l', write_format='ffhhh', name='Servo') link.Open() last_flight = {} last_angles = (0, 0) flight, json_desc_dict, configuration, additional_attr = InitialMessageValues( to_arduino_q) next_read = 0 next_write = 0 now = GetNow(json_desc_dict, additional_attr) flight_present = False while not shutdown.value: if not to_arduino_q.empty(): flight, json_desc_dict, configuration, additional_attr = to_arduino_q.get( block=False) if 'test_servos' in configuration: messageboard.RemoveSetting(configuration, 'test_servos') link.Write((0, 0, *LASER_RGB_OFF)) time.sleep(1) link.Write((90, 0, *LASER_RGB_OFF)) time.sleep(1) link.Write((180, 0, *LASER_RGB_OFF)) time.sleep(1) link.Write((270, 0, *LASER_RGB_OFF)) new_flight = DifferentFlights(flight, last_flight) if new_flight: Log('Flight changed from %s to %s' % ( messageboard.DisplayFlightNumber(last_flight), messageboard.DisplayFlightNumber(flight) ), ser=link) # Turn off laser so that line isn't traced while it moves to new position link.Write((*last_angles, *LASER_RGB_OFF)) last_flight = flight if time.time() >= next_read: link.Read() # simple ack message sent by servos next_read = time.time() + READ_DELAY_TIME now = GetNow(json_desc_dict, additional_attr) current_angles = AzimuthAltitude(flight, now) if current_angles and time.time() > next_write: if current_angles[1] >= configuration['minimum_altitude_servo_tracking']: Log('Flight #: %s current_angles: %s' % ( messageboard.DisplayFlightNumber(flight), str(current_angles))) flight_present = True laser_rgb = LaserRGBFlight(flight) link.Write((*current_angles, *laser_rgb)) last_angles = current_angles # flight no longer tracked; send one more command to turn off lasers elif flight_present: link.Write((*last_angles, *LASER_RGB_OFF)) flight_present = False next_write = time.time() + WRITE_DELAY_TIME link.Close(SHUTDOWN_TEXT) LASER_RGB_OFF = (0, 0, 0) def LaserRGBFlight(flight): """Based on flight attributes, set the laser.""" if not flight: return LASER_RGB_OFF return 1, 0, 0 def DifferentFlights(f1, f2): """True if both squawk and flight number different; false otherwise.""" if f1 is None and f2 is None: return True if f1 is None or f2 is None: return True if ( f1.get('flight_number') != f2.get('flight_number') and f1.get('squawk') != f2.get('squawk')): return True return False def FloatToAlphanumericStr(x, decimals, total_length, sign=True): """Formats a float as a string without a decimal point. Since the decimal point is controlled independently on the alphanumeric display, numbers that include decimals must be sent without the decimal point. This formats a float as %+5.2f, for example - but without the decimal. Args: x: Value to format. decimals: how many digits should follow the (absent) decimal point. total_length: desired total length of the resulting string-ified number (inclusive of the absent decimal point. sign: boolean indicating whether a sign should be included for positive numbers. Returns: String as specified - for instance, 0.4 might be formatted as ' +04'. """ sign_str = '' <----SKIPPED LINES----> |