Module code.sensors.dataCollectShards
Author: Jonathan Rotter
Collects data from the various sensors and combines it.
Features lots of try-except so that data collection can continue even if one or two sensors fail
Expand source code
#!/usr/bin/env python3.4
'''
Author: Jonathan Rotter
Collects data from the various
sensors and combines it.
Features lots of try-except
so that data collection can
continue even if one or two
sensors fail
'''
import time
import os
import sys
TEMPSENSOR = True
'''
For specifying whenever the temperature sensors should be used.
set it to False if it is broken or the wires are disconnected for example
'''
if TEMPSENSOR:
import tempSensor # contains code for collecting tempSensor data
if __name__ == '__main__':
# add this path to sys.path so that Adafruit_BNO055 can be imported
sys.path.append('/home/pi/Adafruit_Python_BNO055')
# 3rd-party libary from somewhere on github
from Adafruit_BNO055 import BNO055
silent = True
'''
Specify if the data should be printed each time
it is collected
'''
bno = None
'''
Holds an object representing the
Adafruit BNO055 gyroscope sensor
'''
defaultRotation = {'heading': 0, 'roll': 0, 'pitch': 0}
'''
Set on gyroscope startup and is used for setting the initial
rotation to be zero
'''
defaultAcc = {'x': 0, 'y': 0, 'z': 0}
'''
Set on gyroscope startup and is used for setting the initial
acceleration to be zero
'''
gyroRunning = True
'''
If the gyro is running. The variable is used to message that it needs a reboot
'''
hasSetupOnce = False
'''
If the gyro has gone through setup at least once
'''
def setup():
'''
Gyroscope startup code. Sets calibration
values `defaultAcc` and `defaultRotation`
and prints info regarding the sensor
'''
# ---------------------------
# ---- Gyro Startup Code ----
# ---------------------------
global bno, gyroRunning, hasSetupOnce
# make a BNO055 object representing the gyro
# No idea what rst is or why it is set to 18
bno = BNO055.BNO055(serial_port='/dev/serial0', rst=18)
# Register read errors come after this (for debugging)
# variables used in gyro setup
disconnected = False
failureCount = 0
# Initialize the BNO055 and stop if something went wrong.
# Crashes occurs here; Register read error
while True:
try:
# try to start the gyro
disconnected = not bno.begin()
except Exception as e:
# catch an exception and increment the failed start counter
print(e)
# wait a bit
time.sleep(0.1)
failureCount += 1
if failureCount > 10:
# give up after 10 tries
print('You\'re a failure, just like this code')
gyroRunning = False
break # haven't tested if this break statement works
else:
# all things good on startup
break
if disconnected:
# failed to init the gyro
print('Failed to initialize BNO055! Is the sensor connected?')
gyroRunning = False
# if the gyro managed to start well without crashing
if gyroRunning:
# Print system status and self test result.
status, self_test, error = bno.get_system_status()
print('System status: {0}'.format(status))
print('Self test result (0x0F is normal): 0x{0:02X}'.format(self_test))
# Print out an error if system status is in error mode.
if status == 0x01:
raise RuntimeError('System error: {0}'.format(error) +
'\nSee datasheet section 4.3.59 for the meaning.')
# Print BNO055 software revision and other diagnostic data.
sw, bl, accel, mag, gyro = bno.get_revision()
print('Software version: {0}'.format(sw))
print('Bootloader version: {0}'.format(bl))
print('Accelerometer ID: 0x{0:02X}'.format(accel))
print('Magnetometer ID: 0x{0:02X}'.format(mag))
print('Gyroscope ID: 0x{0:02X}\n'.format(gyro))
if hasSetupOnce:
# don't get default values again so a reboot
# doesn't mess up the displayed values
return
# number of measurements to average
MEASUREMENTS = 10
# the first few readings tend to be zero so get rid of those
for i in range(5):
bno.read_euler()
bno.read_linear_acceleration()
time.sleep(0.1)
global defaultRotation, defaultAcc
defaultRotation = {'heading': 0, 'roll': 0, 'pitch': 0}
defaultAcc = {'x': 0, 'y': 0, 'z': 0}
# take ten measurements and average them
for i in range(MEASUREMENTS):
# get orientation
heading, roll, pitch = bno.read_euler()
print(heading, roll, pitch, end=' ')
# sum values, will be divided by the number of measurements later
defaultRotation['heading'] += heading
defaultRotation['roll'] += roll
defaultRotation['pitch'] += pitch
# linear acceleration
x, y, z = bno.read_linear_acceleration()
print(x, y, z)
# sum values, will be divided by the number of measurements later
defaultAcc['x'] += x
defaultAcc['y'] += y
defaultAcc['z'] += z
# pause for 100ms
time.sleep(0.1)
# divide the sum of readings by
# the number of measurements to get the average
defaultRotation['heading'] /= MEASUREMENTS
defaultRotation['roll'] /= MEASUREMENTS
defaultRotation['pitch'] /= MEASUREMENTS
defaultAcc['x'] /= MEASUREMENTS
defaultAcc['y'] /= MEASUREMENTS
defaultAcc['z'] /= MEASUREMENTS
print(defaultAcc)
print(defaultRotation)
# for making sure these values aren't altered if the gyro reboots
hasSetupOnce = True
# ------------------------
# ---- Main Function -----
# ------------------------
def getDataFragment():
'''
Collects data from the various sensors and returns them as a list
Return:
data: A list of all the different sensor values
'''
global gyroRunning
# get the current time
t = time.localtime()
t = ':'.join([str(i).zfill(2) for i in [t.tm_hour, t.tm_min, t.tm_sec]])
# try to get the data from the temperature probe if it is enabled
try:
if TEMPSENSOR:
externalTemp = round(tempSensor.getTemp(), 2)
else:
# no temperature probe data
externalTemp = -1
except:
# some error occurred
externalTemp = 'Error'
try:
# try to get the core temperature of the raspberry pi
coreTemp = os.popen('/opt/vc/bin/vcgencmd measure_temp').read()
coreTemp = round(float(coreTemp[coreTemp.index('=')+1:-3]), 2)
except:
# some error occurred
coreTemp = 'Error'
# Gyro Sensors
try:
heading, roll, pitch = bno.read_euler()
# remove the initial state to get
# orientation relative to its start point
heading -= defaultRotation['heading']
roll -= defaultRotation['roll']
pitch -= defaultRotation['pitch']
# round data
heading = round(heading, 2)
roll = round(roll, 2)
pitch = round(pitch, 2)
# unused
sys, gyro, accel, mag = bno.get_calibration_status()
# read magnetic field
x, y, z = bno.read_magnetometer()
# take the absolute value of the magnetic field and turn it into gauss
magField = pow(x ** 2 + y ** 2 + z ** 2, 0.5)
magField = round(magField / 100, 3) # 100 microTesla = 1 Gauss
# get linear acceleration
x, y, z = bno.read_linear_acceleration()
# for removing strange acceleration picked up when there is none
# btw read_linear_acceleration() takes out gravity already
x -= defaultAcc['x']
y -= defaultAcc['y']
z -= defaultAcc['z']
# round data
x = round(x, 3)
y = round(y, 3)
z = round(z, 3)
# round the temp too
# this is the temperature of the gyro,
# which shows internal ROV temperature
internalTemp = round(bno.read_temp(), 2)
#
# all the data will be displayed on an html page so if the
# values have too many decimal places it will mess up the html table
#
except:
# exception in getting data
heading, roll, pitch = 'Error', 'Error', 'Error'
magField = 'Error'
x, y, z = 'Error', 'Error', 'Error'
internalTemp = 'Error'
gyroRunning = False
if not gyroRunning:
# if the gyro has failed try to reboot it
print('Attempting to restart gyro')
gyroRunning = True
setup()
# assemble the data into a list
fragment = [t, externalTemp, coreTemp, internalTemp,
heading, roll, pitch,
magField, x, y, z
]
# print the data if allowed
if not silent:
print(fragment)
# return the data
return fragment
Global variables
var TEMPSENSOR-
For specifying whenever the temperature sensors should be used. set it to False if it is broken or the wires are disconnected for example
var bno-
Holds an object representing the Adafruit BNO055 gyroscope sensor
var defaultAcc-
Set on gyroscope startup and is used for setting the initial acceleration to be zero
var defaultRotation-
Set on gyroscope startup and is used for setting the initial rotation to be zero
var gyroRunning-
If the gyro is running. The variable is used to message that it needs a reboot
var hasSetupOnce-
If the gyro has gone through setup at least once
var silent-
Specify if the data should be printed each time it is collected
Functions
def getDataFragment()-
Collects data from the various sensors and returns them as a list
Return
data- A list of all the different sensor values
Expand source code
def getDataFragment(): ''' Collects data from the various sensors and returns them as a list Return: data: A list of all the different sensor values ''' global gyroRunning # get the current time t = time.localtime() t = ':'.join([str(i).zfill(2) for i in [t.tm_hour, t.tm_min, t.tm_sec]]) # try to get the data from the temperature probe if it is enabled try: if TEMPSENSOR: externalTemp = round(tempSensor.getTemp(), 2) else: # no temperature probe data externalTemp = -1 except: # some error occurred externalTemp = 'Error' try: # try to get the core temperature of the raspberry pi coreTemp = os.popen('/opt/vc/bin/vcgencmd measure_temp').read() coreTemp = round(float(coreTemp[coreTemp.index('=')+1:-3]), 2) except: # some error occurred coreTemp = 'Error' # Gyro Sensors try: heading, roll, pitch = bno.read_euler() # remove the initial state to get # orientation relative to its start point heading -= defaultRotation['heading'] roll -= defaultRotation['roll'] pitch -= defaultRotation['pitch'] # round data heading = round(heading, 2) roll = round(roll, 2) pitch = round(pitch, 2) # unused sys, gyro, accel, mag = bno.get_calibration_status() # read magnetic field x, y, z = bno.read_magnetometer() # take the absolute value of the magnetic field and turn it into gauss magField = pow(x ** 2 + y ** 2 + z ** 2, 0.5) magField = round(magField / 100, 3) # 100 microTesla = 1 Gauss # get linear acceleration x, y, z = bno.read_linear_acceleration() # for removing strange acceleration picked up when there is none # btw read_linear_acceleration() takes out gravity already x -= defaultAcc['x'] y -= defaultAcc['y'] z -= defaultAcc['z'] # round data x = round(x, 3) y = round(y, 3) z = round(z, 3) # round the temp too # this is the temperature of the gyro, # which shows internal ROV temperature internalTemp = round(bno.read_temp(), 2) # # all the data will be displayed on an html page so if the # values have too many decimal places it will mess up the html table # except: # exception in getting data heading, roll, pitch = 'Error', 'Error', 'Error' magField = 'Error' x, y, z = 'Error', 'Error', 'Error' internalTemp = 'Error' gyroRunning = False if not gyroRunning: # if the gyro has failed try to reboot it print('Attempting to restart gyro') gyroRunning = True setup() # assemble the data into a list fragment = [t, externalTemp, coreTemp, internalTemp, heading, roll, pitch, magField, x, y, z ] # print the data if allowed if not silent: print(fragment) # return the data return fragment def setup()-
Gyroscope startup code. Sets calibration values
defaultAccanddefaultRotationand prints info regarding the sensorExpand source code
def setup(): ''' Gyroscope startup code. Sets calibration values `defaultAcc` and `defaultRotation` and prints info regarding the sensor ''' # --------------------------- # ---- Gyro Startup Code ---- # --------------------------- global bno, gyroRunning, hasSetupOnce # make a BNO055 object representing the gyro # No idea what rst is or why it is set to 18 bno = BNO055.BNO055(serial_port='/dev/serial0', rst=18) # Register read errors come after this (for debugging) # variables used in gyro setup disconnected = False failureCount = 0 # Initialize the BNO055 and stop if something went wrong. # Crashes occurs here; Register read error while True: try: # try to start the gyro disconnected = not bno.begin() except Exception as e: # catch an exception and increment the failed start counter print(e) # wait a bit time.sleep(0.1) failureCount += 1 if failureCount > 10: # give up after 10 tries print('You\'re a failure, just like this code') gyroRunning = False break # haven't tested if this break statement works else: # all things good on startup break if disconnected: # failed to init the gyro print('Failed to initialize BNO055! Is the sensor connected?') gyroRunning = False # if the gyro managed to start well without crashing if gyroRunning: # Print system status and self test result. status, self_test, error = bno.get_system_status() print('System status: {0}'.format(status)) print('Self test result (0x0F is normal): 0x{0:02X}'.format(self_test)) # Print out an error if system status is in error mode. if status == 0x01: raise RuntimeError('System error: {0}'.format(error) + '\nSee datasheet section 4.3.59 for the meaning.') # Print BNO055 software revision and other diagnostic data. sw, bl, accel, mag, gyro = bno.get_revision() print('Software version: {0}'.format(sw)) print('Bootloader version: {0}'.format(bl)) print('Accelerometer ID: 0x{0:02X}'.format(accel)) print('Magnetometer ID: 0x{0:02X}'.format(mag)) print('Gyroscope ID: 0x{0:02X}\n'.format(gyro)) if hasSetupOnce: # don't get default values again so a reboot # doesn't mess up the displayed values return # number of measurements to average MEASUREMENTS = 10 # the first few readings tend to be zero so get rid of those for i in range(5): bno.read_euler() bno.read_linear_acceleration() time.sleep(0.1) global defaultRotation, defaultAcc defaultRotation = {'heading': 0, 'roll': 0, 'pitch': 0} defaultAcc = {'x': 0, 'y': 0, 'z': 0} # take ten measurements and average them for i in range(MEASUREMENTS): # get orientation heading, roll, pitch = bno.read_euler() print(heading, roll, pitch, end=' ') # sum values, will be divided by the number of measurements later defaultRotation['heading'] += heading defaultRotation['roll'] += roll defaultRotation['pitch'] += pitch # linear acceleration x, y, z = bno.read_linear_acceleration() print(x, y, z) # sum values, will be divided by the number of measurements later defaultAcc['x'] += x defaultAcc['y'] += y defaultAcc['z'] += z # pause for 100ms time.sleep(0.1) # divide the sum of readings by # the number of measurements to get the average defaultRotation['heading'] /= MEASUREMENTS defaultRotation['roll'] /= MEASUREMENTS defaultRotation['pitch'] /= MEASUREMENTS defaultAcc['x'] /= MEASUREMENTS defaultAcc['y'] /= MEASUREMENTS defaultAcc['z'] /= MEASUREMENTS print(defaultAcc) print(defaultRotation) # for making sure these values aren't altered if the gyro reboots hasSetupOnce = True