def testCrossStartFinish(self): point_a = gps_pb2.Point() point_b = gps_pb2.Point() point_c = gps_pb2.Point() point_b.start_finish_distance = 5.613414540798601 point_c.start_finish_distance = 8.86833983566463 point_a.time.FromMilliseconds(1000) point_b.time.FromMilliseconds(2000) point_c.time.FromMilliseconds(3000) point_a.lat = 45.594961 point_a.lon = -122.694508 point_b.lat = 45.594988 point_b.lon = -122.694587 point_c.lat = 45.595000 point_c.lon = -122.694638 session = gps_pb2.Session() session.track = 'Portland International Raceway' session.start_finish.lat = 45.595015 session.start_finish.lon = -122.694526 lap = session.laps.add() lap.points.extend([point_a, point_b]) es = main.ExitSpeed(min_points_per_session=0) es.point = point_c es.lap = lap es.session = session es.CrossStartFinish() self.assertEqual(2, len(es.session.laps)) self.assertEqual(2, len(es.session.laps[0].points)) self.assertEqual(2, len(es.session.laps[1].points)) self.assertIn(point_a, es.session.laps[0].points) self.assertIn(point_b, es.session.laps[0].points) self.assertIn(point_b, es.session.laps[1].points) self.assertIn(point_c, es.session.laps[1].points) self.assertNotIn(point_c, es.session.laps[0].points)
def testCalcAcceleration(self): point_b = gps_pb2.Point() point_b.speed_ms = 70 point_b.time.FromMilliseconds(1) point_c = gps_pb2.Point() point_c.speed_ms = 72 point_c.time.FromMilliseconds(2) self.assertEqual(1999.9999999999998, lap_lib.CalcAcceleration(point_b, point_c))
def testSolvePointBAngle(self): point_b = gps_pb2.Point() point_b.start_finish_distance = 8 point_c = gps_pb2.Point() point_c.start_finish_distance = 6 with mock.patch.object(common_lib, 'PointDelta') as mock_delta: mock_delta.return_value = 7 self.assertEqual(46.56746344221023, lap_lib.SolvePointBAngle(point_b, point_c))
def testUpdateSpeedDeltas(self): point = gps_pb2.Point() point.speed_ms = 88 # m/s best_point = gps_pb2.Point() best_point.speed_ms = 87 self.leds.UpdateSpeedDeltas(point, best_point) deltas = collections.deque(maxlen=FLAGS.speed_deltas) deltas.append(-1.0) self.assertSequenceEqual(deltas, self.leds.speed_deltas)
def testPointDelta(self): point_a = gps_pb2.Point() point_b = gps_pb2.Point() point_a.lat = 1.1 point_b.lat = 2.2 point_a.lon = -1.1 point_b.lon = -2.2 self.assertEqual(171979.02735070087, common_lib.PointDelta(point_a, point_b))
def testSetLapTime(self): es = main.ExitSpeed() first_point = gps_pb2.Point() first_point.time.FromJsonString(u'2020-05-23T17:47:44.100Z') last_point = gps_pb2.Point() last_point.time.FromJsonString(u'2020-05-23T17:49:00.100Z') session = gps_pb2.Session() lap = session.laps.add() lap.points.append(first_point) lap.points.append(last_point) es.lap = lap es.session = session es.SetLapTime() self.assertEqual(76, lap.duration.ToSeconds()) self.assertEqual(es.leds.best_lap, lap)
def testProcessPoint(self): prior_point = gps_pb2.Point() prior_point.lat = 12.000000 prior_point.lon = 23.000000 prior_point.time.FromJsonString(u'2020-05-23T17:47:44.100Z') point = gps_pb2.Point() point.lat = 12.000001 point.lon = 23.000002 point.time.FromJsonString(u'2020-05-23T17:47:44.200Z') es = main.ExitSpeed() es.lap = gps_pb2.Lap() es.lap.points.extend([prior_point, point]) es.point = point es.ProcessPoint() self.assertEqual(2856514.6203466402, point.start_finish_distance)
def InitializeSubProcesses(self): """Initialize subprocess modules based on config.yaml.""" if self.config.get('gps'): self.gps = gps_sensor.GPSProcess(self.config, self.point_queue) while self.point_queue.empty(): self.point = gps_pb2.Point().FromString(self.point_queue.get()) logging.log_every_n_seconds( logging.INFO, 'Waiting for GPS fix to determine track before starting other ' 'sensor subprocesses', 10) break self.ProcessSession() if self.config.get('accelerometer'): self.accel = accelerometer.AccelerometerProcess( self.config, self.point_queue) if self.config.get('gyroscope'): self.gyro = gyroscope.GyroscopeProcess(self.config, self.point_queue) if self.config.get('labjack'): self.labjack = labjack.Labjack(self.config, self.point_queue) if self.config.get('tire_temps'): self.tire_temps = tire_temperature.MultiTireInterface( self.config, self.point_queue) if self.config.get('wbo2'): self.wbo2 = wbo2.WBO2(self.config, self.point_queue) if self.config.get('timescale'): self.timescale = timescale.Timescale( timescale.CreateSession(self.session)) if self.config.get('rtmp_overlay'): self.rtmp_overlay = rtmp_overlay.RTMPOverlay(self.config)
def testReadValues(self): # pylint: disable=invalid-name # pylint: disable=unused-argument def _binaryToCalibratedAnalogVoltage(result, isLowVoltage, channelNumber): if channelNumber in self.labjack.HIGH_VOLTAGE_CHANNELS: self.assertFalse(isLowVoltage) else: self.assertTrue(isLowVoltage) mapping = {32816: 1.5, 35696: 2.7, 32827: 3.9, 39968: 1.4} return mapping[result] # pylint: enable=invalid-name # pylint: enable=unused-argument self.mock_u3.getTemperature.return_value = 298.73988991230726 self.mock_u3.getFeedback.side_effect = [[32816], [35696], [32827], [39968]] self.mock_u3.binaryToCalibratedAnalogVoltage.side_effect = ( _binaryToCalibratedAnalogVoltage) self.labjack.ReadValues() point = gps_pb2.Point().FromString(self.point_queue.get()) self.assertEqual(78.061801842153101916, point.labjack_temp_f) self.assertEqual(1.5, point.fuel_level_voltage) self.assertEqual(2.7, point.water_temp_voltage) self.assertEqual(3.9, point.oil_pressure_voltage) self.assertEqual(14.0, point.battery_voltage)
def ReadValues(self): """Reads the labjack voltages.""" try: if self.config.get('labjack'): point = gps_pb2.Point() point.labjack_temp_f = ( self.u3.getTemperature() * 9.0/5.0 - 459.67) for input_name, proto_field in self.config['labjack'].items(): if input_name.startswith('ain') or input_name.startswith('fio'): channel = int(input_name[-1]) # Note getFeedback(u3.AIN(4)) is reading voltage from FIO4. # Physically AIN4 and FIO4 are identical. AIN is for analog input # and FIO is flexible input/output. feedback = self.u3.getFeedback(u3.AIN(channel))[0] is_low_voltage = channel not in self.HIGH_VOLTAGE_CHANNELS voltage = self.u3.binaryToCalibratedAnalogVoltage( feedback, isLowVoltage=is_low_voltage, channelNumber=channel) if input_name in self.config['labjack'].get('tick_divider_10'): voltage = voltage * 10 setattr(point, proto_field, voltage) self.AddPointToQueue(point) except u3.LabJackException: stack_trace = ''.join(traceback.format_exception(*sys.exc_info())) logging.log_every_n_seconds(logging.ERROR, 'Error reading labjack values\n%s', 10, stack_trace)
def ConvertTraqmateToProto(filepath): """Converts a Traqmate CSV file into a exit speed proto. Args: filepath: The file name and path of the Traqmate CSV file. Returns: A exit speed session proto. """ es = main.ExitSpeed() start = time.time() first_elapsed = None for elapsed_time, json_time, lat, lon, alt, speed in _ReadCsvFile( filepath): point = gps_pb2.Point() point.lon = lon point.lat = lat point.alt = alt point.speed_ms = speed es.ProcessReport(point) now = time.time() elapsed_time = float(elapsed_time) if not first_elapsed: first_elapsed = elapsed_time # Traqmate CSV files have data points every 0.025s where as our GPS sensor # will only record at 0.1s. if elapsed_time * 10 % 1 != 0: continue if start + elapsed_time > now: print(json_time, speed) sleep_duration = start + elapsed_time - first_elapsed - now if sleep_duration > 0: time.sleep(sleep_duration) return es.session
def testPerpendicularDistanceToFinish(self): point_b_angle = 60 point_b = gps_pb2.Point() point_b.start_finish_distance = 1000 self.assertEqual( 500.0000000000001, lap_lib.PerpendicularDistanceToFinish(point_b_angle, point_b))
def testCalcTimeAfterFinish(self): start_finish = gps_pb2.Point() start_finish.lat = 45.595015 start_finish.lon = -122.694526 lap = gps_pb2.Lap() point_a = lap.points.add() point_b = lap.points.add() point_c = lap.points.add() point_a.time.FromMilliseconds(1) point_b.time.FromMilliseconds(2) point_c.time.FromMilliseconds(3) point_a.lat = 45.593988 point_a.lon = -122.693587 point_b.lat = 45.594988 point_b.lon = -122.694587 point_c.lat = 45.595000 point_c.lon = -122.694638 point_b.start_finish_distance = common_lib.PointDelta( start_finish, point_b) point_c.start_finish_distance = common_lib.PointDelta( start_finish, point_c) point_a.speed_ms = 68.2 point_b.speed_ms = 70 point_c.speed_ms = 70.2 self.assertEqual(1000000.0548742702, lap_lib.CalcTimeAfterFinish(lap))
def testSolveTimeToCrossFinish(self): point_b = gps_pb2.Point() point_b.speed_ms = 70 acceleration = 2 perp_dist_b = 1 self.assertEqual( 0.014282800023195819, lap_lib.SolveTimeToCrossFinish(point_b, perp_dist_b, acceleration))
def testProcessSession(self): point = gps_pb2.Point() point.speed_ms = 21 lap = gps_pb2.Lap() session = gps_pb2.Session() es = main.ExitSpeed() es.point = point es.session = session es.ProcessSession() for _ in session.laps: for lap_point in lap.points: self.assertEqual(point, lap_point) point = gps_pb2.Point() point.speed_ms = 1 es.point = point es.ProcessSession()
def testCalculateElapsedValues(self): before_point = gps_pb2.Point() prior_point = gps_pb2.Point() prior_point.lat = 12.000000 prior_point.lon = 23.000000 prior_point.time.FromJsonString(u'2020-05-23T17:47:44.100Z') point = gps_pb2.Point() point.lat = 12.000001 point.lon = 23.000002 point.time.FromJsonString(u'2020-05-23T17:47:44.200Z') es = main.ExitSpeed() es.lap = gps_pb2.Lap() es.lap.points.extend([before_point, prior_point, point]) es.point = point es.ProcessPoint() self.assertEqual(prior_point.elapsed_duration_ms, 0) self.assertEqual(prior_point.elapsed_distance_m, 0) self.assertEqual(point.elapsed_duration_ms, 100) self.assertEqual(point.elapsed_distance_m, 0.2430443280901163)
def ProcessPointQueue(self): """Updates instance variables with point values. Image generation takes ~0.3 seconds and most of that time is spent rendering the PNG file. This method ensures we overlaying the most recent data values and emptying the queue. """ for _ in range(self._point_queue.qsize()): point = gps_pb2.Point().FromString(self._point_queue.get()) if point.speed_mph: self._last_speed = point.speed_mph
def Run(self) -> None: """Runs exit speed in a loop.""" self.InitializeSubProcesses() self.AddNewLap() while True: self.point = gps_pb2.Point().FromString(self.point_queue.get()) self.ProcessLap() logging.log_every_n_seconds( logging.INFO, 'Main: Point queue size currently at %d.', 10, self.point_queue.qsize()) self.sdnotify.notify('STATUS=Last report time:%s' % self.point.time.ToJsonString()) self.sdnotify.notify('WATCHDOG=1')
def testGPSProcessLoop(self): point_queue = multiprocessing.Queue() with mock.patch.object(gps.gps, 'next') as mock_get: mock_get.return_value = TEST_REPORT proc = gps_sensor.GPSProcess({}, point_queue) while point_queue.empty(): pass proc.Join() self.assertEqual(point_queue.qsize(), 1) point = gps_pb2.Point().FromString(point_queue.get()) self.assertEqual(point.lat, TEST_REPORT_VALUES['lat']) self.assertEqual(point.lon, TEST_REPORT_VALUES['lon']) self.assertEqual(point.alt, TEST_REPORT_VALUES['alt']) self.assertEqual(point.speed_ms, TEST_REPORT_VALUES['speed'])
def Loop(self): """Adds point data with GPS values to point queue.""" gps_sensor = GPS() while not self.stop_process_signal.value: report = gps_sensor.GetReport() if report: point = gps_pb2.Point() point.lat = report.lat point.lon = report.lon if report.get('alt'): point.alt = report.alt point.speed_ms = report.speed point.geohash = geohash.encode(point.lat, point.lon) self.AddPointToQueue(point)
def Loop(self): """Adds point data with gryoscope values to point queue.""" gyro = Gyroscope() frequency_hz = int( self.config.get('gyroscope', {}).get('frequency_hz')) or 10 while not self.stop_process_signal.value: cycle_time = time.time() x, y, z = gyro.GetRotationalValues() point = gps_pb2.Point() point.gyro_x = x point.gyro_y = y point.gyro_z = z self.AddPointToQueue(point) time.sleep(sensor.SleepBasedOnHertz(cycle_time, frequency_hz))
def setUp(self): super().setUp() _, self.file_path = tempfile.mkstemp(suffix='_1.data') self.point = gps_pb2.Point() self.point.alt = 1 self.point.speed_ms = 1 self.point.lat = 45.69545832462609 self.point.lon = -121.52551179751754 self.point.tps_voltage = 2 self.point.water_temp_voltage = 3 self.point.oil_pressure_voltage = 4 self.point.rpm = 1000 self.point.afr = 14.7 self.point.fuel_level_voltage = 5
def main(unused_argv): config = { 'rtmp_overlay': { 'output': '/tmp/ramdisk/overlay.png', 'resolution': [1280, 720] } } ro = RTMPOverlay(config, start_process=False) ro.AddPointToQueue(gps_pb2.Point(speed=130)) ro.AddLapDuration(1, 90123.456) ro.AddLapDuration(2, 91123.456) ro.AddLapDuration(3, 92123.456) ro.AddLapDuration(4, 94123.456) ro.Do()
def Loop(self): """Adds point data with accelerometer values to point queue.""" accel = Accelerometer() frequency_hz = int( self.config.get('accelerometer', {}).get('frequency_hz')) or 10 while not self.stop_process_signal.value: cycle_time = time.time() x, y, z = accel.GetGForces() point = gps_pb2.Point() point.accelerometer_x = x point.accelerometer_y = y point.accelerometer_z = z pitch, roll = accel.CalcPitchAndRoll(x, y, z) point.pitch = pitch point.roll = roll self.AddPointToQueue(point) time.sleep(sensor.SleepBasedOnHertz(cycle_time, frequency_hz))
def testCalcLastLapDuration(self): start_finish = gps_pb2.Point() start_finish.lat = 45.595015 start_finish.lon = -122.694526 session = gps_pb2.Session() lap = session.laps.add() point_x = lap.points.add() point_y = lap.points.add() point_z = lap.points.add() point_x.time.FromMilliseconds(1) point_y.time.FromMilliseconds(2) point_z.time.FromMilliseconds(3) point_x.lat = 45.593988 point_x.lon = -122.693587 point_y.lat = 45.594988 point_y.lon = -122.694587 point_z.lat = 45.595000 point_z.lon = -122.694638 point_y.start_finish_distance = common_lib.PointDelta( start_finish, point_y) point_z.start_finish_distance = common_lib.PointDelta( start_finish, point_z) point_y.speed_ms = 69.8 point_y.speed_ms = 70 point_z.speed_ms = 70.2 self.assertEqual(2.0 * 1e6, lap_lib.CalcLastLapDuration(session)) lap = session.laps.add() point_a = point_z lap.points.append(point_a) point_b = lap.points.add() point_c = lap.points.add() point_b.time.FromMilliseconds(3) point_c.time.FromMilliseconds(4) point_b.lat = 45.594988 point_b.lon = -122.694587 point_c.lat = 45.595000 point_c.lon = -122.694638 point_b.start_finish_distance = common_lib.PointDelta( start_finish, point_b) point_c.start_finish_distance = common_lib.PointDelta( start_finish, point_c) point_b.speed_ms = 70 point_c.speed_ms = 70.2 self.assertEqual(1000000, lap_lib.CalcLastLapDuration(session))
def testFindNearestBestLapPoint(self): lap = gps_pb2.Lap() point = lap.points.add() point.lat = 1 point.lon = 1 point = lap.points.add() point.lat = 5 point.lon = 5 point = lap.points.add() point.lat = 20 point.lon = 20 self.leds.SetBestLap(lap) # Build the tree. point = gps_pb2.Point() point.lat = 4 point.lon = 4 nearest = self.leds.FindNearestBestLapPoint(point) self.assertEqual(nearest.lat, 5) self.assertEqual(nearest.lon, 5)
def testGetPriorUniquePoint(self): point_c = gps_pb2.Point() point_c.time.FromMilliseconds(10) point_c.lat = 1 point_c.lon = -1 lap = gps_pb2.Lap() point = lap.points.add() point.time.FromMilliseconds(7) point = lap.points.add() point.time.FromMilliseconds(8) point.lat = 8 point.lon = -8 point = lap.points.add() point.time.FromMilliseconds(9) point = lap.points.add() point.time.FromMilliseconds(10) # second point at 10. point.lat = 10 point.lon = -10 returned = lap_lib.GetPriorUniquePoint(lap, point_c) self.assertEqual(8, returned.time.ToMilliseconds())
def testGetLogFilePrefix(self): point = gps_pb2.Point() point.time.FromJsonString(u'2020-05-23T17:47:44.100Z') es = main.ExitSpeed() expected = '/tmp/Corrado/2020-05-23T17:47:44.100000' self.assertEqual(expected, es.GetLogFilePrefix(point, tz=pytz.UTC))
def testGetTimeDelta(self): point_b = gps_pb2.Point() point_b.time.FromMilliseconds(1) point_c = gps_pb2.Point() point_c.time.FromMilliseconds(2) self.assertEqual(1 * 1e6, lap_lib.GetTimeDelta(point_b, point_c))