class U3Proxy(object): t0config = u3.Timer0Config(TimerMode=10) t1config = u3.Timer1Config(TimerMode=11) timer0 = u3.Timer0() timer1 = u3.Timer1() horigin = None lorigin = None def __init__(self): self.instance = U3(debug=False, autoOpen=False) def __enter__(self): self.instance.open() self.instance.configIO(TimerCounterPinOffset=4, NumberOfTimersEnabled=2, EnableCounter0=True, EnableCounter1=0, FIOAnalog=0) _, _, low, high = self.instance.getFeedback(self.t0config, self.t1config, self.timer0, self.timer1) self.horigin = self.horigin or high self.lorigin = self.lorigin or low return U3Resource(self.instance, self.horigin, self.lorigin, high, low) def __exit__(self, type, value, tb): self.instance.close()
def startPWM(self, duty_cycle): if self.live: temp = 65535 - 256 * duty_cycle self.device.configIO(NumberOfTimersEnabled=1) self.device.getFeedback(u3.Timer0Config(TimerMode=1, Value=65535)) self.device.getFeedback(u3.Timer0(Value=temp, UpdateReset=True)) else: print "duty cycle:", duty_cycle
class U3Resource(object): timer0 = u3.Timer0() timer1 = u3.Timer1() counter = u3.Counter0() _reset_offset = 0 def __init__(self, instance, horigin, lorigin, high, low): self.instance = instance self.horigin = horigin self.lorigin = lorigin self.high = high self.low = low def get_monotonic(self): high, low = self.instance.getFeedback(self.timer1, self.timer0) b_high = '{:b}00000000000000000000000000000000'.format(high - self.high) b_low = '{:032b}'.format(low - self.low) tick = int(b_high, 2) + int(b_low, 2) return tick * 2.5e-07 # tick = '{:b}{:032b}'.format(high-self.high, low-self.low) # return int(tick, 2) * 2.5e-07 def get_time(self): return self.get_monotonic() - self._reset_offset def get_origin(self): high, low = self.instance.getFeedback(self.timer1, self.timer0) b_high = '{:b}00000000000000000000000000000000'.format(high - self.high) b_low = '{:032b}'.format(low - self.low) tick = int(b_high, 2) + int(b_low, 2) return tick * 2.5e-07 # high, low = self.instance.getFeedback(self.timer1, self.timer0) # tick = '{:b}{:032b}'.format(high-self.horigin, low-self.lorigin) # return int(tick, 2) * 2.5e-07 def get_counter(self): return self.instance.getFeedback(self.counter)[0] def reset_counter(self): raise NotImplementedError def reset_timer(self): self._reset_offset = self.get_monotonic()
def update_pwm(self, duty): set_bits = 65536 - int(duty * 65536) self.u.getFeedback(u3.Timer0(Value=set_bits, UpdateReset=True))
class ExitSpeed(object): """Main object which loops and logs data.""" LABJACK_TIMER_CMD = u3.Timer0(UpdateReset=True, Value=0, Mode=None) REPORT_REQ_FIELDS = ('lat', 'lon', 'time', 'speed') def __init__( self, start_finish_range=20, # Meters, ~4x the width of straightaways. live_data=True, min_points_per_session=60 * 10): # 1 min @ gps 10hz): """Initializer. Args: start_finish_range: Maximum distance a point can be considered when determining if the car crosses the start/finish. live_data: A boolean, if True indicates that this session's data should be tagged as live. min_points_per_session: Used to prevent sessions from prematurely ending. """ self.start_finish_range = start_finish_range self.live_data = live_data self.min_points_per_session = min_points_per_session self.point_queue = multiprocessing.Queue() self.config = config_lib.LoadConfig() self.leds = leds.LEDs() self.data_logger = None self.timescale = None self.rtmp_overlay = None self.point = None self.session = gps_pb2.Session() self.sdnotify = sdnotify.SystemdNotifier() self.sdnotify.notify('READY=1') 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 AddNewLap(self) -> None: """Adds a new lap to the current session.""" session = self.session lap = session.laps.add() self.lap = lap self.lap.number = len(session.laps) if self.config.get('timescale'): self.timescale.AddLapToQueue(lap) def GetLogFilePrefix(self, point: gps_pb2.Point, tz=None): utc_dt = point.time.ToDatetime() current_dt = utc_dt.replace(tzinfo=datetime.timezone.utc).astimezone( tz=tz) current_seconds = current_dt.second + current_dt.microsecond / 1e6 return os.path.join( FLAGS.data_log_path, '%s/' % self.config.get('car', 'unknown_car'), '%s:%03f' % (current_dt.strftime('%Y-%m-%dT%H:%M'), current_seconds)) def _InitializeDataLogger(self, point: gps_pb2.Point): file_prefix = self.GetLogFilePrefix(point) logging.info('Logging data to %s', file_prefix) self.data_logger = data_logger.Logger(file_prefix) def LogPoint(self) -> None: """Writes the current point to the data log.""" point = self.point if not self.data_logger: self._InitializeDataLogger(point) self.data_logger.WriteProto(point) def CalculateElapsedValues(self): """Populates the elapsed_duration_ms and elapsed_distance_m point values.""" point = self.point if len(self.lap.points) > 1: prior_point = lap_lib.GetPriorUniquePoint(self.lap, self.point) point.elapsed_duration_ms = (point.time.ToMilliseconds() - prior_point.time.ToMilliseconds() + prior_point.elapsed_duration_ms) point.elapsed_distance_m = ( common_lib.PointDelta(point, prior_point) + prior_point.elapsed_distance_m) else: point.elapsed_duration_ms = 0 point.elapsed_distance_m = 0 def ProcessPoint(self) -> None: """Updates LEDs, logs point and writes data to PostgresSQL.""" point = self.point point.start_finish_distance = common_lib.PointDelta( point, self.session.start_finish) point.speed_mph = point.speed_ms * 2.23694 point.speed_kmh = point.speed_ms * 3.6 self.leds.UpdateLeds(point) self.CalculateElapsedValues() self.LogPoint() if self.config.get('timescale'): self.timescale.AddPointToQueue(point, self.lap.number) if self.config.get('rtmp_overlay'): self.rtmp_overlay.AddPointToQueue(point) def SetLapTime(self) -> None: """Sets the lap duration based on the first and last point time delta.""" delta = lap_lib.CalcLastLapDuration(self.session) self.lap.duration.FromNanoseconds(delta) self.leds.SetBestLap(self.lap) if self.config.get('timescale'): self.timescale.AddLapDurationToQueue( self.lap.number, self.lap.duration.ToMilliseconds()) if self.config.get('rtmp_overlay'): self.rtmp_overlay.AddLapDuration( self.lap.number, self.lap.duration.ToMilliseconds()) minutes = self.lap.duration.ToSeconds() // 60 seconds = (self.lap.duration.ToMilliseconds() % 60000) / 1000.0 logging.info('New Lap %d:%.03f', minutes, seconds) def CrossStartFinish(self) -> None: """Checks and handles when the car crosses the start/finish.""" if len(self.lap.points) >= self.min_points_per_session: prior_point = lap_lib.GetPriorUniquePoint(self.lap, self.point) if (self.point.start_finish_distance < self.start_finish_range and # First point past start/finish has an obtuse angle. lap_lib.SolvePointBAngle(prior_point, self.point) > 90): logging.info('Start/Finish') self.leds.CrossStartFinish() self.SetLapTime() self.AddNewLap() # Start and end laps on the same point just past start/finish. self.lap.points.append(prior_point) if self.config.get('timescale'): self.timescale.AddPointToQueue(prior_point, self.lap.number) # Reset elapsed values for first point of the lap. self.point.elapsed_duration_ms = 0 self.point.elapsed_distance_m = 0 self.lap.points.append(self.point) def ProcessLap(self) -> None: """Adds the point to the lap and checks if we crossed start/finish.""" self.ProcessPoint() self.CrossStartFinish() def ProcessSession(self) -> None: """Populates the session proto.""" _, track, start_finish = tracks.FindClosestTrack(self.point) logging.info('Closest track: %s', track.name) self.session.track = track.name self.session.start_finish.lat = start_finish.lat self.session.start_finish.lon = start_finish.lon self.session.car = self.config['car'] self.session.time.FromNanoseconds(self.point.time.ToNanoseconds()) 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 count(self): counterPin = self.portlist[0][1] # lowest timer is fio4, thus lowest counter fio5 if counterPin < 5: self.logger.info("Lowest port for counter is FIO 05") self.logger.info(" ... aborting") exit() self.logger.info(" placing timer on FIO" + str(counterPin - 1) ) self.logger.info(" placing counter on FIO" + str(counterPin) ) numOfCounters = 1 clockBase = "1MHz" clockDivisor = 0 import u3 import datetime import time clkBaseStr = clockBase if clockBase is "1MHz": clockBase = 3 elif clockBase is "4MHz": clockBase = 4 elif clockBase is "12MHz": clockBase = 5 elif clockBase is "48MHz": clockBase = 6 else: self.logger.info("Invalid clockBase for timer/counter specified") self.logger.info(" possible: 1MHz, 4MHz, 12MHz, 48MHz") self.logger.info(" ... aborting") exit() self.logger.info(" clock frequency is " + str(clkBaseStr) ) self.logger.info(" clock divisor is " + str(clockDivisor) ) # Enable the timers, make sure no pin is set to analog self.lj.configIO( NumberOfTimersEnabled = numOfCounters, EnableCounter1=True, TimerCounterPinOffset = counterPin-1, # first comes the timer, then the counter FIOAnalog = 0) sysTimerConf = u3.TimerConfig(0,10,0) self.lj.getFeedback(sysTimerConf) self.lj.configTimerClock(TimerClockBase = clockBase, TimerClockDivisor = clockDivisor) #print "U3 Configuration: ", self.lj.configU3() # handles for timer / counter clkTimer = u3.Timer0(False) counter = u3.Counter1(False) # stop systemtime from computer start_time = systemtime() number_of_measures = 0 ## ## ## Counter Loop while True: if self.STOP is True: # exit condition break # stop actual time act_time = systemtime() - start_time # before sleep startData = self.lj.getFeedback(clkTimer, counter) prevClock = startData[0] prevEvents = startData[1] # pause and wait for events time.sleep( self.parent.count_interval ) # after sleep results = self.lj.getFeedback(clkTimer, counter) clock = results[0] events = results[1] # calculate frequency counts = events - prevEvents # temp store here intervalTime = clock - prevClock # temp store here deltaT = intervalTime / 4e6 freq = float(counts) / deltaT # put measures self.queue.put( (act_time,) + tuple([freq]) ) #print ( (act_time,) + tuple([freq]) ) # count and delay number_of_measures = number_of_measures + 1 # max count/time exceeded if (self.parent.max_count is not None) and (number_of_measures >= self.parent.max_count): break if (self.parent.max_time is not None) and (act_time >= self.parent.max_time): break