diff --git a/.gitignore b/.gitignore index c6127b3..38dc2db 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,171 @@ modules.order Module.symvers Mkfile.old dkms.conf + +# -*- mode: gitignore; -*- +*~ +\#*\# +/.emacs.desktop +/.emacs.desktop.lock +*.elc +auto-save-list +tramp +.\#* + +# Org-mode +.org-id-locations +*_archive + +# flymake-mode +*_flymake.* + +# eshell files +/eshell/history +/eshell/lastdir + +# elpa packages +/elpa/ + +# reftex files +*.rel + +# AUCTeX auto folder +/auto/ + +# cask packages +.cask/ +dist/ + +# Flycheck +flycheck_*.el + +# server auth directory +/server/ + +# projectiles files +.projectile + +# directory configuration +.dir-locals.el + +# network security +/network-security.data + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +.python-version + +# celery beat schedule file +celerybeat-schedule + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# Project target +robotd diff --git a/LICENSE b/LICENSE index 723ae9a..d7a5dee 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ BSD 2-Clause License -Copyright (c) 2018, Miguel Angel Astor Romero +Copyright (c) 2018, Miguel Astor, Carlos Sanguña and Antonio Russoniello All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ef0d4d2 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +TARGET = robotd +OBJECT = robotd.o +SOURCE = robotd.c +CFLAGS = -std=c11 -Wall -g -O0 `pkg-config --cflags python` +LDLIBS = -lmraa `pkg-config --libs python` + +.PHONY: all +all: $(TARGET) + +$(TARGET): $(OBJECT) + +$(OBJECT): $(SOURCE) + +.PHONY: clean +clean: + $(RM) $(TARGET) $(OBJECT) diff --git a/README.md b/README.md index 34893ae..d495ee4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # Robotd + A control daemon for an Intel Galileo-based robot. diff --git a/robot.py b/robot.py new file mode 100644 index 0000000..b678863 --- /dev/null +++ b/robot.py @@ -0,0 +1,30 @@ +#! /usr/bin/env python + +import mraa +import syslog + +GREEN_LED = 2 +RED_LED = 4 + +syslog.openlog("robot.py", syslog.LOG_PID | syslog.LOG_NDELAY, syslog.LOG_USER) +syslog.syslog(syslog.LOG_NOTICE, "Robot.py started.") + +try: + red = mraa.Gpio(RED_LED) + red.dir(mraa.DIR_OUT) + green = mraa.Gpio(GREEN_LED) + green.dir(mraa.DIR_OUT) + + while True: + red.write(1) + green.write(1) + +except KeyboardInterrupt as e: + syslog.syslog(syslog.LOG_ERR, str(e)) + +finally: + syslog.syslog(syslog.LOG_NOTICE, "Shutting down LEDs.") + red.write(0) + green.write(0) + syslog.syslog(syslog.LOG_NOTICE, "Robot.py finished.") + syslog.closelog() diff --git a/robotd.c b/robotd.c new file mode 100644 index 0000000..9b7647a --- /dev/null +++ b/robotd.c @@ -0,0 +1,92 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define GPIO_PIN_4 4 +#define GPIO_PIN_13 13 + +int main(int argc, char ** argv) { + int rv; + bool done = false; + mraa_gpio_context pin13, pin4; + mraa_result_t mr; + + // Turn the process into a daemon. + rv = daemon(0, 1); + + if (rv != 0) { + perror("daemon(0, 1)"); + return EXIT_FAILURE; + } + + // Open a syslog connection + openlog(argv[0], LOG_NDELAY | LOG_PID, LOG_DAEMON); + syslog(LOG_DAEMON | LOG_NOTICE, "Started robot daemon."); + + // Open PIN 13 as a PULLUP input pin for the push button + pin13 = mraa_gpio_init(GPIO_PIN_13); + mr = mraa_gpio_dir(pin13, MRAA_GPIO_IN); + mr = mraa_gpio_mode(pin13, MRAA_GPIO_PULLUP); + syslog(LOG_DAEMON | LOG_NOTICE, "Push button ready."); + + // TODO: MRAA error handling. + + // Open PIN 4 as an output pin for the red indicator LED + pin4 = mraa_gpio_init(GPIO_PIN_4); + mr = mraa_gpio_dir(pin4, MRAA_GPIO_OUT); + syslog(LOG_DAEMON | LOG_NOTICE, "Red LED ready."); + + // TODO: MRAA error handling. + + // Star pin processing loop + while (!done) { + // Keep the red LED on and read from the push button pin + mr = mraa_gpio_write(pin4, 1); + rv = mraa_gpio_read(pin13); + + // TODO: MRAA error handling. + + if (rv == 0) { + // If the button is pressed then stop reading and go on with the program + syslog(LOG_DAEMON | LOG_NOTICE, "Button push detected."); + done = true; + } + } + + // Turn off the red LED + mr = mraa_gpio_write(pin4, 0); + + // TODO: MRAA error handling. + + // Open the source code file for the Python script + syslog(LOG_DAEMON | LOG_NOTICE, "Opening Python source code."); + FILE * code = fopen("/home/root/robot.py", "r"); + + if (code == NULL) { + syslog(LOG_DAEMON | LOG_NOTICE, "Failed to load Python program."); + return EXIT_FAILURE; + } + + // Execute the Python code + syslog(LOG_DAEMON | LOG_NOTICE, "Performing Python call."); + Py_SetProgramName(argv[0]); + Py_Initialize(); + PyRun_SimpleFile(code, "/home/root/robot.py"); + Py_Finalize(); + + // TODO: Python error handling. + + // Clean up and leave + syslog(LOG_DAEMON | LOG_NOTICE, "Finishing."); + closelog(); + //execlp("shutdown", "shutdown", "-Ph", "now", (char *)NULL); + + return EXIT_SUCCESS; +}