def Start(self): print("| opening, starting camera service |") # try to open the camera camera = picamera.PiCamera(camera_num=0, stereo_mode='none', stereo_decimate=False, resolution=self.camera_cfg['resolution'], framerate=None, sensor_mode=self.camera_cfg['sensor_mode'], led_pin=None) # camera settings camera.exposure_mode = self.camera_cfg['exposure_mode'] camera.iso = self.camera_cfg['iso'] camera.awb_mode = self.camera_cfg['awb_mode'] camera.awb_gains = self.camera_cfg['awb_gains'] camera.shutter_speed = self.camera_cfg['shutter_speed'] camera.brightness = self.camera_cfg['brightness'] camera.exposure_compensation = self.camera_cfg['exposure_compensation'] camera.meter_mode = self.camera_cfg['meter_mode'] camera.contrast = self.camera_cfg['contrast'] # Create NeoPixel object with appropriate configuration. self.led_flash = Adafruit_NeoPixel( self.camera_cfg['led_count'], self.camera_cfg['led_pin'], self.camera_cfg['led_freq_hz'], self.camera_cfg['led_dma'], self.camera_cfg['led_inverter'], self.camera_cfg['led_brightness'], self.camera_cfg['led_channel'], ws.SK6812W_STRIP) # Intialize the library (must be called once before other functions). self.led_flash.begin() print("| started, autotigger -", self.script_cfg['headless'], "|") if not self.script_cfg['headless']: print('| looking for ', self.script_cfg['path'] + '/tmp/trigger.proc |') else: print('| starting auto capture |') print('| process will run ', self.script_cfg['max'], ' or ', self.script_cfg['triggers'], ' triggers |') # run some basic tests and conenct our script # these script hault on fail, see logs details self.process['start'] = self.Connect() # if everything connects if self.process['start']: # try to open the camera process try: # open the in-memory photo stream stream = BytesIO() # set th flash on # set th flash on self.led_flash.setPixelColor( 0, Color(self.camera_cfg['led_color_r'], self.camera_cfg['led_color_g'], self.camera_cfg['led_color_b'])) self.led_flash.show() # grab a reliable piece of time start_stamp = datetime.now() # init system date stamp # first loop, we need to set the frames stop timecode to the start time frame_stop = perf_counter() # capture frames continuously in-memory until we capture a trigger for photo in camera.capture_continuous(stream, format='jpeg', use_video_port=False, resize=None, splitter_port=0, quality=100): # set th flash off self.led_flash.setPixelColor(0, Color(0, 0, 0)) self.led_flash.show() # time since the last photo the last operation ran camera_lapse = perf_counter() - frame_stop # this frames start timecode frame_start = perf_counter() # get the start byte of our imu file imu_byte = path.getsize(self.script_cfg['path'] + '/tmp/imu.dat') # Truncate the stream to the current position (in case # prior iterations output a longer image) stream.truncate() # this frames stop timecode frame_stop = perf_counter() # get the time stamp that this frame was recveived frame_stamp = start_stamp + timedelta(0, frame_start) # get the total time this operation took frame_lapse = frame_stop - frame_start self.process['loop'] += 1 # this loop counts result = {} # tmp holder for the IMU data result[ 'telemetry'] = '' # we will get this on post process # store the results meta data for this frame result['trigger'] = format(frame_stamp) result['trigger_lapse'] = "{:.12f}".format(frame_lapse) result['camera_lapse'] = "{:.12f}".format(camera_lapse) result['imu_byte'] = imu_byte # if we have hit the max amount of loops then we need to stop if self.script_cfg['max'] != 0 and self.process[ 'loop'] >= self.script_cfg['max']: # close our connections, kill everything stream.close() self.End(camera) break # if we have hit the max amount of triggers then we need to stop elif self.script_cfg['triggers'] != 0 and self.process[ 'count'] >= self.script_cfg['triggers']: # close our connections, save everything stream.close() self.End(camera) break # otherwise lets see if a stop file exists elif path.isfile(self.script_cfg['path'] + '/tmp/stop.proc'): # close our connections, save everything stream.close() self.End(camera) break # test our triggers else: # if we are set to run headless then do not wait for the tigger file if self.script_cfg['headless']: print("| capture | ") self.process['count'] += 1 # this trigger counts self.process['loop'] = 0 # reset the loop count # get the file name and open the file result['image'] = "image-" + str( self.process['count']).zfill(4) + ".jpg" # write our frame to a file file = open( self.script_cfg['path'] + "/tmp/" + result['image'], 'wb') file.flush() # <-- here's something not to forget! # Rewind the stream and write the file to tmp stream.seek(0) file.write(stream.read()) file.close() # get the file size result['size'] = path.getsize( self.script_cfg['path'] + "/tmp/" + result['image']) # Reset the stream for the next capture stream.seek(0) stream.truncate() stream.flush() # send the result to the database DBLite.InsertDB(DBLite, self.process['connection'], self.script_cfg, result) print("| complete -", result, " | ") # set th flash on self.led_flash.setPixelColor( 0, Color(self.camera_cfg['led_color_r'], self.camera_cfg['led_color_g'], self.camera_cfg['led_color_b'])) self.led_flash.show() # otherwise lets see if a tigger file exists elif path.isfile(self.script_cfg['path'] + '/tmp/trigger.proc'): print("| capture trigger | ") self.process['count'] += 1 # this trigger counts self.process['loop'] = 0 # reset the loop count # get the file name and open the file result['image'] = "image-" + str( self.process['count']).zfill(4) + ".jpg" # write our frame to a file file = open( self.script_cfg['path'] + "/tmp/" + result['image'], 'wb') file.flush() # <-- here's something not to forget! # Rewind the stream and write the file to tmp stream.seek(0) file.write(stream.read()) file.close() # get the file size result['size'] = path.getsize( self.script_cfg['path'] + "/tmp/" + result['image']) # Reset the stream for the next capture stream.seek(0) stream.truncate() stream.flush() # send the result to the database DBLite.InsertDB(DBLite, self.process['connection'], self.script_cfg, result) # remove the trigger file remove(self.script_cfg['path'] + '/tmp/trigger.proc') print("| complete -", result, " | ") # set th flash on # set th flash on self.led_flash.setPixelColor( 0, Color(self.camera_cfg['led_color_r'], self.camera_cfg['led_color_g'], self.camera_cfg['led_color_b'])) self.led_flash.show() else: # throw away this frame, no trigger found print("| rest offset -", self.offsets_cfg['rest'], " | ") # Reset the stream for the next capture stream.seek(0) stream.truncate() stream.flush() sleep(self.offsets_cfg['rest']) except KeyboardInterrupt: print("| bye user exit, closing connections |") # close our connections, kill everything stream.close() self.End(camera) else: print("| failed to connect services, closing camera |") # close the camera, something went wrong starting our services camera.close()
def Start(self): print("| starting, autotigger -", self.script_cfg['headless'], "|") # report the start if self.script_cfg['debug']: print('start looking for ', self.script_cfg['path'] + '/tmp/trigger.proc') print('process start ', self.process['loop'], ' will run ', self.script_cfg['max'], ' or ', self.script_cfg['triggers'], ' triggers') # run some basic tests and conenct our script # these script hault on fail, see logs details self.process['start'] = self.Connect() # run the process if our tests are valid while self.process['start']: # constructs our process loop # start monitoring our process try: # if we have hit the max amount of loops then we need to stop if self.script_cfg['max'] != 0 and self.process[ 'loop'] >= self.script_cfg['max']: # stop the process and exit self.End() break # if we have hit the max amount of triggers then we need to stop elif self.script_cfg['triggers'] != 0 and self.process[ 'count'] >= self.script_cfg['triggers']: # stop the process and exit self.End() break # runs some triggers else: # if we are set to run headless then do not wait for the tigger file if self.script_cfg['headless']: # run the tigger process, now result = self.Event(True) if not result: print(" trigger was not valid ") else: print(" trigger was valid ") # send the result to the database DBLite.InsertDB(DBLite, self.process['connection'], self.script_cfg, result) # otherwise lets see if a tigger file exists else: # look for the tigger file in the following path if path.isfile(self.script_cfg['path'] + '/tmp/trigger.proc' ): # does the trigger file exists fire # run the tigger process, now result = self.Event(True) if not result: print(" trigger is not ready ") else: print(" trigger recorded storing ") # send the result to the database DBLite.InsertDB(DBLite, self.process['connection'], self.script_cfg, result) # remove the trigger file remove(self.script_cfg['path'] + '/tmp/trigger.proc') else: # run the tigger process, fail self.Event(False) except KeyboardInterrupt: print("| bye early exit, closing connections |") # close our connections DBLite.CloseDB(DBLite, self.process['connection'], self.script_cfg) IMUDevice.StopIMU(IMUDevice, self.process['pid'], self.script_cfg) exit()