diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..c14e273 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM python:2.7 +MAINTAINER Cem Gokmen + +COPY app /app +WORKDIR /app + +RUN install_git.sh +RUN install_rtimulib.sh +RUN pip install -r requirements.txt + +VOLUME /data +EXPOSE 9000 + +CMD twistd -n -l - -y nobelgt.tac \ No newline at end of file diff --git a/install_git.sh b/install_git.sh new file mode 100644 index 0000000..ec25416 --- /dev/null +++ b/install_git.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -ex #Fail if any line fails, print everything + +apt-get update +apt-get install git \ No newline at end of file diff --git a/install_rtimulib.sh b/install_rtimulib.sh new file mode 100644 index 0000000..5161f13 --- /dev/null +++ b/install_rtimulib.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -ex #Fail if any line fails, print everything + +apt-get update +apt-get install python-dev + +cd /tmp +git clone https://github.com/VIP-LES/RTIMULib2.git + +cd RTIMULib2/Linux/python +python setup.py build +python setup.py install \ No newline at end of file diff --git a/main.py b/main.py index e69de29..5cc4b19 100644 --- a/main.py +++ b/main.py @@ -0,0 +1,51 @@ +from sensormodules import IMUModule, GeigerCounterModule +import logging +import signal +import csv + + +class GracefulKiller: + kill_now = False + + def __init__(self): + signal.signal(signal.SIGINT, self.exit_gracefully) + signal.signal(signal.SIGTERM, self.exit_gracefully) + + def exit_gracefully(self, signum, frame): + self.kill_now = True + + +if __name__ == '__main__': + killer = GracefulKiller() + modules = {} + csvs = {} + + logger = logging.getLogger("verne") + + modules['imu'] = IMUModule(logger.getChild("imu")) + modules['geiger'] = GeigerCounterModule(logger.getChild("geiger"), "/dev/geigerCounter", 9600) + + for m in modules.keys(): + f = open('%s.csv' % m, 'wb') + writer = csv.writer(f, delimiter=' ', quotechar='|', quoting=csv.QUOTE_MINIMAL) + + csvs[m] = (f, writer) + + while True: + for m in modules.keys(): + data = modules[m].poll() + + if len(data) > 0: + currentTime = None # Todo: get the time here. + writer = csvs[m][0] + + for datum in data: + writer.writerow([currentTime] + list(datum)) + + if killer.kill_now: + break + + for c in csvs.values(): + c[1].close() + + print("Goodbye!") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..738c33e --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pyserial==3.3 \ No newline at end of file diff --git a/sensormodules/GeigerCounterModule.py b/sensormodules/GeigerCounterModule.py new file mode 100644 index 0000000..be99db9 --- /dev/null +++ b/sensormodules/GeigerCounterModule.py @@ -0,0 +1,21 @@ +from . import SensorModule +from . import SerialModule + + +class GeigerCounterModule(SensorModule): + def __init__(self, logger, device, baudRate): + self.sm = SerialModule(logger, device, baudRate) + self.logger = logger + + def poll(self): + # The geiger counter's number of ticks is equal to the number of + # characters on the serial output. + + data = self.sm.poll() + + retval = [] + + for _ in xrange(data): + retval.append(True) + + return retval \ No newline at end of file diff --git a/sensormodules/IMUModule.py b/sensormodules/IMUModule.py new file mode 100644 index 0000000..659e9e1 --- /dev/null +++ b/sensormodules/IMUModule.py @@ -0,0 +1,45 @@ +import sys + +import RTIMU +import os.path +import time +import math + +from . import SensorModule + +class IMUModule(SensorModule): + SETTINGS_FILE = "RTIMULib" + + def __init__(self, logger): + sys.path.append('.') + + logger.info("Using settings file " + IMUModule.SETTINGS_FILE + ".ini") + if not os.path.exists(IMUModule.SETTINGS_FILE + ".ini"): + logger.warning("Settings file does not exist, will be created") + + s = RTIMU.Settings(IMUModule.SETTINGS_FILE) + imu = RTIMU.RTIMU(s) + + logger.info("IMU Name: " + imu.IMUName()) + + if not imu.IMUInit(): + raise ValueError("IMU Init Failed") + + imu.setSlerpPower(0.02) + imu.setGyroEnable(True) + imu.setAccelEnable(True) + imu.setCompassEnable(True) + + self.imu = imu + self.poll_interval = imu.IMUGetPollInterval() + self.logger = logger + + def poll(self): + if self.imu.IMURead(): + # x, y, z = imu.getFusionData() + # print("%f %f %f" % (x,y,z)) + data = self.imu.getIMUData() + fusionPose = data["fusionPose"] + processedData = [(math.degrees(fusionPose[0]), math.degrees(fusionPose[1]), math.degrees(fusionPose[2]))] + + return processedData \ No newline at end of file diff --git a/sensormodules/SensorModule.py b/sensormodules/SensorModule.py new file mode 100644 index 0000000..ec3225e --- /dev/null +++ b/sensormodules/SensorModule.py @@ -0,0 +1,12 @@ +import abc + +class SensorModule: + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def poll(self): + """ + This is our module's polling method which will be called from the main event loop. + This method should not block under any circumstances. + """ + return \ No newline at end of file diff --git a/sensormodules/SerialModule.py b/sensormodules/SerialModule.py new file mode 100644 index 0000000..33673ba --- /dev/null +++ b/sensormodules/SerialModule.py @@ -0,0 +1,15 @@ +from . import SensorModule +import serial + +class SerialModule(SensorModule): + def __init__(self, logger, device, baudRate): + self.sd = serial.Serial(device, baudRate, timeout=None) + + self.logger = logger + + def poll(self): + # It's important to realize that this method may produce incomplete data if called + # in the middle of a line and it's up to the main loop to handle that. + if self.sd.in_waiting > 0: + data = self.sd.read(self.sd.in_waiting) + return [data] \ No newline at end of file diff --git a/sensormodules/__init__.py b/sensormodules/__init__.py new file mode 100644 index 0000000..285410b --- /dev/null +++ b/sensormodules/__init__.py @@ -0,0 +1,4 @@ +from SensorModule import SensorModule +from SerialModule import SerialModule +from GeigerCounterModule import GeigerCounterModule +from IMUModule import IMUModule \ No newline at end of file