From 378974f15b2d8bb82cff71a80112ae24f5f2691a Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 23 Feb 2015 16:28:18 +0100 Subject: [PATCH 001/169] Started MCP3424 module --- Makefile.am | 6 +++--- mcp3424/MCP3424.cpp | 1 + mcp3424/MCP3424.hpp | 3 +++ 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 mcp3424/MCP3424.cpp create mode 100644 mcp3424/MCP3424.hpp diff --git a/Makefile.am b/Makefile.am index d54e486..fa257f7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,11 @@ bin_PROGRAMS = openstratos -openstratos_SOURCES = openstratos.cpp camera/Camera.cpp gps/GPS.cpp serial/Serial.cpp battery/Battery.cpp temperature/Temperature.cpp +openstratos_SOURCES = openstratos.cpp camera/Camera.cpp gps/GPS.cpp serial/Serial.cpp battery/Battery.cpp temperature/Temperature.cpp mcp3424/MCP3424.cpp openstratos_LDADD = -lwiringPi openstratos_CPPFLAGS = -std=c++11 -Wno-unused-result EXTRA_PROGRAMS = openstratosRoot utesting -openstratosRoot_SOURCES = openstratos-root.cpp camera/Camera.cpp gps/GPS.cpp serial/Serial.cpp battery/Battery.cpp temperature/Temperature.cpp +openstratosRoot_SOURCES = openstratos-root.cpp camera/Camera.cpp gps/GPS.cpp serial/Serial.cpp battery/Battery.cpp temperature/Temperature.cpp mcp3424/MCP3424.cpp openstratosRoot_CPPFLAGS = -std=c++11 -Wno-unused-result -utesting_SOURCES = testing/testing.cpp camera/Camera.cpp gps/GPS.cpp serial/Serial.cpp battery/Battery.cpp temperature/Temperature.cpp +utesting_SOURCES = testing/testing.cpp camera/Camera.cpp gps/GPS.cpp serial/Serial.cpp battery/Battery.cpp temperature/Temperature.cpp mcp3424/MCP3424.cpp utesting_CPPFLAGS = -std=c++11 -Itesting/bandit -Wno-unused-result -DOS_TESTING diff --git a/mcp3424/MCP3424.cpp b/mcp3424/MCP3424.cpp new file mode 100644 index 0000000..17b5026 --- /dev/null +++ b/mcp3424/MCP3424.cpp @@ -0,0 +1 @@ +#include "MCP3424.hpp" \ No newline at end of file diff --git a/mcp3424/MCP3424.hpp b/mcp3424/MCP3424.hpp new file mode 100644 index 0000000..91e0cc7 --- /dev/null +++ b/mcp3424/MCP3424.hpp @@ -0,0 +1,3 @@ +#ifndef MCP_H + #define MCP_H +#endif \ No newline at end of file From 2dd24c162a5af40a1bc2393b43dd09cb4611be15 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 23 Feb 2015 18:13:17 +0100 Subject: [PATCH 002/169] Added contribution agreement --- DCO.txt | 25 ++++++++++++++ contributing.md | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 DCO.txt create mode 100644 contributing.md diff --git a/DCO.txt b/DCO.txt new file mode 100644 index 0000000..a404c0d --- /dev/null +++ b/DCO.txt @@ -0,0 +1,25 @@ +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(1) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(2) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(3) The contribution was provided directly to me by some other + person who certified (1), (2) or (3) and I have not modified + it. + +(4) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/contributing.md b/contributing.md new file mode 100644 index 0000000..5d8d7ca --- /dev/null +++ b/contributing.md @@ -0,0 +1,88 @@ +# Contributing to OpenStratos # + +OpenStratos is an open source project developed by university students, and accepts contributions from the community. These contributions are made in the form of Issues or [Pull Requests](https://help.github.com/articles/using-pull-requests/) on the [OpenStratos repositories](https://github.com/OpenStratos) on GitHub. + +Issues are a quick way to point out a bug. If you find a bug or documentation error in OpenStratos then please check a few things first: + +1. It is not already an open issue +2. The issue has already been fixed (check the develop branch, or look for closed issues) +3. Can you solve the issue yourself? + +Reporting issues is helpful but an even better approach is to send a pull Request, which is done by "forking" the main repository and committing to your own copy. This will require you to use the version control system called Git. + +The bug tracker is located at [openstratos.org](https://openstratos.org/bugtracker/). Please post your issues there. + +## Guidelines ## + +Before we look into how, here are the guidelines. If your Pull Requests fail +to pass these guidelines it will be declined and you will need to re-submit +when you’ve made the changes. This might sound a bit tough, but it is required +for us to maintain quality of the code-base. + + +### Code style + +All C++ code must meet the [Google C++ style guide](http://google-styleguide.googlecode.com/svn/trunk/cppguide.html). All the Python code must meet the [Google Python Style Guide](https://google-styleguide.googlecode.com/svn/trunk/pyguide.html). This makes certain that all code is the same format as the existing code and means it will be as readable as possible. + +### Compatibility + +OpenStratos must be compatible with C++11. This means that it must use all the benefits of C++11 as possible. In the case of Python, it must be Python 3.4+ compatible. We do not support Python 2.x. + +### Branching + +OpenStratos uses the [Git-Flow](http://nvie.com/posts/a-successful-git-branching-model/) branching model which requires all pull requests to be sent to the "develop" branch. This is where the next planned version will be developed. The "master" branch will always contain the latest stable version and is kept clean so a "hotfix" (e.g: an emergency security patch) can be applied to master to create a new version, without worrying about other features holding it up. For this reason all commits need to be made to "develop" and any sent to "master" will be closed automatically. If you have multiple changes to submit, please place all changes into their own branch on your fork. + +One thing at a time: A pull request should only contain one change. That does not mean only one commit, but one change - however many commits it took. The reason for this is that if you change X and Y but send a pull request for both at the same time, we might really want X but disagree with Y, meaning we cannot merge the request. Using the Git-Flow branching model you can create new branches for both of these features and send two requests. + +### Signing + +You must sign your work, certifying that you either wrote the work or otherwise have the right to pass it on to an open source project. Git makes this trivial as you merely have to use `--signoff` on your commits to your OpenStratos fork. + +`git commit --signoff` + +or simply + +`git commit -s` + +This will sign your commits with the information setup in your git config, e.g. + +`Signed-off-by: Razican ` + +If you are using [Tower](http://www.git-tower.com/) there is a "Sign-Off" checkbox in the commit window. You could even alias git commit to use the `-s` flag so you don’t have to think about it. + +By signing your work in this manner, you certify to a "Developer's Certificate of Origin". The current version of this certificate is in the `DCO.txt` file in the root of this repository. + +## How-to Guide + +There are two ways to make changes, the easy way and the hard way. Either way you will need to [join GitHub](https://github.com/join). + +Easy way GitHub allows in-line editing of files for making simple typo changes and quick-fixes. This is not the best way as you are unable to test if the code works. If you do this you could be introducing syntax errors, etc, but for a Git-phobic user this is good for a quick-fix. + +Hard way The best way to contribute is to "clone" your fork of OpenStratos to your development area. That sounds like some jargon, but "forking" on GitHub means "making a copy of that repo to your account" and "cloning" means "copying that code to your environment so you can work on it". + +1. Set up Git (Windows, Mac & Linux) +2. Go to the OpenStratos repo you want to contribute to. +3. Fork it +4. Clone your OpenStratos repo. +5. Checkout the "develop" branch. +6. Create a new branch for your changes. At this point you are ready to start making changes. +6. Fix existing bugs on the Issue tracker after taking a look to see nobody else is working on them. +7. Commit the files. +8. Push your branch to your fork. +9. [Send a pull request](https://help.github.com/articles/using-pull-requests/) + +The core developers will now be alerted about the change and at least one of the team will respond. If your change fails to meet the guidelines it will be bounced, or feedback will be provided to help you improve it. + +Once the core developer handling your pull request is happy with it they will merge it into develop and your patch will be part of the next release. + +### Keeping your fork up-to-date + +Unlike systems like Subversion, Git can have multiple remotes. A remote is the name for a URL of a Git repository. By default your fork will have a remote named "origin" which points to your fork, but you can add another remote named "upstream" which points to the OpenStratos repository. This is a read-only remote but you can pull from this develop branch to update your own. + +If you are using command-line you can do the following: + +1. `git remote add upstream {OpenStratos repo}` +2. `git pull upstream develop` +3. `git push origin develop` + +Now your fork is up to date. This should be done regularly, or before you send a pull request at least. From 58cf517242aed8394783c21fc9191b99e2ac8a2e Mon Sep 17 00:00:00 2001 From: Jordan Aranda Date: Tue, 24 Feb 2015 00:21:06 +0100 Subject: [PATCH 003/169] PCB Design Added Needs GPS, XBEE, GSM and ADC modules. USB UART Serials for XBEE and GPS. --- pcb_design/OpenStratos.sch | 2746 ++++++++++++++++++++++++++++++++++++ 1 file changed, 2746 insertions(+) create mode 100644 pcb_design/OpenStratos.sch diff --git a/pcb_design/OpenStratos.sch b/pcb_design/OpenStratos.sch new file mode 100644 index 0000000..3617a23 --- /dev/null +++ b/pcb_design/OpenStratos.sch @@ -0,0 +1,2746 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>DC POWER JACK</b> Pad shape changed to LONG 2007.07.26<p> +Source: DCJ0303.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME + + + + + + + + + + + + +>NAME + + + + + + + + + + + + + +<b>DC POWER JACK</b><p> +Source: DCJ0303.pdf + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ +<br><br> +You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + +>VALUE + + + + + +<b>SUPPLY SYMBOL</b> + + + + + + + + + + + + + + + + +<B>DIODE</B><p> +diameter 2 mm, horizontal, grid 7.62 mm + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<B>DIODE</B><p> +general purpose rectifier, 1 A + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find drivers, regulators, and amplifiers.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ +<br><br> +You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + + + + + + + + + + + + + + +<b>SOT-223</b> + + + + + + + + +>NAME +>VALUE + + + + + + + + + + +<b>DPAK</b><p> +PLASTIC PACKAGE CASE 369C-01<br> +Source: http://www.onsemi.co.jp .. LM317M-D.PDF + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +ADJ +IN +OUT + + + + + + + +<b>Voltage Regulator</b> +Standard LM317 adjustable voltage regulator. AOI (Adjust Output Input). Google 'LM317 Calculator' for easy to use app to get the two resistor values needed. 240/720 for 5V output. 240/390 for 3.3V output. Spark Fun Electronics SKU : COM-00527 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ +<br><br> +You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>Name +>Value + + +<b>RESISTOR</b><p> +chip + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +>NAME +>VALUE + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>CAPACITOR</b><p> +chip + + + + + + + + +>NAME +>VALUE + + + + + + +1/6W Thru-hole Resistor - *UNPROVEN* + + + + + + +>NAME +>VALUE + + + + + + +>NAME +>VALUE + + + + +1/4W Resistor, 0.4" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +1/2W Resistor, 0.5" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +1W Resistor, 0.6" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +2W Resistor, 0.8" wide<p> + +Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> + + + + + + +>Name +>Value + + +<h3>AXIAL-0.3-KIT</h3> + +Commonly used for 1/4W through-hole resistors. 0.3" pitch between holes.<br> +<br> + +<b>Warning:</b> This is the KIT version of the AXIAL-0.3 package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + + + + + + + + + + +This is the "EZ" version of the standard .3" spaced resistor package.<br> +It has a reduced top mask to make it harder to install upside-down. + + + + + + + + + + +>Name +>Value + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + +<b>Resistor</b> +Basic schematic elements and footprints for 0603, 1206, and PTH resistors. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +TOP + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 +J8 +>VALUE +39 + + + + +>NAME +11 +21 +31 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE +Connector +J8 +TL +TR +BL +BR +Mounting holes + + + + + + + + + + + +<b>Raspberry Pi B+</b><br> +Based on issue: Thursday, July 10, 2014 - Rev 1.2<p> +LBR by Tim R. 07-2014 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ +<br><br> +You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + +<b>USB Series A Hole Mounted</b> + + + + + + + + + + + + + + + + + + + + + +>NAME +PCB Edge + + + + +<b>USB Series A Surface Mounted</b> + + + + + + + + + + + + + + + + +>NAME + + +<b>USB Series Mini-B Hole Mounted</b> + + + + + + + + + + + + + + + + + + + + +>NAME + + + + + + +USB Series B Surface Mounted + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME + + + + +<b>USB Series Mini-B Surface Mounted</b> + + + + + + + + + + + + + + + + +>VALUE +>NAME + + + + +<b>USB Series B Hole Mounted</b> + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + +<b>USB Series Mini-B Surface Mounted</b> + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + +Card-edge USB A connector. + +For boards designed to be plugged directly into a USB slot. If possible, ensure that your PCB is about 2.4mm thick to fit snugly. + + + + + + + + +>Name +>Value +Card edge + + +<b>USB Series B Hole Mounted</b> + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + +>NAME + + + + + + + + + + + + + + + + + + +>NAME + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + +Micro USB Package + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +PCB Edge + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +PCB Edge + + + + + + + + + + + + + + + + + + + + + + + +USB + + + + + + + + +<b>USB Connectors</b> +<p>USB-B-PTH is fully proven SKU : PRT-00139/CONN-08278 +<p>USB-miniB is fully proven SKU : PRT-00587 +<p>USB-A-PCB is untested. +<p>USB-A-H is throughly reviewed, but untested. Spark Fun Electronics SKU : PRT-00437 +<p>USB-B-SMT is throughly reviewed, but untested. Needs silkscreen touching up. +<p>USB-A-S has not been used/tested +<p>USB-MB-H has not been used/tested +<P>USB-MICROB has been used. CONN-09505 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<h3>SparkFun Electronics' preferred foot prints</h3> +In this library you'll find all manner of retired footprints for resistors, capacitors, board names, ICs, etc., that are no longer used in our catalog.<br><br> +We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. +<br><br> +<b>Licensing:</b>Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ +<br><br> +You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. + + +<b>OMRON SWITCH</b> + + + + + + + + + + + + + + + + + + + + + + + + +>NAME + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>NAME +>Value + + + + + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + +<b>Momentary Switch</b><br> +Button commonly used for reset or general input.<br> +Spark Fun Electronics SKU : COM-00097<br> +SMT- SWCH-08247 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +<b>Relays</b><p> +<ul> +<li>Eichhoff +<li>Finder +<li>Fujitsu +<li>HAMLIN +<li>OMRON +<li>Matsushita +<li>NAiS +<li>Siemens +<li>Schrack +</ul> +<author>Created by librarian@cadsoft.de</author> + + +<b>AUTOMOTIVE QUIET RELAY</b> NAiS<p> +Source: http://www.mew-europe.com/.. en_ds_61208_0000.pdf + + + + + + + + + + + + + +>NAME +>VALUE + + + + + + + + + + + + + + + +>VALUE +>PART + + + + + + + + + +>PART + + + + + + + +<b>AUTOMOTIVE QUIET RELAY</b> NAiS<p> +Source: http://www.mew-europe.com/.. en_ds_61208_0000.pdf + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +BATTERY_1_1000mAh + + + + +RASPBERRY_PI_A+ + + + + +BATTERY_2_4000mAh + + + + +BATTERY_3_1000mAh + + + + + + + + +3V RELAYS +USB_MODULE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Since Version 6.2.2 text objects can contain more than one line, +which will not be processed correctly with this version. + + + From a7217be0254231f298b669806cb7502e497aa0da Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 24 Feb 2015 23:45:12 +0100 Subject: [PATCH 004/169] Moved PCB design and updated bandit --- pcb_design/OpenStratos.sch | 2746 ------------------------------------ testing/bandit | 2 +- 2 files changed, 1 insertion(+), 2747 deletions(-) delete mode 100644 pcb_design/OpenStratos.sch diff --git a/pcb_design/OpenStratos.sch b/pcb_design/OpenStratos.sch deleted file mode 100644 index 3617a23..0000000 --- a/pcb_design/OpenStratos.sch +++ /dev/null @@ -1,2746 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>DC POWER JACK</b> Pad shape changed to LONG 2007.07.26<p> -Source: DCJ0303.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME - - - - - - - - - - - - ->NAME - - - - - - - - - - - - - -<b>DC POWER JACK</b><p> -Source: DCJ0303.pdf - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find non-functional items- supply symbols, logos, notations, frame blocks, etc.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ -<br><br> -You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - ->VALUE - - - - - -<b>SUPPLY SYMBOL</b> - - - - - - - - - - - - - - - - -<B>DIODE</B><p> -diameter 2 mm, horizontal, grid 7.62 mm - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<B>DIODE</B><p> -general purpose rectifier, 1 A - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find drivers, regulators, and amplifiers.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ -<br><br> -You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - - - - - - - - - - - - - - -<b>SOT-223</b> - - - - - - - - ->NAME ->VALUE - - - - - - - - - - -<b>DPAK</b><p> -PLASTIC PACKAGE CASE 369C-01<br> -Source: http://www.onsemi.co.jp .. LM317M-D.PDF - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -ADJ -IN -OUT - - - - - - - -<b>Voltage Regulator</b> -Standard LM317 adjustable voltage regulator. AOI (Adjust Output Input). Google 'LM317 Calculator' for easy to use app to get the two resistor values needed. 240/720 for 5V output. 240/390 for 3.3V output. Spark Fun Electronics SKU : COM-00527 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find resistors, capacitors, inductors, test points, jumper pads, etc.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ -<br><br> -You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - ->Name ->Value - - -<b>RESISTOR</b><p> -chip - - - - - - - - - - ->NAME ->VALUE - - - - - - - - ->NAME ->VALUE - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>CAPACITOR</b><p> -chip - - - - - - - - ->NAME ->VALUE - - - - - - -1/6W Thru-hole Resistor - *UNPROVEN* - - - - - - ->NAME ->VALUE - - - - - - ->NAME ->VALUE - - - - -1/4W Resistor, 0.4" wide<p> - -Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> - - - - - - ->Name ->Value - - -1/2W Resistor, 0.5" wide<p> - -Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> - - - - - - ->Name ->Value - - -1W Resistor, 0.6" wide<p> - -Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> - - - - - - ->Name ->Value - - -2W Resistor, 0.8" wide<p> - -Yageo CFR series <a href="http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf">http://www.yageo.com/pdf/yageo/Leaded-R_CFR_2008.pdf</a> - - - - - - ->Name ->Value - - -<h3>AXIAL-0.3-KIT</h3> - -Commonly used for 1/4W through-hole resistors. 0.3" pitch between holes.<br> -<br> - -<b>Warning:</b> This is the KIT version of the AXIAL-0.3 package. This package has a smaller diameter top stop mask, which doesn't cover the diameter of the pad. This means only the bottom side of the pads' copper will be exposed. You'll only be able to solder to the bottom side. - - - - - - - - - - ->Name ->Value - - - - - - - - - - - - - - - - - - - - - - - - - - -This is the "EZ" version of the standard .3" spaced resistor package.<br> -It has a reduced top mask to make it harder to install upside-down. - - - - - - - - - - ->Name ->Value - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - -<b>Resistor</b> -Basic schematic elements and footprints for 0603, 1206, and PTH resistors. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -TOP - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -1 -J8 ->VALUE -39 - - - - ->NAME -11 -21 -31 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE -Connector -J8 -TL -TR -BL -BR -Mounting holes - - - - - - - - - - - -<b>Raspberry Pi B+</b><br> -Based on issue: Thursday, July 10, 2014 - Rev 1.2<p> -LBR by Tim R. 07-2014 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b> Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ -<br><br> -You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - -<b>USB Series A Hole Mounted</b> - - - - - - - - - - - - - - - - - - - - - ->NAME -PCB Edge - - - - -<b>USB Series A Surface Mounted</b> - - - - - - - - - - - - - - - - ->NAME - - -<b>USB Series Mini-B Hole Mounted</b> - - - - - - - - - - - - - - - - - - - - ->NAME - - - - - - -USB Series B Surface Mounted - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME - - - - -<b>USB Series Mini-B Surface Mounted</b> - - - - - - - - - - - - - - - - ->VALUE ->NAME - - - - -<b>USB Series B Hole Mounted</b> - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - -<b>USB Series Mini-B Surface Mounted</b> - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - -Card-edge USB A connector. - -For boards designed to be plugged directly into a USB slot. If possible, ensure that your PCB is about 2.4mm thick to fit snugly. - - - - - - - - ->Name ->Value -Card edge - - -<b>USB Series B Hole Mounted</b> - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - ->NAME - - - - - - - - - - - - - - - - - - ->NAME - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - -Micro USB Package - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME -PCB Edge - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME -PCB Edge - - - - - - - - - - - - - - - - - - - - - - - -USB - - - - - - - - -<b>USB Connectors</b> -<p>USB-B-PTH is fully proven SKU : PRT-00139/CONN-08278 -<p>USB-miniB is fully proven SKU : PRT-00587 -<p>USB-A-PCB is untested. -<p>USB-A-H is throughly reviewed, but untested. Spark Fun Electronics SKU : PRT-00437 -<p>USB-B-SMT is throughly reviewed, but untested. Needs silkscreen touching up. -<p>USB-A-S has not been used/tested -<p>USB-MB-H has not been used/tested -<P>USB-MICROB has been used. CONN-09505 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<h3>SparkFun Electronics' preferred foot prints</h3> -In this library you'll find all manner of retired footprints for resistors, capacitors, board names, ICs, etc., that are no longer used in our catalog.<br><br> -We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com. -<br><br> -<b>Licensing:</b>Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/ -<br><br> -You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage. - - -<b>OMRON SWITCH</b> - - - - - - - - - - - - - - - - - - - - - - - - ->NAME - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->NAME ->Value - - - - - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - -<b>Momentary Switch</b><br> -Button commonly used for reset or general input.<br> -Spark Fun Electronics SKU : COM-00097<br> -SMT- SWCH-08247 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -<b>Relays</b><p> -<ul> -<li>Eichhoff -<li>Finder -<li>Fujitsu -<li>HAMLIN -<li>OMRON -<li>Matsushita -<li>NAiS -<li>Siemens -<li>Schrack -</ul> -<author>Created by librarian@cadsoft.de</author> - - -<b>AUTOMOTIVE QUIET RELAY</b> NAiS<p> -Source: http://www.mew-europe.com/.. en_ds_61208_0000.pdf - - - - - - - - - - - - - ->NAME ->VALUE - - - - - - - - - - - - - - - ->VALUE ->PART - - - - - - - - - ->PART - - - - - - - -<b>AUTOMOTIVE QUIET RELAY</b> NAiS<p> -Source: http://www.mew-europe.com/.. en_ds_61208_0000.pdf - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -BATTERY_1_1000mAh - - - - -RASPBERRY_PI_A+ - - - - -BATTERY_2_4000mAh - - - - -BATTERY_3_1000mAh - - - - - - - - -3V RELAYS -USB_MODULE - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Since Version 6.2.2 text objects can contain more than one line, -which will not be processed correctly with this version. - - - diff --git a/testing/bandit b/testing/bandit index cd1e581..dbcfc1a 160000 --- a/testing/bandit +++ b/testing/bandit @@ -1 +1 @@ -Subproject commit cd1e5816bb817a5e7e1d1a03a02f0f7a68a101c8 +Subproject commit dbcfc1a59319ea7733d6f393b99807a0903b6fbe From 0213f200eff445f4ef5f25ca8c50755a41850ef9 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 25 Feb 2015 15:15:16 +0100 Subject: [PATCH 005/169] Added camera test --- testing/camera_test.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/testing/camera_test.cc b/testing/camera_test.cc index 81f7540..96d4256 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -16,4 +16,18 @@ describe("Camera", [](){ Camera::get_instance().stop(); AssertThat(Camera::get_instance().is_recording(), Equals(false)); }); + + #ifdef RASPIVID + it("file creation test", [&](){ + Camera::get_instance().record(10); + this_thread::sleep_for(chrono::seconds(11)); + + struct stat buf; + int result = stat("os_video.h264", &buf); + + AssertThat(result, Equals(0)); + }); + #else + it_skip("file creation test", [&](){}); + #endif }); From 26e4ae1234d2fe9b31daf1ffe0f63f9cb89e22e3 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 25 Feb 2015 22:14:44 +0100 Subject: [PATCH 006/169] Better config generation --- .gitignore | 1 + config.h | 86 ---------------------------------------------------- configure.ac | 5 ++- 3 files changed, 3 insertions(+), 89 deletions(-) delete mode 100644 config.h diff --git a/.gitignore b/.gitignore index b651be9..e348156 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ Makefile .deps/ .dirstamp *~ +config.h # Eclipse files .project diff --git a/config.h b/config.h deleted file mode 100644 index 308566b..0000000 --- a/config.h +++ /dev/null @@ -1,86 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the `alarm' function. */ -#define HAVE_ALARM 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#define HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the `wiringPi' library (-lwiringPi). */ -#define HAVE_LIBWIRINGPI 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `stpcpy' function. */ -#define HAVE_STPCPY 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "openstratos" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "https://openstratos.org/bugtracker" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "OpenStratos" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "OpenStratos Alpha-1-dev" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "openstratos" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "Alpha-1-dev" - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Version number of package */ -#define VERSION "Alpha-1-dev" - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ diff --git a/configure.ac b/configure.ac index 9244376..6d47806 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ([2.68]) AC_INIT(OpenStratos, Alpha-1-dev, https://openstratos.org/bugtracker) -AC_CONFIG_SRCDIR([openstratos.h]) +AC_CONFIG_SRCDIR([openstratos.cc]) AM_INIT_AUTOMAKE([subdir-objects]) AC_CONFIG_HEADERS([config.h]) @@ -15,7 +15,6 @@ AC_PROG_MAKE_SET AC_CHECK_PROG(RASPIVID, raspivid, yes) # Checks for libraries. -AC_CHECK_LIB([pthread], [pthread_create]) AC_CHECK_LIB([wiringPi], [wiringPiSetupSys]) # Checks for header files. @@ -25,12 +24,12 @@ AC_LANG([C++]) AX_CXX_COMPILE_STDCXX_11() # Checks for typedefs, structures, and compiler characteristics. +AC_CHECK_HEADER_STDBOOL AC_C_INLINE AC_TYPE_SIZE_T # Checks for library functions. AC_FUNC_ERROR_AT_LINE -AC_FUNC_MKTIME AC_CHECK_FUNCS([stpcpy strstr]) AC_CONFIG_FILES([Makefile]) From 3ded729f9056b0faa345e26df25dc575078a4de7 Mon Sep 17 00:00:00 2001 From: Eneko Cruz Date: Sun, 15 Mar 2015 12:46:11 +0100 Subject: [PATCH 007/169] Added controller for the GSM module. Software power control has been tested. Voice calls and text SMS are awaiting testing and geolocation is to be implemented. Signed-off-by: Eneko Cruz --- gsm/GSMDevice.cpp | 156 ++++++++++++++++++++++++++++++++++++++++++++++ gsm/GSMDevice.hpp | 64 +++++++++++++++++++ 2 files changed, 220 insertions(+) create mode 100644 gsm/GSMDevice.cpp create mode 100644 gsm/GSMDevice.hpp diff --git a/gsm/GSMDevice.cpp b/gsm/GSMDevice.cpp new file mode 100644 index 0000000..f33b375 --- /dev/null +++ b/gsm/GSMDevice.cpp @@ -0,0 +1,156 @@ +#include "GSMDevice.hpp" + +using namespace std; + +GSMDevice::GSMDevice(){ //Instantiates a GSM device controlled using GPIO 4 (default, software pwr control) and /dev/ttyAMA0 for UART + GSMDevice(DEFAULT_GPIO,DEFAULT_UART); +} + +//WARNING: May take up to six seconds +GSMDevice::GSMDevice(int gpio, string serial){ //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial){ + gpionum = gpio; + serialPort = serial; + InitSerial(); + InitGSMModule(); + delay(3000); //Allow some time for the GSM module to connect to the network. +} + +void GSMDevice::TogglePWR(){ + //Toggles the power status of the GSM module. Turns it on if it is off and turns it off if it is on. + //WARNING: Takes 2500 miliseconds to complete + + digitalWrite(gpionum, LOW); //Spec says that the adafruit FONA expects a 2000ms low pulse + delay(2000); + digitalWrite(gpionum, HIGH); + delay(500); //Give the module some time to turn on, ensure that when + //function returns the module is operational. +} + +bool GSMDevice::Call(string num){ //Establishes a voice connection with a phone number. The function + char *number = new char[num.length() + 1]; //will return when the voice connection is established. Note that + strcpy(number, num.c_str()); //having a voice connection does not mean that both parties are + char send[20]; //ready to exchange data. In fact, the sender should allow for some + //time before transmitting so that the receiver can answer. + + if(strlen(number)>(sizeof(send)/sizeof(char))-(3+1)){ //If the number does not fit into the buffer, reject it, as + if(OPENSTRATOS_GSM_DEBUG_){ //phone numbers (without C.C.) take 9 chars. + printf("[!] Number too long. Aborting call\n"); + } + return false; + } + strncpy(send, "ATD", strlen("ATD")); //AT command preamble: ATD + strncpy(send+3, number, strlen(number)); //Number to dial + int length = strlen(send); + send[length] = (char)0x3b;//ascii for semicolon //Semicolon ending command + send[length+1] = (char)0x0;//terminate string with null byte + bool success = SerialSendCompareResponse(send, "OK"); //Modem will reply OK if a voice connection was established. + if(OPENSTRATOS_GSM_DEBUG_ && !success){ + printf("[!] ATD+number+; did not reply OK\n"); + } + return success; +} + +bool GSMDevice::AbortCall(){ //Aborts a phone call. No effect if not in a call. + bool success = SerialSendCompareResponse("ATH","OK"); //Returns true if call aborted or if not in a call. + if(OPENSTRATOS_GSM_DEBUG_ && !success){ //Expecting the modem to return OK. + printf("[!] ATH did not reply OK\n"); + } + return success; +} + +bool GSMDevice::SendSMS(string message, string n){ //Sends a short message to a phone number + char *destnum = new char[n.length() + 1]; + strcpy(destnum, n.c_str()); + char *messagechar = new char[message.length() + 1]; + strcpy(messagechar, message.c_str()); + + if (SerialSendCompareResponse("AT+CMGF=1", "OK")==false){ //Select SMS message format + if(OPENSTRATOS_GSM_DEBUG_){ //Abort if the modem cannot be set to text mode. + printf("[!] AT+CMFG=1 did not reply OK to SMS format selection\n"); + } + return false; + } + + char send[30] = "AT+CMGS=\""; //SMS command preamble: AT+CMGS=" + strncpy(send+9 , destnum, 19); //SMS destination (actual phone number) + send[strlen(send)] = (char)0x22;//ascii for " (double quote) //SMS command termination: " + + if (!SerialSendCompareResponse(send, "> ")){ //Input prompt should be open and expecting text input + if(OPENSTRATOS_GSM_DEBUG_){ + printf("[!] Failed SMS attempt. SIM800L did not provide input prompt\n"); + } + return false; //If there is not any input prompt, abort. + } + + serialPrintf(fdesc,messagechar); //Send message + serialPrintf(fdesc,"\r\n"); //Return + FlushSerialInput(); //Module will reply with "+CMGS". Not interested in that, so flush. + return true; //Message sent. +} + +void GSMDevice::BroadcastGeolocation(string n){ //Tries to perform geolocation and sends coordinates to a phone number via SMS. + //TODO +} + +bool GSMDevice::CheckGSMModule(){ //Returns true if module is up and running, false if it is not. + if(SerialSendCompareResponse("AT","OK")){ //Probe the SIM800L, see AT command reference for more info. + return true; + } + return false; +} + +bool GSMDevice::InitSerial(){ + char *cstr = new char[serialPort.length() + 1]; + strcpy(cstr, serialPort.c_str()); + fdesc = serialOpen(cstr, UART_BAUDRATE); + if(fdesc==-1){ //serialOpen returns a standard linux file descriptor. -1 means failed + ;/*EXCEPTION: NO SERIAL PORT AVAILABLE*/ + if(OPENSTRATOS_GSM_DEBUG_){ + printf("[!] Serial port open error\n"); + } + return false; + } + return true; +} + +bool GSMDevice::InitGSMModule(){ + if (wiringPiSetup() == -1){ + /*EXCEPTION: UNABLE TO ACCESS GPIOS*/; + return false; + } + pinMode(gpionum, OUTPUT); //Set GPIO as digital output + digitalWrite(gpionum, HIGH); //Set to high so that GSM module stays in standby until TogglePWR is called + return true; +} + +bool GSMDevice::SerialSendCompareResponse(char *send, char *expected){ + SerialSendRead(send); //Send a string via serial. + return (strcmp(serialin, expected) == 0); //Compare what got placed in serialin with the expected answer +} + +uint16_t GSMDevice::SerialSendRead(char *send) { + FlushSerialInput(); + if(OPENSTRATOS_GSM_DEBUG_){ + printf("[i] Sending: %s", send); + } + serialPrintf(fdesc, send); + uint16_t readlength = SerialReadLine(); + if(OPENSTRATOS_GSM_DEBUG_){ + printf("[i] Received: %s\n", serialin); + } + return readlength; +} + +void GSMDevice::FlushSerialInput() { + serialFlush(fdesc); +} + +uint16_t GSMDevice::SerialReadLine() { + uint16_t i = 0; + while(serialDataAvail(fdesc)&&i<254) { + char c = serialGetchar(fdesc); + serialin[i++] = c; + } + serialin[i] = 0x0; + return i; +} diff --git a/gsm/GSMDevice.hpp b/gsm/GSMDevice.hpp new file mode 100644 index 0000000..de80a02 --- /dev/null +++ b/gsm/GSMDevice.hpp @@ -0,0 +1,64 @@ +#ifndef OPENSTRATOS_WIRINGPI_H_ +#define OPENSTRATOS_WIRINGPI_H_ +#include +#endif + +#ifndef OPENSTRATOS_WIRINGSERIAL_H +#define OPENSTRATOS_WIRINGSERIAL_H +#include +#endif + +#ifndef OPENSTRATOS_GSM_INCLUDE_ALL_ +#define OPENSTRATOS_GSM_INCLUDE_ALL_ +#include +#include +#include +#include +#include +#include +#endif + +#define OPENSTRATOS_GSM_DEBUG_ 0 +//0 = disable debug mode +//1 = enable debug mode + +#ifndef OPENSTRATOS_GSM_GSMDEVICE_CLASS_ +#define OPENSTRATOS_GSM_GSMDEVICE_CLASS_ +using namespace std; + +class GSMDevice{ + public: + GSMDevice(); //Instantiates a GSM device controlled using GPIO 4 (default, software pwr control) and /dev/ttyAMA0 for UART + GSMDevice(int gpio, string serial); //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial); + void TogglePWR(); //Toggles the power status of the GSM module. Turns it on if it is off and turns it off if it is on. + bool Call(string number); //Calls a given phone number. Returns true if suceeded, false if failed. + bool AbortCall(); //Aborts a phone call. Returns true if suceeded, false if failed or not in a call. + bool SendSMS(string message, string n); //Sends a short message to a phone number. Returns true if suceeded, false if failed + void BroadcastGeolocation(string n); //Tries to perform geolocation and sends coordinates to a phone number via SMS. + bool CheckGSMModule(); //Returns true if module is up and running, false if it is not + private: + uint16_t SerialReadLine(); + uint16_t SerialSendRead(char *); + void FlushSerialInput(); //Discards all data received from the serial port. + bool SerialSendCompareResponse(char*, char*); //Sends a string of data via serial port. Checks that the reply matches with another string. + bool InitGSMModule(); //Initializes the gsm module. Returns true if successful. False if failed. + bool InitSerial(); //Initializes the serial interface. Returns true if successful. False if failed. + int gpionum; //GPIO pin used for software power control + string serialPort; //Serial port identifier. Tipically /dev/ttyAMA0 in Raspbian. + int fdesc; //Standard unix file descriptor associated with the serial port (see serialPort) + char serialin[255]; //Buffer on which data received via the serial port is placed +}; +#endif + +#ifndef OPENSTRATOS_GSM_DEFAULT_PARAMETERS_ +#define OPENSTRATOS_GSM_DEFAULT_PARAMETERS_ +#define DEFAULT_UART "/dev/ttyAMA0" +#define DEFAULT_GPIO 4 +#define UART_BAUDRATE 4800 +#endif + +#ifndef OPENSTRATOS_GSM_GPIO_VALUES_ +#define OPENSTRATOS_GSM_GPIO_VALUES_ +#define HIGH 1 +#define LOW 0 +#endif From 0cd492e0421418a12393efb2b5cc8e17565a1dca Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 31 Mar 2015 10:46:25 +0200 Subject: [PATCH 008/169] Changed MCP working directory --- Makefile.am | 6 +++--- adc/ADC.cc | 1 + adc/ADC.h | 4 ++++ adc/MCP3424.cc | 11 +++++++++++ adc/MCP3424.h | 24 ++++++++++++++++++++++++ mcp3424/MCP3424.cc | 1 - mcp3424/MCP3424.h | 4 ---- testing/bandit | 2 +- 8 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 adc/ADC.cc create mode 100644 adc/ADC.h create mode 100644 adc/MCP3424.cc create mode 100644 adc/MCP3424.h delete mode 100644 mcp3424/MCP3424.cc delete mode 100644 mcp3424/MCP3424.h diff --git a/Makefile.am b/Makefile.am index 1b57569..f721f09 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,11 @@ bin_PROGRAMS = openstratos -openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc mcp3424/MCP3424.cc +openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc adc/MCP3424.cc adc/ADC.cc openstratos_LDADD = -lwiringPi openstratos_CPPFLAGS = -std=c++11 -Wno-unused-result EXTRA_PROGRAMS = openstratosRoot utesting -openstratosRoot_SOURCES = openstratos-root.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc mcp3424/MCP3424.cc +openstratosRoot_SOURCES = openstratos-root.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc adc/MCP3424.cc adc/ADC.cc openstratosRoot_CPPFLAGS = -std=c++11 -Wno-unused-result -utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc mcp3424/MCP3424.cc +utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc adc/MCP3424.cc adc/ADC.cc utesting_CPPFLAGS = -std=c++11 -Itesting/bandit -Wno-unused-result -DOS_TESTING diff --git a/adc/ADC.cc b/adc/ADC.cc new file mode 100644 index 0000000..bc03559 --- /dev/null +++ b/adc/ADC.cc @@ -0,0 +1 @@ +#include "adc/ADC.h" \ No newline at end of file diff --git a/adc/ADC.h b/adc/ADC.h new file mode 100644 index 0000000..d330504 --- /dev/null +++ b/adc/ADC.h @@ -0,0 +1,4 @@ +#ifndef ADC_ADC_H_ +#define ADC_ADC_H_ + +#endif \ No newline at end of file diff --git a/adc/MCP3424.cc b/adc/MCP3424.cc new file mode 100644 index 0000000..393b7a5 --- /dev/null +++ b/adc/MCP3424.cc @@ -0,0 +1,11 @@ +#include "adc/MCP3424.h" +#include + +using namespace os; + +MCP3424::MCP3424(int i2c_address, int gain, int res) +{ + this->gain = gain; + this->res = res; + this->fd = wiringPiI2CSetup(i2c_address); +} diff --git a/adc/MCP3424.h b/adc/MCP3424.h new file mode 100644 index 0000000..e75ba01 --- /dev/null +++ b/adc/MCP3424.h @@ -0,0 +1,24 @@ +#ifndef ADC_MCP3424_H_ +#define ADC_MCP3424_H_ + +namespace os { + + class MCP3424 + { + private: + int fd; + int gain; + int res; + + inline int get_divisor() {return 1 << (this->gain + 2*this->res);} + + public: + MCP3424(int i2c_address, int gain, int res); + MCP3424(MCP3424& copy) = delete; + ~MCP3424() = default; + + double read_channel(int channel); + }; +} + +#endif // ADC_MCP3424_H_ diff --git a/mcp3424/MCP3424.cc b/mcp3424/MCP3424.cc deleted file mode 100644 index ed3af8b..0000000 --- a/mcp3424/MCP3424.cc +++ /dev/null @@ -1 +0,0 @@ -#include "mcp3424/MCP3424.h" diff --git a/mcp3424/MCP3424.h b/mcp3424/MCP3424.h deleted file mode 100644 index 835a9e2..0000000 --- a/mcp3424/MCP3424.h +++ /dev/null @@ -1,4 +0,0 @@ -#ifndef MCP3424_MCP3424_H_ -#define MCP3424_MCP3424_H_ - -#endif // MCP3424_MCP3424_H_ diff --git a/testing/bandit b/testing/bandit index cd1e581..dbcfc1a 160000 --- a/testing/bandit +++ b/testing/bandit @@ -1 +1 @@ -Subproject commit cd1e5816bb817a5e7e1d1a03a02f0f7a68a101c8 +Subproject commit dbcfc1a59319ea7733d6f393b99807a0903b6fbe From cf9636f2da9cd8b1ada6781bdf8612c549b1d7e8 Mon Sep 17 00:00:00 2001 From: cruzeneko Date: Tue, 31 Mar 2015 13:56:06 +0000 Subject: [PATCH 009/169] Modified SMS termination string. Changed \r\n to \x1a\r\n to meet SIM800L AT command spec. --- gsm/GSMDevice.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsm/GSMDevice.cpp b/gsm/GSMDevice.cpp index f33b375..19f3a2c 100644 --- a/gsm/GSMDevice.cpp +++ b/gsm/GSMDevice.cpp @@ -83,7 +83,7 @@ bool GSMDevice::SendSMS(string message, string n){ //Sends a short message to } serialPrintf(fdesc,messagechar); //Send message - serialPrintf(fdesc,"\r\n"); //Return + serialPrintf(fdesc,"\x1a\r\n"); //SUB control character (ascii 0x1a)+Return FlushSerialInput(); //Module will reply with "+CMGS". Not interested in that, so flush. return true; //Message sent. } From b6cbdba36460e468b32f56caca3a23c406852b50 Mon Sep 17 00:00:00 2001 From: cruzeneko Date: Tue, 31 Mar 2015 14:41:15 +0000 Subject: [PATCH 010/169] Implemented geolocation and GPRS connections. Not tested yet. Signed-off-by: cruzeneko --- constants.h | 1 + gsm/GSMDevice.cpp | 22 +++++++++++++++++++++- gsm/GSMDevice.hpp | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/constants.h b/constants.h index 9aaaef1..7b7cd5b 100644 --- a/constants.h +++ b/constants.h @@ -14,4 +14,5 @@ #define BAT_R1 3300 #define BAT_R2 4700 + #define APNNAME "gprs-service.com" #endif // CONSTANTS_H_ diff --git a/gsm/GSMDevice.cpp b/gsm/GSMDevice.cpp index 19f3a2c..ac15586 100644 --- a/gsm/GSMDevice.cpp +++ b/gsm/GSMDevice.cpp @@ -89,7 +89,27 @@ bool GSMDevice::SendSMS(string message, string n){ //Sends a short message to } void GSMDevice::BroadcastGeolocation(string n){ //Tries to perform geolocation and sends coordinates to a phone number via SMS. - //TODO + initGPRS(); + uint16_t responseLength = SerialSendRead("AT+CIPGSMLOC=1,1"); + serialin[responseLength+1] = (char)0x0; + SendSMS(serialin, "699686404"); + tearDownGPRS(); +} + +void GSMDevice::InitGPRS(){ + SerialSendCompareResponse("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK"); //About to turn on GPRS + string preamble = "AT+SAPBR=3,1,\"APN\",\""; + string end = ";"; + string command = preamble + APNNAME + end; + char *send = new char[command.length() + 1]; + strcpy(send, command.c_str()); + SerialSendCompareResponse(send, "OK"); //Set APN provided. + SerialSendCompareResponse("AT+SAPBR=1,1","OK"); //Activate GPRS context + /*SerialSendCompareResponse("AT+SAPBR=2,1","OK");*/ //Not realy necessary +} + +void GSMDevice::TearDownGPRS(){ + SerialSendCompareResponse("AT+SAPBR=0,1","OK"); } bool GSMDevice::CheckGSMModule(){ //Returns true if module is up and running, false if it is not. diff --git a/gsm/GSMDevice.hpp b/gsm/GSMDevice.hpp index de80a02..2eba881 100644 --- a/gsm/GSMDevice.hpp +++ b/gsm/GSMDevice.hpp @@ -43,6 +43,8 @@ class GSMDevice{ bool SerialSendCompareResponse(char*, char*); //Sends a string of data via serial port. Checks that the reply matches with another string. bool InitGSMModule(); //Initializes the gsm module. Returns true if successful. False if failed. bool InitSerial(); //Initializes the serial interface. Returns true if successful. False if failed. + void InitGPRS(); + void TearDownGPRS(); int gpionum; //GPIO pin used for software power control string serialPort; //Serial port identifier. Tipically /dev/ttyAMA0 in Raspbian. int fdesc; //Standard unix file descriptor associated with the serial port (see serialPort) From 7d0c4b1a349a1e5b7aa7b6773ce44036a02ab02c Mon Sep 17 00:00:00 2001 From: cruzeneko Date: Tue, 31 Mar 2015 15:14:50 +0000 Subject: [PATCH 011/169] Improved software power control. --- gsm/GSMDevice.cpp | 43 +++++++++++++++++++++++++++++++++---------- gsm/GSMDevice.hpp | 8 ++++++-- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/gsm/GSMDevice.cpp b/gsm/GSMDevice.cpp index ac15586..e8d451d 100644 --- a/gsm/GSMDevice.cpp +++ b/gsm/GSMDevice.cpp @@ -3,25 +3,47 @@ using namespace std; GSMDevice::GSMDevice(){ //Instantiates a GSM device controlled using GPIO 4 (default, software pwr control) and /dev/ttyAMA0 for UART - GSMDevice(DEFAULT_GPIO,DEFAULT_UART); + GSMDevice(DEFAULT_GPIO,5,DEFAULT_UART); } //WARNING: May take up to six seconds -GSMDevice::GSMDevice(int gpio, string serial){ //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial){ - gpionum = gpio; - serialPort = serial; +GSMDevice::GSMDevice(int pwrgpio, int statusgpio, string serial){ //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial){ + this->statusgpio = statusgpio; + this->pwrgpio = pwrgpio; + this->serialPort = serial; InitSerial(); InitGSMModule(); delay(3000); //Allow some time for the GSM module to connect to the network. } +//Returns 0 for LOW, 1 for HIGH. +uint16_t GSMDevice::CheckModuleStatus(){ + return digitalRead(this->statusgpio); +} + + +//Turns the module on. +void GSMDevice::TurnOn(){ + if(!CheckModuleStatus()){ + TogglePWR(); + } +} + +//Turns the module off. +void GSMDevice::TurnOff(){ + if(CheckModuleStatus()){ + TogglePWR(); + } +} + + void GSMDevice::TogglePWR(){ //Toggles the power status of the GSM module. Turns it on if it is off and turns it off if it is on. //WARNING: Takes 2500 miliseconds to complete - digitalWrite(gpionum, LOW); //Spec says that the adafruit FONA expects a 2000ms low pulse + digitalWrite(this->pwrgpio, LOW); //Spec says that the adafruit FONA expects a 2000ms low pulse delay(2000); - digitalWrite(gpionum, HIGH); + digitalWrite(this->pwrgpio, HIGH); delay(500); //Give the module some time to turn on, ensure that when //function returns the module is operational. } @@ -120,8 +142,8 @@ bool GSMDevice::CheckGSMModule(){ //Returns true if module is up and runnin } bool GSMDevice::InitSerial(){ - char *cstr = new char[serialPort.length() + 1]; - strcpy(cstr, serialPort.c_str()); + char *cstr = new char[this->serialPort.length() + 1]; + strcpy(cstr, this->serialPort.c_str()); fdesc = serialOpen(cstr, UART_BAUDRATE); if(fdesc==-1){ //serialOpen returns a standard linux file descriptor. -1 means failed ;/*EXCEPTION: NO SERIAL PORT AVAILABLE*/ @@ -138,8 +160,9 @@ bool GSMDevice::InitGSMModule(){ /*EXCEPTION: UNABLE TO ACCESS GPIOS*/; return false; } - pinMode(gpionum, OUTPUT); //Set GPIO as digital output - digitalWrite(gpionum, HIGH); //Set to high so that GSM module stays in standby until TogglePWR is called + pinMode(this->pwrgpio, OUTPUT); //Set GPIO as digital output + digitalWrite(this->pwrgpio, HIGH); //Set to high so that GSM module stays in standby until TogglePWR is called + pinMode(this->pwrgpio, INPUT); return true; } diff --git a/gsm/GSMDevice.hpp b/gsm/GSMDevice.hpp index 2eba881..f1a2607 100644 --- a/gsm/GSMDevice.hpp +++ b/gsm/GSMDevice.hpp @@ -29,7 +29,7 @@ using namespace std; class GSMDevice{ public: GSMDevice(); //Instantiates a GSM device controlled using GPIO 4 (default, software pwr control) and /dev/ttyAMA0 for UART - GSMDevice(int gpio, string serial); //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial); + GSMDevice(int pwrgpio, int statusgpio, string serial); //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial); void TogglePWR(); //Toggles the power status of the GSM module. Turns it on if it is off and turns it off if it is on. bool Call(string number); //Calls a given phone number. Returns true if suceeded, false if failed. bool AbortCall(); //Aborts a phone call. Returns true if suceeded, false if failed or not in a call. @@ -37,6 +37,9 @@ class GSMDevice{ void BroadcastGeolocation(string n); //Tries to perform geolocation and sends coordinates to a phone number via SMS. bool CheckGSMModule(); //Returns true if module is up and running, false if it is not private: + uint16_t CheckModuleStatus(); + void TurnOn(); + void TurnOff(); uint16_t SerialReadLine(); uint16_t SerialSendRead(char *); void FlushSerialInput(); //Discards all data received from the serial port. @@ -45,7 +48,8 @@ class GSMDevice{ bool InitSerial(); //Initializes the serial interface. Returns true if successful. False if failed. void InitGPRS(); void TearDownGPRS(); - int gpionum; //GPIO pin used for software power control + int pwrgpio; + int statusgpio; //GPIO pin used for software power control string serialPort; //Serial port identifier. Tipically /dev/ttyAMA0 in Raspbian. int fdesc; //Standard unix file descriptor associated with the serial port (see serialPort) char serialin[255]; //Buffer on which data received via the serial port is placed From f33e91ac05c74eded4804ea0f35ae990772423db Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 15 Apr 2015 16:28:34 +0200 Subject: [PATCH 012/169] Updated to C++14 --- Makefile.am | 6 +++--- battery/Battery.cc | 3 +-- serial/Serial.cc | 4 ++-- temperature/Temperature.cc | 3 +-- testing/battery_test.cc | 2 +- testing/camera_test.cc | 4 ++-- testing/temperature_test.cc | 2 +- testing/testing.cc | 1 - 8 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Makefile.am b/Makefile.am index 617a2f8..5574159 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,11 @@ bin_PROGRAMS = openstratos openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc openstratos_LDADD = -lwiringPi -openstratos_CPPFLAGS = -std=c++11 -Wno-unused-result +openstratos_CPPFLAGS = -std=c++14 -Wno-unused-result EXTRA_PROGRAMS = openstratosRoot utesting openstratosRoot_SOURCES = openstratos-root.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc -openstratosRoot_CPPFLAGS = -std=c++11 -Wno-unused-result +openstratosRoot_CPPFLAGS = -std=c++14 -Wno-unused-result utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc -utesting_CPPFLAGS = -std=c++11 -Itesting/bandit -Wno-unused-result -DOS_TESTING +utesting_CPPFLAGS = -std=c++14 -Itesting/bandit -Wno-unused-result -DOS_TESTING diff --git a/battery/Battery.cc b/battery/Battery.cc index 37748cd..05c63c8 100644 --- a/battery/Battery.cc +++ b/battery/Battery.cc @@ -2,7 +2,6 @@ #include #include -#include #include @@ -67,7 +66,7 @@ void Battery::read_battery() this->battery = volt_to_percent(voltage5*(BAT_R1+BAT_R2)/BAT_R2); - this_thread::sleep_for(chrono::milliseconds(50)); + this_thread::sleep_for(50ms); } this->stopped = true; } diff --git a/serial/Serial.cc b/serial/Serial.cc index d3dc457..6e05fba 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -59,13 +59,13 @@ void Serial::serial_thread() frame = ""; endl_pos = 0; - this_thread::sleep_for(chrono::milliseconds(50)); + this_thread::sleep_for(50ms); } } } else if (available == 0) { - this_thread::sleep_for(chrono::milliseconds(25)); + this_thread::sleep_for(25ms); } else if (available < 0) { diff --git a/temperature/Temperature.cc b/temperature/Temperature.cc index 310c312..78c702f 100644 --- a/temperature/Temperature.cc +++ b/temperature/Temperature.cc @@ -2,7 +2,6 @@ #include #include -#include #include @@ -66,7 +65,7 @@ void Temperature::read_temperature() float voltage = value * 5 / 32768; // 2^15 this->temperature = r_to_c(TEMP_R * (TEMP_VIN / voltage - 1)); - this_thread::sleep_for(chrono::milliseconds(50)); + this_thread::sleep_for(50ms); } this->stopped = true; } diff --git a/testing/battery_test.cc b/testing/battery_test.cc index a06a9f7..8832aff 100644 --- a/testing/battery_test.cc +++ b/testing/battery_test.cc @@ -11,7 +11,7 @@ describe("Battery", [](){ Battery bat(80); bat.start_reading(); - this_thread::sleep_for(chrono::milliseconds(75)); + this_thread::sleep_for(75ms); AssertThat(bat.get_battery(), Is().EqualToWithDelta(50, 0.05)); bat.stop_reading(); diff --git a/testing/camera_test.cc b/testing/camera_test.cc index 81f7540..e03b606 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -4,7 +4,7 @@ describe("Camera", [](){ Camera::get_instance().record(200); AssertThat(Camera::get_instance().is_recording(), Equals(true)); - this_thread::sleep_for(chrono::milliseconds(250)); + this_thread::sleep_for(250ms); AssertThat(Camera::get_instance().is_recording(), Equals(false)); }); @@ -12,7 +12,7 @@ describe("Camera", [](){ Camera::get_instance().record(); AssertThat(Camera::get_instance().is_recording(), Equals(true)); - this_thread::sleep_for(chrono::milliseconds(200)); + this_thread::sleep_for(200ms); Camera::get_instance().stop(); AssertThat(Camera::get_instance().is_recording(), Equals(false)); }); diff --git a/testing/temperature_test.cc b/testing/temperature_test.cc index 81b9028..2a38a37 100644 --- a/testing/temperature_test.cc +++ b/testing/temperature_test.cc @@ -5,7 +5,7 @@ describe("Temperature", [&](){ temp.start_reading(); AssertThat(temp.is_reading(), Equals(true)); - this_thread::sleep_for(chrono::milliseconds(100)); + this_thread::sleep_for(100ms); temp.stop_reading(); AssertThat(temp.is_reading(), Equals(false)); diff --git a/testing/testing.cc b/testing/testing.cc index 36dcfa0..9c03a48 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -1,5 +1,4 @@ #include -#include #include From 74be9496ab993ed5bab6bd37888aa4907801de5f Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 12:10:02 +0200 Subject: [PATCH 013/169] Added logger and started logic --- .gitignore | 3 +- Makefile.am | 2 +- gps/GPS.cc | 40 +++++++++++++-- gps/GPS.h | 5 +- logger/Logger.cc | 32 ++++++++++++ logger/Logger.h | 26 ++++++++++ openstratos.cc | 130 +++++++++++++++++++++++++++++++++++++++++++++-- openstratos.h | 19 +++++-- serial/Serial.cc | 26 +++++++--- serial/Serial.h | 3 +- 10 files changed, 267 insertions(+), 19 deletions(-) create mode 100644 logger/Logger.cc create mode 100644 logger/Logger.h diff --git a/.gitignore b/.gitignore index b651be9..4482287 100644 --- a/.gitignore +++ b/.gitignore @@ -30,6 +30,7 @@ openstratos openstratosRoot utesting Makefile +data # http://www.gnu.org/software/automake @@ -51,4 +52,4 @@ Makefile # Eclipse files .project -.cproject \ No newline at end of file +.cproject diff --git a/Makefile.am b/Makefile.am index 5574159..8932edd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = openstratos -openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc +openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc logger/Logger.cc openstratos_LDADD = -lwiringPi openstratos_CPPFLAGS = -std=c++14 -Wno-unused-result diff --git a/gps/GPS.cc b/gps/GPS.cc index 2180789..f0e399d 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -5,8 +5,11 @@ #include #include +#include + #include "constants.h" #include "serial/Serial.h" +#include "logger/Logger.h" using namespace std; @@ -20,12 +23,42 @@ GPS& GPS::get_instance() GPS::~GPS() { - this->serial.close(); + if (this->serial.is_open()) + { + this->logger->log("Closing serial interface..."); + this->serial.close(); + this->logger->log("Serial interface closed."); + + this->logger->log("Deallocating frame logger..."); + delete this->frame_logger; + } + this->logger->log("Shutting down..."); + // TODO shut down GPS + this->logger->log("Shut down finished."); + delete this->logger; } -void GPS::initialize(const string& serial_URL) +bool GPS::initialize(const string& serial_URL) { - this->serial.initialize(serial_URL, 9600, "\r\n", bind(&GPS::parse, this, placeholders::_1)); + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + this->logger = new Logger("data/logs/gps/GPS."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "GPS"); + + this->logger->log("Starting serial connection..."); + if ( ! this->serial.initialize(serial_URL, 9600, "\r\n", bind(&GPS::parse, this, placeholders::_1))) { + this->logger->log("GPS serial error."); + return false; + } else { + this->logger->log("Serial connection started."); + this->frame_logger = new Logger("data/logs/GPSFrames."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPS Frame"); + return true; + } #ifndef OS_TESTING this->serial.send_frame("$PMTK220,100*2F"); @@ -35,6 +68,7 @@ void GPS::initialize(const string& serial_URL) uint_fast8_t GPS::parse(const string& frame) { + this->frame_logger->log(frame); string frame_type = frame.substr(1, frame.find_first_of(',')-1); if (frame_type == "GPGGA") diff --git a/gps/GPS.h b/gps/GPS.h index 5e44fea..a8d2bc7 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -6,6 +6,7 @@ #include #include "serial/Serial.h" +#include "logger/Logger.h" using namespace std; @@ -21,6 +22,8 @@ namespace os { { private: Serial serial; + Logger* logger; + Logger* frame_logger; tm time; bool active; @@ -53,7 +56,7 @@ namespace os { float get_VDOP() {return this->vdop;} euc_vec* get_velocity() {return &this->velocity;} - void initialize(const string& serial_URL); + bool initialize(const string& serial_URL); uint_fast8_t parse(const string& frame); }; } diff --git a/logger/Logger.cc b/logger/Logger.cc new file mode 100644 index 0000000..64460f6 --- /dev/null +++ b/logger/Logger.cc @@ -0,0 +1,32 @@ +#include "logger/Logger.h" + +#include +#include + +#include + +using namespace std; +using namespace os; + +Logger::Logger(const string& path, const string& prefix) +{ + this->log_stream.open(path); + this->log_prefix = prefix; + this->log("Logging started"); +} + +Logger::~Logger() +{ + this->log_stream.close(); +} + +void Logger::log(const string& message) +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + this->log_stream << "[" << log_prefix << "] - " << now->tm_mon << "/" << now->tm_mday << "/" << (now->tm_year+1900) + << " " << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec << "." << timer.tv_usec << " " + << message << endl; +} diff --git a/logger/Logger.h b/logger/Logger.h new file mode 100644 index 0000000..0c56b9d --- /dev/null +++ b/logger/Logger.h @@ -0,0 +1,26 @@ +#ifndef LOGGER_LOGGER_H_ +#define LOGGER_LOGGER_H_ + +#include +#include + +using namespace std; + +namespace os { + + class Logger + { + private: + ofstream log_stream; + string log_prefix; + public: + Logger() = delete; + Logger(Logger& copy) = delete; + ~Logger(); + + Logger(const string& path, const string& prefix); + void log(const string& message); + }; +} + +#endif // LOGGER_LOGGER_H_ diff --git a/openstratos.cc b/openstratos.cc index 0e6c886..3463929 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -2,7 +2,131 @@ int main(void) { - cout << "[OpenStratos] Starting" << endl; - cout << "[OpenStratos] Starting checks (not really)" << endl; + cout << "[OpenStratos] Starting..." << endl; // Only if verbose + + struct timeval timer; + struct timezone tz; + + gettimeofday(&timer, &tz); + + struct tm * now = gmtime(&timer.tv_sec); + + cout << "[OpenStratos] Current time: " << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec << + " UTC of " << now->tm_mon << "/" << now->tm_mday << "/" << (now->tm_year+1900) << endl; // Only if verbose + + if ( ! file_exists("data")) + { + cout << "[OpenStratos] No data directory, creating..." << endl; + if (mkdir("data", 0755) == 0) + { + cout << "[OpenStratos] Data directory created." << endl; + } + else + { + cout << "[OpenStratos] Error creating data directory." << endl; + exit(1); + } + } + + if ( ! file_exists("data/logs")) + { + cout << "[OpenStratos] No log directory, creating..." << endl; + if (mkdir("data/logs", 0755) == 0 && mkdir("data/logs/main", 0755) == 0 && + mkdir("data/logs/camera", 0755) == 0 && mkdir("data/logs/gps", 0755) == 0) + { + cout << "[OpenStratos] Log directory created." << endl; + } + else + { + cout << "[OpenStratos] Error creating log directory." << endl; + exit(1); + } + } + + cout << "[OpenStratos] Starting logger..." << endl; // Only if verbose + + Logger logger("data/logs/main/OpenStratos."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "OpenStratos"); + cout << "[OpenStratos] Logger started." << endl; // Only if verbose + + if (file_exists("data/video")) + { + logger.log("Video directory exists."); + } + else + { + logger.log("No video directory, creating..."); + if (mkdir("data/video", 0755) == 0) + { + logger.log("Video directory created."); + } + else + { + logger.log("Error creating video directory."); + cout << "[OpenStratos] Error creating video directory." << endl; + exit(1); + } + } + + logger.log("Available disk space: " + to_string(get_available_disk_space()/1073741824) + " GiB"); + if (get_available_disk_space() < 21705523200) // Enough for about 3 hours of video + { + logger.log("Error: Not enough disk space."); + cout << "[OpenStratos] Error: Not enough disk space." << endl; + exit(1); + } + + // 115 MiB per minute +/- + logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7235174400) + + " hours of fullHD video."); + + logger.log("Turning on GPS..."); + if ( ! GPS::get_instance().initialize("")) + { + logger.log("GPS initialization error."); + exit(1); + } + logger.log("GPS On."); + + logger.log("Starting GPS Thread..."); + thread gps_thread(gps_thread_fn); + logger.log("GPS thread started."); + + + + logger.log("Joining threads..."); + gps_thread.join(); + logger.log("Finishing execution."); return 0; -} \ No newline at end of file +} + +inline bool file_exists(const string& name) +{ + struct stat buffer; + return (stat (name.c_str(), &buffer) == 0); +} + +inline float get_available_disk_space() +{ + struct statvfs fs; + statvfs("data", &fs); + + return fs.f_bsize*fs.f_bavail; +} + +void gps_thread_fn() +{ + while ( ! GPS::get_instance().is_active()) + { + this_thread::sleep_for(1s); + } + this_thread::sleep_for(2s); + + struct timezone tz = {0, 0}; + struct timeval tv = {timegm(GPS::get_instance().get_time()), 0}; + + settimeofday(&tv, &tz); + + // TODO +} diff --git a/openstratos.h b/openstratos.h index edbd55e..41af738 100644 --- a/openstratos.h +++ b/openstratos.h @@ -1,10 +1,23 @@ #ifndef OPENSTRATOS_H_ #define OPENSTRATOS_H_ -#include "config.hpp" - #include +#include +#include + +#include +#include +#include + +#include "config.h" +#include "logger/Logger.h" +#include "gps/GPS.h" using namespace std; +using namespace os; + +inline bool file_exists(const string& name); +inline float get_available_disk_space(); +void gps_thread_fn(); -#endif // OPENSTRATOS_H_ \ No newline at end of file +#endif // OPENSTRATOS_H_ diff --git a/serial/Serial.cc b/serial/Serial.cc index 6e05fba..aec4741 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -13,7 +13,7 @@ using namespace std; using namespace os; -void Serial::initialize(const string& url, int baud, const string endl, function) +bool Serial::initialize(const string& url, int baud, const string endl, function) { this->listener = listener; this->endl = endl; @@ -21,10 +21,17 @@ void Serial::initialize(const string& url, int baud, const string endl, function this->fd = serialOpen(url.c_str(), baud); #endif + if (this->fd == -1) { + this->open = false; + this->stopped = true; + return false; + } + this->open = true; this->stopped = false; thread t(&Serial::serial_thread, this); t.detach(); + return true; } Serial::~Serial() @@ -91,12 +98,19 @@ uint_fast8_t Serial::send_frame(string frame) void Serial::close() { - this->open = false; - while( ! this->stopped); + if (this->open) { + this->open = false; + while( ! this->stopped); - #ifndef OS_TESTING - serialClose(this->fd); - #endif + #ifndef OS_TESTING + serialClose(this->fd); + #endif + } +} + +bool Serial::is_open() +{ + return this->open; } bool Serial::is_valid(string frame) diff --git a/serial/Serial.h b/serial/Serial.h index bd8fc73..e64e4f0 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -27,7 +27,8 @@ namespace os { uint_fast8_t send_frame(string frame); void close(); bool is_valid(string frame); - void initialize(const string& serial_URL, int baud, const string endl, function); + bool is_open(); + bool initialize(const string& serial_URL, int baud, const string endl, function); }; } From 251ed7a4247620b1c703cdf37191e62ffdab6fbd Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:08:12 +0200 Subject: [PATCH 014/169] Added camera initialization --- Makefile.am | 7 ++----- camera/Camera.cc | 31 +++++++++++++++++++++++++++++- camera/Camera.h | 6 ++++++ config.h | 2 ++ logger/Logger.cc | 10 ++++++---- openstratos.cc | 50 ++++++++++++++++++++++++++++++++++++++++-------- openstratos.h | 5 +++++ testing/bandit | 2 +- 8 files changed, 94 insertions(+), 19 deletions(-) diff --git a/Makefile.am b/Makefile.am index 8932edd..20f199d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,9 +3,6 @@ openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.c openstratos_LDADD = -lwiringPi openstratos_CPPFLAGS = -std=c++14 -Wno-unused-result -EXTRA_PROGRAMS = openstratosRoot utesting -openstratosRoot_SOURCES = openstratos-root.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc -openstratosRoot_CPPFLAGS = -std=c++14 -Wno-unused-result - -utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc +EXTRA_PROGRAMS = utesting +utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc logger/Logger.cc utesting_CPPFLAGS = -std=c++14 -Itesting/bandit -Wno-unused-result -DOS_TESTING diff --git a/camera/Camera.cc b/camera/Camera.cc index c4b5810..1c4dfd7 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -1,11 +1,15 @@ #include "camera/Camera.h" #include +#include #include #include #include +#include +#include + using namespace os; using namespace std; @@ -30,7 +34,16 @@ void Camera::record(int time) { if ( ! this->recording) { - string command = "raspivid -o os_video.h264 -t " + to_string(time) + " &"; + string command; + if (time > 0) + { + command = "raspivid -o data/video/test.h264 -t " + to_string(time) + " &"; + } + else + { + command = "raspivid -o data/video/video-"+ to_string(get_file_count("data/video/")) + +".h264 -t " + to_string(time) + " &"; + } #ifndef RASPIVID command = ""; #endif @@ -56,3 +69,19 @@ void Camera::stop() system("pkill raspivid"); this->recording = false; } + +int os::get_file_count(const string& path) +{ + DIR *dp; + int i = 0; + struct dirent *ep; + dp = opendir(path.c_str()); + + while (ep = readdir(dp)) + { + i++; + } + (void) closedir(dp); + + return i-2; +} diff --git a/camera/Camera.h b/camera/Camera.h index 1619de6..de6b350 100644 --- a/camera/Camera.h +++ b/camera/Camera.h @@ -1,6 +1,10 @@ #ifndef CAMERA_CAMERA_H_ #define CAMERA_CAMERA_H_ +#include + +using namespace std; + namespace os { class Camera @@ -20,6 +24,8 @@ namespace os { void stop(); bool is_recording() const {return this->recording;} }; + + int get_file_count(const string& path); } #endif // CAMERA_CAMERA_H_ diff --git a/config.h b/config.h index 308566b..bfb307e 100644 --- a/config.h +++ b/config.h @@ -84,3 +84,5 @@ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ + +#define RASPIVID 0 diff --git a/logger/Logger.cc b/logger/Logger.cc index 64460f6..bc17e3d 100644 --- a/logger/Logger.cc +++ b/logger/Logger.cc @@ -2,6 +2,7 @@ #include #include +#include #include @@ -12,7 +13,7 @@ Logger::Logger(const string& path, const string& prefix) { this->log_stream.open(path); this->log_prefix = prefix; - this->log("Logging started"); + this->log("Logging started."); } Logger::~Logger() @@ -26,7 +27,8 @@ void Logger::log(const string& message) gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); - this->log_stream << "[" << log_prefix << "] - " << now->tm_mon << "/" << now->tm_mday << "/" << (now->tm_year+1900) - << " " << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec << "." << timer.tv_usec << " " - << message << endl; + this->log_stream << "[" << log_prefix << "] - " << setfill('0') << setw(2) << now->tm_mon << "/" << + setfill('0') << setw(2) << now->tm_mday << "/" << (now->tm_year+1900) << " " << + setfill('0') << setw(2) << now->tm_hour << ":" << setfill('0') << setw(2) << now->tm_min << ":" << + setfill('0') << setw(2) << now->tm_sec << "." << timer.tv_usec << " - " << message << endl; } diff --git a/openstratos.cc b/openstratos.cc index 3463929..80cb258 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -81,22 +81,56 @@ int main(void) logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7235174400) + " hours of fullHD video."); - logger.log("Turning on GPS..."); - if ( ! GPS::get_instance().initialize("")) + // logger.log("Turning on GPS..."); + // if ( ! GPS::get_instance().initialize("")) + // { + // logger.log("GPS initialization error."); + // exit(1); + // } + // logger.log("GPS On."); + + // logger.log("Starting GPS Thread..."); + // thread gps_thread(gps_thread_fn); + // logger.log("GPS thread started."); + + logger.log("Starting camera recording..."); + if ( ! RASPIVID) { - logger.log("GPS initialization error."); + logger.log("Error: No raspivid found. Is this a Raspberry?"); exit(1); } - logger.log("GPS On."); + logger.log("Recording 10 seconds as test..."); + Camera::get_instance().record(10000); + this_thread::sleep_for(11s); + Camera::get_instance().stop(); - logger.log("Starting GPS Thread..."); - thread gps_thread(gps_thread_fn); - logger.log("GPS thread started."); + if (file_exists("data/video/test.h264")) + { + logger.log("Camera test OK."); + logger.log("Removing test file..."); + if (remove("data/video/test.h264")) + { + logger.log("Error removing test file."); + } + else + { + logger.log("Test file removed."); + } + } + else + { + logger.log("Test recording error."); + exit(1); + } + logger.log("Starting video recording..."); + Camera::get_instance().record(); + logger.log("Stopping video..."); + Camera::get_instance().stop(); logger.log("Joining threads..."); - gps_thread.join(); + // gps_thread.join(); logger.log("Finishing execution."); return 0; } diff --git a/openstratos.h b/openstratos.h index 41af738..ab3c2f8 100644 --- a/openstratos.h +++ b/openstratos.h @@ -1,6 +1,10 @@ #ifndef OPENSTRATOS_H_ #define OPENSTRATOS_H_ +#ifndef RASPIVID +#define RASPIVID 0 +#endif + #include #include #include @@ -12,6 +16,7 @@ #include "config.h" #include "logger/Logger.h" #include "gps/GPS.h" +#include "camera/Camera.h" using namespace std; using namespace os; diff --git a/testing/bandit b/testing/bandit index dbcfc1a..b630327 160000 --- a/testing/bandit +++ b/testing/bandit @@ -1 +1 @@ -Subproject commit dbcfc1a59319ea7733d6f393b99807a0903b6fbe +Subproject commit b63032706618bd09dbc49b6ffe05d233fa8b0250 From 91f06dd596a115a306488c042f94f712ddaa5a72 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:22:51 +0200 Subject: [PATCH 015/169] Better build script --- .travis.yml | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b624c1..b64090f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,22 @@ language: cpp compiler: gcc +sudo: required + +addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - autoconf + - automake + - m4 + - gcc-4.9 + - g++-4.9 before_install: - git submodule update --init --recursive > /dev/null - - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - - sudo apt-get update -qq install: - - sudo apt-get install -qq autoconf automake m4 gcc-4.9 g++-4.9 > /dev/null - - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 90 - "bash -ex ./install-wiringpi.sh" script: @@ -27,7 +35,6 @@ notifications: recipients: - iban.eguia@opendeusto.es - jordan.aranda@me.com - - aritzbilbao@deusto.es - eneko.cruz@opendeusto.es on_success: change on_failure: always From 0aea04bd1ef565841f0de788b511d0a8283d7e98 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:30:40 +0200 Subject: [PATCH 016/169] Added g++4.9 flag --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index b64090f..b407dc6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ addons: before_install: - git submodule update --init --recursive > /dev/null + - export CXX="g++-4.9" install: - "bash -ex ./install-wiringpi.sh" From 58862640275af327bb0b6d6e1262ea04f938a4ea Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:36:24 +0200 Subject: [PATCH 017/169] Debugging segmentation fault --- testing/testing.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/testing/testing.cc b/testing/testing.cc index 9c03a48..1b5c80e 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -1,4 +1,5 @@ #include +#include #include @@ -19,11 +20,21 @@ int main(int argc, char* argv[]) } go_bandit([](){ - + cout << "Starting core tests" << endl; #include "core_test.cc" + + cout << "Starting camera tests" << endl; #include "camera_test.cc" + + cout << "Starting serial tests" << endl; #include "serial_test.cc" + + cout << "Starting GPS tests" << endl; #include "gps_test.cc" + + cout << "Starting temperature tests" << endl; #include "temperature_test.cc" + + cout << "Starting battery tests" << endl; #include "battery_test.cc" }); From 8ca30c36ea084a87135744dca26981bce4109fea Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:41:59 +0200 Subject: [PATCH 018/169] Continue debugging --- testing/camera_test.cc | 3 +++ testing/core_test.cc | 3 --- testing/testing.cc | 3 --- 3 files changed, 3 insertions(+), 6 deletions(-) delete mode 100644 testing/core_test.cc diff --git a/testing/camera_test.cc b/testing/camera_test.cc index e03b606..beef6f1 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -1,9 +1,12 @@ describe("Camera", [](){ it("recording test", [&](){ + cout << "Start recording" << endl; Camera::get_instance().record(200); AssertThat(Camera::get_instance().is_recording(), Equals(true)); + cout << "Finish recording..." << endl; + this_thread::sleep_for(250ms); AssertThat(Camera::get_instance().is_recording(), Equals(false)); }); diff --git a/testing/core_test.cc b/testing/core_test.cc deleted file mode 100644 index e9d712d..0000000 --- a/testing/core_test.cc +++ /dev/null @@ -1,3 +0,0 @@ -describe("Core test", [](){ - -}); diff --git a/testing/testing.cc b/testing/testing.cc index 1b5c80e..5ff9a85 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -20,9 +20,6 @@ int main(int argc, char* argv[]) } go_bandit([](){ - cout << "Starting core tests" << endl; - #include "core_test.cc" - cout << "Starting camera tests" << endl; #include "camera_test.cc" From 80adf7a2bf70adac823e87cf4d8dca8cb8bc0ba0 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:45:09 +0200 Subject: [PATCH 019/169] Continue debugging... It works perfectly in my system though. --- testing/camera_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/camera_test.cc b/testing/camera_test.cc index beef6f1..da31a01 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -9,6 +9,8 @@ describe("Camera", [](){ this_thread::sleep_for(250ms); AssertThat(Camera::get_instance().is_recording(), Equals(false)); + + cout << "checked first test." << endl; }); it("recording and stopping test", [&](){ From ce9fa76ca4a6be095e9fa8974616fe7cc7c7d33c Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:51:39 +0200 Subject: [PATCH 020/169] Possible cause found --- serial/Serial.cc | 15 ++++++++++----- testing/camera_test.cc | 7 ++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index aec4741..4a50f3a 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -15,22 +15,27 @@ using namespace os; bool Serial::initialize(const string& url, int baud, const string endl, function) { + cout << "Initializing serial..." << endl; this->listener = listener; this->endl = endl; #ifndef OS_TESTING this->fd = serialOpen(url.c_str(), baud); + + if (this->fd == -1) { + this->open = false; + this->stopped = true; + return false; + } #endif - if (this->fd == -1) { - this->open = false; - this->stopped = true; - return false; - } + cout << "Finishing initialization" << endl; this->open = true; this->stopped = false; thread t(&Serial::serial_thread, this); t.detach(); + + cout << "Serial initialized" << endl; return true; } diff --git a/testing/camera_test.cc b/testing/camera_test.cc index da31a01..80818ea 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -1,16 +1,11 @@ describe("Camera", [](){ it("recording test", [&](){ - cout << "Start recording" << endl; Camera::get_instance().record(200); AssertThat(Camera::get_instance().is_recording(), Equals(true)); - cout << "Finish recording..." << endl; - this_thread::sleep_for(250ms); AssertThat(Camera::get_instance().is_recording(), Equals(false)); - - cout << "checked first test." << endl; }); it("recording and stopping test", [&](){ @@ -20,5 +15,7 @@ describe("Camera", [](){ this_thread::sleep_for(200ms); Camera::get_instance().stop(); AssertThat(Camera::get_instance().is_recording(), Equals(false)); + + cout << "checked second test" << endl; }); }); From 36babbbb5641200c9ee4658862e4fa4bc487b029 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 13:55:46 +0200 Subject: [PATCH 021/169] Dammmnnnn no way this is happening --- testing/camera_test.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testing/camera_test.cc b/testing/camera_test.cc index 80818ea..8882009 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -9,8 +9,10 @@ describe("Camera", [](){ }); it("recording and stopping test", [&](){ + cout << "starting second test" << endl; Camera::get_instance().record(); AssertThat(Camera::get_instance().is_recording(), Equals(true)); + cout << "First check" << endl; this_thread::sleep_for(200ms); Camera::get_instance().stop(); From 65b06615ff3614c18a1b5a7d47ea3e49044d117d Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:00:07 +0200 Subject: [PATCH 022/169] Could it be this issue? --- openstratos.cc | 5 ++--- openstratos.h | 4 ---- testing/camera_test.cc | 1 + 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 80cb258..202181a 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -94,11 +94,10 @@ int main(void) // logger.log("GPS thread started."); logger.log("Starting camera recording..."); - if ( ! RASPIVID) - { + #ifndef RASPIVID logger.log("Error: No raspivid found. Is this a Raspberry?"); exit(1); - } + #endif logger.log("Recording 10 seconds as test..."); Camera::get_instance().record(10000); this_thread::sleep_for(11s); diff --git a/openstratos.h b/openstratos.h index ab3c2f8..669a5af 100644 --- a/openstratos.h +++ b/openstratos.h @@ -1,10 +1,6 @@ #ifndef OPENSTRATOS_H_ #define OPENSTRATOS_H_ -#ifndef RASPIVID -#define RASPIVID 0 -#endif - #include #include #include diff --git a/testing/camera_test.cc b/testing/camera_test.cc index 8882009..4bbe27f 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -11,6 +11,7 @@ describe("Camera", [](){ it("recording and stopping test", [&](){ cout << "starting second test" << endl; Camera::get_instance().record(); + cout << "should be recording..." << endl; AssertThat(Camera::get_instance().is_recording(), Equals(true)); cout << "First check" << endl; From cabffb3e08a283ab4517cb7d5865f97dfbc2a60e Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:11:47 +0200 Subject: [PATCH 023/169] OK, new attempt --- camera/Camera.cc | 4 ++++ config.h | 2 -- gps/GPS.cc | 4 ++-- openstratos.cc | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 1c4dfd7..a16666c 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -7,6 +7,8 @@ #include #include +#include + #include #include @@ -32,6 +34,8 @@ void Camera::record_thread(int time) void Camera::record(int time) { + cout << "record called" << endl; + cout << "is recording?: " << this->recording << endl; if ( ! this->recording) { string command; diff --git a/config.h b/config.h index bfb307e..308566b 100644 --- a/config.h +++ b/config.h @@ -84,5 +84,3 @@ /* Define to `unsigned int' if does not define. */ /* #undef size_t */ - -#define RASPIVID 0 diff --git a/gps/GPS.cc b/gps/GPS.cc index f0e399d..7f7bf4e 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -44,7 +44,7 @@ bool GPS::initialize(const string& serial_URL) gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); - this->logger = new Logger("data/logs/gps/GPS."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + this->logger = new Logger("data/logs/GPS/GPS."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPS"); @@ -54,7 +54,7 @@ bool GPS::initialize(const string& serial_URL) return false; } else { this->logger->log("Serial connection started."); - this->frame_logger = new Logger("data/logs/GPSFrames."+ to_string(now->tm_year+1900) +"-"+ + this->frame_logger = new Logger("data/logs/GPS/GPSFrames."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPS Frame"); return true; diff --git a/openstratos.cc b/openstratos.cc index 202181a..6f8ee45 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -32,7 +32,7 @@ int main(void) { cout << "[OpenStratos] No log directory, creating..." << endl; if (mkdir("data/logs", 0755) == 0 && mkdir("data/logs/main", 0755) == 0 && - mkdir("data/logs/camera", 0755) == 0 && mkdir("data/logs/gps", 0755) == 0) + mkdir("data/logs/camera", 0755) == 0 && mkdir("data/logs/GPS", 0755) == 0) { cout << "[OpenStratos] Log directory created." << endl; } From 57748bb155d565465925879b5bdada57df61bea0 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:17:30 +0200 Subject: [PATCH 024/169] More debugging --- camera/Camera.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/camera/Camera.cc b/camera/Camera.cc index a16666c..ce217c1 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -52,6 +52,8 @@ void Camera::record(int time) command = ""; #endif + cout << "Command: '" << command << "'" << endl; + system(command.c_str()); this->recording = true; From 999b1fead6d745ae022dcf7aeeef8e31e3aca4d8 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:22:19 +0200 Subject: [PATCH 025/169] Added more debugging messages. --- camera/Camera.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/camera/Camera.cc b/camera/Camera.cc index ce217c1..d995bfa 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -38,13 +38,16 @@ void Camera::record(int time) cout << "is recording?: " << this->recording << endl; if ( ! this->recording) { + cout << "Not recording, so creating command" << endl; string command; if (time > 0) { + cout << "Command with time." << endl; command = "raspivid -o data/video/test.h264 -t " + to_string(time) + " &"; } else { + cout << "Command without time." << endl; command = "raspivid -o data/video/video-"+ to_string(get_file_count("data/video/")) +".h264 -t " + to_string(time) + " &"; } From 024440be6201e7ca5592e4a121d29dbe30532ad3 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:25:34 +0200 Subject: [PATCH 026/169] Added more debugging messages, again. --- camera/Camera.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/camera/Camera.cc b/camera/Camera.cc index d995bfa..dcb6afa 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -50,6 +50,8 @@ void Camera::record(int time) cout << "Command without time." << endl; command = "raspivid -o data/video/video-"+ to_string(get_file_count("data/video/")) +".h264 -t " + to_string(time) + " &"; + cout << "Command created." << endl; + cout << "Command: '" << command << "'" << endl; } #ifndef RASPIVID command = ""; From bcfb59bf659c27e4781809df8d5bc68835982654 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:28:24 +0200 Subject: [PATCH 027/169] Created data directories in build script --- build.sh | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 91822e5..b7471b0 100755 --- a/build.sh +++ b/build.sh @@ -7,5 +7,12 @@ autoconf ./configure make utesting +mkdir data +mkdir data/logs +mkdir data/logs/GPS +mkdir data/logs/camera +mkdir data/logs/main +mkdir data/video + printf "\n\n----- Starting unit tests -----\n\n" -./utesting \ No newline at end of file +./utesting From 38ac61882f244b85f91f15305457b0a87d8747be Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:32:27 +0200 Subject: [PATCH 028/169] Removed debug information --- camera/Camera.cc | 11 ----------- testing/camera_test.cc | 5 ----- testing/testing.cc | 10 ---------- 3 files changed, 26 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index dcb6afa..1c4dfd7 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -7,8 +7,6 @@ #include #include -#include - #include #include @@ -34,31 +32,22 @@ void Camera::record_thread(int time) void Camera::record(int time) { - cout << "record called" << endl; - cout << "is recording?: " << this->recording << endl; if ( ! this->recording) { - cout << "Not recording, so creating command" << endl; string command; if (time > 0) { - cout << "Command with time." << endl; command = "raspivid -o data/video/test.h264 -t " + to_string(time) + " &"; } else { - cout << "Command without time." << endl; command = "raspivid -o data/video/video-"+ to_string(get_file_count("data/video/")) +".h264 -t " + to_string(time) + " &"; - cout << "Command created." << endl; - cout << "Command: '" << command << "'" << endl; } #ifndef RASPIVID command = ""; #endif - cout << "Command: '" << command << "'" << endl; - system(command.c_str()); this->recording = true; diff --git a/testing/camera_test.cc b/testing/camera_test.cc index 4bbe27f..e03b606 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -9,16 +9,11 @@ describe("Camera", [](){ }); it("recording and stopping test", [&](){ - cout << "starting second test" << endl; Camera::get_instance().record(); - cout << "should be recording..." << endl; AssertThat(Camera::get_instance().is_recording(), Equals(true)); - cout << "First check" << endl; this_thread::sleep_for(200ms); Camera::get_instance().stop(); AssertThat(Camera::get_instance().is_recording(), Equals(false)); - - cout << "checked second test" << endl; }); }); diff --git a/testing/testing.cc b/testing/testing.cc index 5ff9a85..6a7551e 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -1,5 +1,4 @@ #include -#include #include @@ -20,18 +19,9 @@ int main(int argc, char* argv[]) } go_bandit([](){ - cout << "Starting camera tests" << endl; #include "camera_test.cc" - - cout << "Starting serial tests" << endl; #include "serial_test.cc" - - cout << "Starting GPS tests" << endl; #include "gps_test.cc" - - cout << "Starting temperature tests" << endl; #include "temperature_test.cc" - - cout << "Starting battery tests" << endl; #include "battery_test.cc" }); From 14ec1df2a60d48e3c6e183938c8d671f8731031c Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 14:33:31 +0200 Subject: [PATCH 029/169] Removed more debug messages --- serial/Serial.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index 4a50f3a..20fb4de 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -6,7 +6,6 @@ #include #include #include -#include #include @@ -15,7 +14,6 @@ using namespace os; bool Serial::initialize(const string& url, int baud, const string endl, function) { - cout << "Initializing serial..." << endl; this->listener = listener; this->endl = endl; #ifndef OS_TESTING @@ -28,14 +26,11 @@ bool Serial::initialize(const string& url, int baud, const string endl, function } #endif - cout << "Finishing initialization" << endl; - this->open = true; this->stopped = false; thread t(&Serial::serial_thread, this); t.detach(); - cout << "Serial initialized" << endl; return true; } From 2e238eb73f235af347865918f2910cb16407d933 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 16 Jul 2015 23:01:15 +0200 Subject: [PATCH 030/169] Added first logic structure --- openstratos.cc | 97 +++++++++++++++++++++++++++++++++++++++----------- openstratos.h | 22 +++++++++--- 2 files changed, 94 insertions(+), 25 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 6f8ee45..03b6b5e 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -4,11 +4,10 @@ int main(void) { cout << "[OpenStratos] Starting..." << endl; // Only if verbose - struct timeval timer; - struct timezone tz; - - gettimeofday(&timer, &tz); + State state = INITIALIZING; + struct timeval timer; + gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); cout << "[OpenStratos] Current time: " << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec << @@ -89,9 +88,7 @@ int main(void) // } // logger.log("GPS On."); - // logger.log("Starting GPS Thread..."); - // thread gps_thread(gps_thread_fn); - // logger.log("GPS thread started."); + // TODO start GSM and send message logger.log("Starting camera recording..."); #ifndef RASPIVID @@ -125,6 +122,56 @@ int main(void) logger.log("Starting video recording..."); Camera::get_instance().record(); + state = ACQUIRING_FIX; + while ( ! GPS::get_instance().is_active()) + { + this_thread::sleep_for(1s); + } + logger.log("GPS fix acquired, waiting for date change."); + this_thread::sleep_for(2s); + + struct timezone tz = {0, 0}; + struct timeval tv = {timegm(GPS::get_instance().get_time()), 0}; + settimeofday(&tv, &tz); + + logger.log("System date change."); + + logger.log("Starting GPS Thread..."); + thread gps_thread(&gps_thread_fn, ref(state)); + logger.log("GPS thread started."); + + // TODO send SMS + + state = WAITING_LAUNCH; + logger.log("Waiting for launch..."); + + // Main logic + while (state != SHUT_DOWN) + { + switch (state) + { + case WAITING_LAUNCH: + // TODO detect launch and send SMS + break; + case GOING_UP: + // TODO detect records and check recording + break; + case GOING_DOWN: + // TODO detect 3 km mark and send SMS + // TODO detect 1,5 km mark and send SMS + // TODO detect 500m mark and send SMS if not landed + // TODO detect landing + break; + case LANDED: + // TODO send SMS with position after 1 minute + // TODO send SMS with position after 15 minutes and shut down + break; + default: + logger.log("State error."); + // TODO try to recover from error. + } + } + logger.log("Stopping video..."); Camera::get_instance().stop(); @@ -134,13 +181,13 @@ int main(void) return 0; } -inline bool file_exists(const string& name) +inline bool os::file_exists(const string& name) { struct stat buffer; return (stat (name.c_str(), &buffer) == 0); } -inline float get_available_disk_space() +inline float os::get_available_disk_space() { struct statvfs fs; statvfs("data", &fs); @@ -148,18 +195,26 @@ inline float get_available_disk_space() return fs.f_bsize*fs.f_bavail; } -void gps_thread_fn() +void os::gps_thread_fn(State& state) { - while ( ! GPS::get_instance().is_active()) - { - this_thread::sleep_for(1s); - } - this_thread::sleep_for(2s); - - struct timezone tz = {0, 0}; - struct timeval tv = {timegm(GPS::get_instance().get_time()), 0}; - - settimeofday(&tv, &tz); + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); - // TODO + Logger logger("data/logs/GPS/Position."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "GPSPosition"); + + while (state != LANDED) { + logger.log("Lat: "+ to_string(GPS::get_instance().get_latitude()) +", Lon: "+ + to_string(GPS::get_instance().get_longitude()) +", Alt: "+ + to_string(GPS::get_instance().get_altitude()) +", Speed: "+ + to_string(GPS::get_instance().get_velocity()->speed) +", Course: "+ + to_string(GPS::get_instance().get_velocity()->course) +", Sat: "+ + to_string(GPS::get_instance().get_satellites()) +", HDOP: "+ + to_string(GPS::get_instance().get_HDOP()) +", VDOP: "+ + to_string(GPS::get_instance().get_VDOP())); + + this_thread::sleep_for(50ms); + } } diff --git a/openstratos.h b/openstratos.h index 669a5af..395cfa7 100644 --- a/openstratos.h +++ b/openstratos.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -14,11 +15,24 @@ #include "gps/GPS.h" #include "camera/Camera.h" +namespace os +{ + enum State { + INITIALIZING, + ACQUIRING_FIX, + WAITING_LAUNCH, + GOING_UP, + GOING_DOWN, + LANDED, + SHUT_DOWN, + }; + + inline bool file_exists(const string& name); + inline float get_available_disk_space(); + void gps_thread_fn(State& state); +} + using namespace std; using namespace os; -inline bool file_exists(const string& name); -inline float get_available_disk_space(); -void gps_thread_fn(); - #endif // OPENSTRATOS_H_ From 124eeb2e9cfed8d7389f49bb59c62222425ccd73 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 18 Jul 2015 13:22:22 +0200 Subject: [PATCH 031/169] Code refactored Still GSM localization left, and GSM testing. We need a new Serial testing, if it can be tested. --- Makefile.am | 10 +-- constants.h | 7 +- gps/GPS.cc | 23 ++++- gps/GPS.h | 19 ++-- gsm/GSM.cc | 151 +++++++++++++++++++++++++++++++ gsm/GSM.h | 40 +++++++++ gsm/GSMDevice.cpp | 199 ----------------------------------------- gsm/GSMDevice.hpp | 70 --------------- openstratos.h | 4 +- serial/Serial.cc | 65 +++++++------- serial/Serial.h | 6 +- testing/gps_test.cc | 83 +++++++++-------- testing/serial_test.cc | 15 ---- 13 files changed, 319 insertions(+), 373 deletions(-) create mode 100644 gsm/GSM.cc create mode 100644 gsm/GSM.h delete mode 100644 gsm/GSMDevice.cpp delete mode 100644 gsm/GSMDevice.hpp diff --git a/Makefile.am b/Makefile.am index 617a2f8..e7ebb82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,11 @@ bin_PROGRAMS = openstratos -openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc +openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc gsm/GSM.cc openstratos_LDADD = -lwiringPi -openstratos_CPPFLAGS = -std=c++11 -Wno-unused-result +openstratos_CPPFLAGS = -std=c++14 EXTRA_PROGRAMS = openstratosRoot utesting -openstratosRoot_SOURCES = openstratos-root.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc -openstratosRoot_CPPFLAGS = -std=c++11 -Wno-unused-result +openstratosRoot_SOURCES = openstratos-root.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc gsm/GSM.cc +openstratosRoot_CPPFLAGS = -std=c++14 -Wno-unused-result utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc -utesting_CPPFLAGS = -std=c++11 -Itesting/bandit -Wno-unused-result -DOS_TESTING +utesting_CPPFLAGS = -std=c++14 -Itesting/bandit -Wno-unused-result -DOS_TESTING diff --git a/constants.h b/constants.h index 7b7cd5b..e1c78fa 100644 --- a/constants.h +++ b/constants.h @@ -14,5 +14,10 @@ #define BAT_R1 3300 #define BAT_R2 4700 - #define APNNAME "gprs-service.com" + #define GSM_LOC_SERV "gprs-service.com" + #define GSM_UART "/dev/ttyAMA0" + #define GSM_PWR_GPIO 4 + #define GSM_STATUS_GPIO 5 + #define GSM_BAUDRATE 4800 + #define GSM_ENDL "\r\n" #endif // CONSTANTS_H_ diff --git a/gps/GPS.cc b/gps/GPS.cc index 2180789..dd18b77 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include "constants.h" #include "serial/Serial.h" @@ -28,11 +29,29 @@ void GPS::initialize(const string& serial_URL) this->serial.initialize(serial_URL, 9600, "\r\n", bind(&GPS::parse, this, placeholders::_1)); #ifndef OS_TESTING - this->serial.send_frame("$PMTK220,100*2F"); - this->serial.send_frame("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->serial.send("$PMTK220,100*2F"); + this->serial.send("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); #endif } +bool GPS::is_valid(string frame) +{ + regex frame_regex("\\$[A-Z][0-9A-Z\\.,-]*\\*[0-9A-F]{1,2}"); + if ( ! regex_match(frame, frame_regex)) return false; + + uint_fast8_t checksum = 0; + for (char c : frame) + { + if (c == '$') continue; + if (c == '*') break; + + checksum ^= c; + } + uint_fast8_t frame_cs = stoi(frame.substr(frame.rfind('*')+1, frame.length()-frame.rfind('*')-1), 0, 16); + + return checksum == frame_cs; +} + uint_fast8_t GPS::parse(const string& frame) { string frame_type = frame.substr(1, frame.find_first_of(',')-1); diff --git a/gps/GPS.h b/gps/GPS.h index 5e44fea..74ea0ac 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -42,16 +42,17 @@ namespace os { public: GPS(GPS& copy) = delete; static GPS& get_instance(); + static bool is_valid(string frame); - tm* get_time() {return &this->time;} - bool is_active() {return this->active;} - uint_fast8_t get_satellites() {return this->satellites;} - double get_latitude() {return this->latitude;} - double get_longitude() {return this->longitude;} - double get_altitude() {return this->altitude;} - float get_HDOP() {return this->hdop;} - float get_VDOP() {return this->vdop;} - euc_vec* get_velocity() {return &this->velocity;} + const tm get_time() const {return this->time;} + bool is_active() const {return this->active;} + uint_fast8_t get_satellites() const {return this->satellites;} + double get_latitude() const {return this->latitude;} + double get_longitude() const {return this->longitude;} + double get_altitude() const {return this->altitude;} + float get_HDOP() const {return this->hdop;} + float get_VDOP() const {return this->vdop;} + const euc_vec get_velocity() const {return this->velocity;} void initialize(const string& serial_URL); uint_fast8_t parse(const string& frame); diff --git a/gsm/GSM.cc b/gsm/GSM.cc new file mode 100644 index 0000000..a51351e --- /dev/null +++ b/gsm/GSM.cc @@ -0,0 +1,151 @@ +#include "gsm/GSM.h" +#include "constants.h" + +#include +#include +#include + +#include +#include + +using namespace std; +using namespace os; + +GSM& GSM::get_instance() +{ + static GSM instance; + return instance; +} + +GSM::~GSM() +{ + this->serial.close(); +} + +bool GSM::initialize(int pwr_gpio, int status_gpio, const string& serial_URL) +{ + this->pwr_gpio = pwr_gpio; + this->status_gpio = status_gpio; + + if ( ! this->serial.initialize(serial_URL, 9600)) + { + return false; + } + + pinMode(this->pwr_gpio, OUTPUT); + digitalWrite(this->pwr_gpio, HIGH); + pinMode(this->pwr_gpio, INPUT); + + this_thread::sleep_for(3s); + + return true; +} + +bool GSM::send_SMS(const string& message, const string& number) const +{ + if (this->send_command_read("AT+CMGF=1") != "OK") + { + return false; + } + + stringstream send_command; + + send_command << "AT+CMGS=\"" << number << "\""; + + if (this->send_command_read(send_command.str()) != "> ") + { + return false; + } + + this->serial.send(message+"\x1a"+GSM_ENDL); + this->serial.flush(); + + return true; +} + +bool GSM::get_location(double& latitude, double& longitude) const +{ + if ( ! this->init_GPRS()) + { + return false; + } + // TODO + // OLD: + // uint16_t responseLength = SerialSendRead("AT+CIPGSMLOC=1,1"); + // serialin[responseLength+1] = (char)0x0; + if (this->tear_down_GPRS()) + { + return false; + } + return false; +} + +bool GSM::get_status() const +{ + return digitalRead(this->status_gpio) == HIGH; +} + +bool GSM::is_up() const +{ + return this->send_command_read("AT") == "OK"; +} + +bool GSM::turn_on() const +{ + if ( ! this->get_status()) + { + digitalWrite(this->pwr_gpio, LOW); + this_thread::sleep_for(2s); + digitalWrite(this->pwr_gpio, HIGH); + this_thread::sleep_for(500ms); + return true; + } + else + { + return false; + } +} + +bool GSM::turn_off() const +{ + if (this->get_status()) + { + digitalWrite(this->pwr_gpio, LOW); + this_thread::sleep_for(2s); + digitalWrite(this->pwr_gpio, HIGH); + this_thread::sleep_for(500ms); + return true; + } + else + { + return false; + } +} + +bool GSM::init_GPRS() const +{ + if (this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") != "OK" || + this->send_command_read("AT+SAPBR=3,1,\"APN\",\"" + string(GSM_LOC_SERV) + ";") != "OK" || + this->send_command_read("AT+SAPBR=1,1") != "OK" || + this->send_command_read("AT+SAPBR=2,1") != "OK") + { + this->serial.flush(); + return false; + } + this->serial.flush(); + return true; +} + +bool GSM::tear_down_GPRS() const +{ + return this->send_command_read("AT+SAPBR=0,1") == "OK"; +} + +const string GSM::send_command_read(const string& command) const +{ + this->serial.flush(); + this->serial.send(command); + string response = this->serial.read_line(); + this->serial.flush(); + return response; +} diff --git a/gsm/GSM.h b/gsm/GSM.h new file mode 100644 index 0000000..a72ff60 --- /dev/null +++ b/gsm/GSM.h @@ -0,0 +1,40 @@ +#ifndef GSM_GMS_H_ +#define GSM_GSM_H_ + +#include + +#include "serial/Serial.h" + +using namespace std; + +namespace os { + + class GSM + { + private: + Serial serial; + + int pwr_gpio; + int status_gpio; + int fh; + + GSM() = default; + ~GSM(); + + const string send_command_read(const string& command) const; + bool init_GPRS() const; + bool tear_down_GPRS() const; + public: + GSM(GSM& copy) = delete; + static GSM& get_instance(); + + bool initialize(int pwr_gpio, int status_gpio, const string& serial_URL); + bool send_SMS(const string& message, const string& number) const; + bool get_location(double& latitude, double& longitude) const; + bool get_status() const; + bool is_up() const; + bool turn_on() const; + bool turn_off() const; + }; +} +#endif diff --git a/gsm/GSMDevice.cpp b/gsm/GSMDevice.cpp deleted file mode 100644 index e8d451d..0000000 --- a/gsm/GSMDevice.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#include "GSMDevice.hpp" - -using namespace std; - -GSMDevice::GSMDevice(){ //Instantiates a GSM device controlled using GPIO 4 (default, software pwr control) and /dev/ttyAMA0 for UART - GSMDevice(DEFAULT_GPIO,5,DEFAULT_UART); -} - -//WARNING: May take up to six seconds -GSMDevice::GSMDevice(int pwrgpio, int statusgpio, string serial){ //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial){ - this->statusgpio = statusgpio; - this->pwrgpio = pwrgpio; - this->serialPort = serial; - InitSerial(); - InitGSMModule(); - delay(3000); //Allow some time for the GSM module to connect to the network. -} - -//Returns 0 for LOW, 1 for HIGH. -uint16_t GSMDevice::CheckModuleStatus(){ - return digitalRead(this->statusgpio); -} - - -//Turns the module on. -void GSMDevice::TurnOn(){ - if(!CheckModuleStatus()){ - TogglePWR(); - } -} - -//Turns the module off. -void GSMDevice::TurnOff(){ - if(CheckModuleStatus()){ - TogglePWR(); - } -} - - -void GSMDevice::TogglePWR(){ - //Toggles the power status of the GSM module. Turns it on if it is off and turns it off if it is on. - //WARNING: Takes 2500 miliseconds to complete - - digitalWrite(this->pwrgpio, LOW); //Spec says that the adafruit FONA expects a 2000ms low pulse - delay(2000); - digitalWrite(this->pwrgpio, HIGH); - delay(500); //Give the module some time to turn on, ensure that when - //function returns the module is operational. -} - -bool GSMDevice::Call(string num){ //Establishes a voice connection with a phone number. The function - char *number = new char[num.length() + 1]; //will return when the voice connection is established. Note that - strcpy(number, num.c_str()); //having a voice connection does not mean that both parties are - char send[20]; //ready to exchange data. In fact, the sender should allow for some - //time before transmitting so that the receiver can answer. - - if(strlen(number)>(sizeof(send)/sizeof(char))-(3+1)){ //If the number does not fit into the buffer, reject it, as - if(OPENSTRATOS_GSM_DEBUG_){ //phone numbers (without C.C.) take 9 chars. - printf("[!] Number too long. Aborting call\n"); - } - return false; - } - strncpy(send, "ATD", strlen("ATD")); //AT command preamble: ATD - strncpy(send+3, number, strlen(number)); //Number to dial - int length = strlen(send); - send[length] = (char)0x3b;//ascii for semicolon //Semicolon ending command - send[length+1] = (char)0x0;//terminate string with null byte - bool success = SerialSendCompareResponse(send, "OK"); //Modem will reply OK if a voice connection was established. - if(OPENSTRATOS_GSM_DEBUG_ && !success){ - printf("[!] ATD+number+; did not reply OK\n"); - } - return success; -} - -bool GSMDevice::AbortCall(){ //Aborts a phone call. No effect if not in a call. - bool success = SerialSendCompareResponse("ATH","OK"); //Returns true if call aborted or if not in a call. - if(OPENSTRATOS_GSM_DEBUG_ && !success){ //Expecting the modem to return OK. - printf("[!] ATH did not reply OK\n"); - } - return success; -} - -bool GSMDevice::SendSMS(string message, string n){ //Sends a short message to a phone number - char *destnum = new char[n.length() + 1]; - strcpy(destnum, n.c_str()); - char *messagechar = new char[message.length() + 1]; - strcpy(messagechar, message.c_str()); - - if (SerialSendCompareResponse("AT+CMGF=1", "OK")==false){ //Select SMS message format - if(OPENSTRATOS_GSM_DEBUG_){ //Abort if the modem cannot be set to text mode. - printf("[!] AT+CMFG=1 did not reply OK to SMS format selection\n"); - } - return false; - } - - char send[30] = "AT+CMGS=\""; //SMS command preamble: AT+CMGS=" - strncpy(send+9 , destnum, 19); //SMS destination (actual phone number) - send[strlen(send)] = (char)0x22;//ascii for " (double quote) //SMS command termination: " - - if (!SerialSendCompareResponse(send, "> ")){ //Input prompt should be open and expecting text input - if(OPENSTRATOS_GSM_DEBUG_){ - printf("[!] Failed SMS attempt. SIM800L did not provide input prompt\n"); - } - return false; //If there is not any input prompt, abort. - } - - serialPrintf(fdesc,messagechar); //Send message - serialPrintf(fdesc,"\x1a\r\n"); //SUB control character (ascii 0x1a)+Return - FlushSerialInput(); //Module will reply with "+CMGS". Not interested in that, so flush. - return true; //Message sent. -} - -void GSMDevice::BroadcastGeolocation(string n){ //Tries to perform geolocation and sends coordinates to a phone number via SMS. - initGPRS(); - uint16_t responseLength = SerialSendRead("AT+CIPGSMLOC=1,1"); - serialin[responseLength+1] = (char)0x0; - SendSMS(serialin, "699686404"); - tearDownGPRS(); -} - -void GSMDevice::InitGPRS(){ - SerialSendCompareResponse("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"", "OK"); //About to turn on GPRS - string preamble = "AT+SAPBR=3,1,\"APN\",\""; - string end = ";"; - string command = preamble + APNNAME + end; - char *send = new char[command.length() + 1]; - strcpy(send, command.c_str()); - SerialSendCompareResponse(send, "OK"); //Set APN provided. - SerialSendCompareResponse("AT+SAPBR=1,1","OK"); //Activate GPRS context - /*SerialSendCompareResponse("AT+SAPBR=2,1","OK");*/ //Not realy necessary -} - -void GSMDevice::TearDownGPRS(){ - SerialSendCompareResponse("AT+SAPBR=0,1","OK"); -} - -bool GSMDevice::CheckGSMModule(){ //Returns true if module is up and running, false if it is not. - if(SerialSendCompareResponse("AT","OK")){ //Probe the SIM800L, see AT command reference for more info. - return true; - } - return false; -} - -bool GSMDevice::InitSerial(){ - char *cstr = new char[this->serialPort.length() + 1]; - strcpy(cstr, this->serialPort.c_str()); - fdesc = serialOpen(cstr, UART_BAUDRATE); - if(fdesc==-1){ //serialOpen returns a standard linux file descriptor. -1 means failed - ;/*EXCEPTION: NO SERIAL PORT AVAILABLE*/ - if(OPENSTRATOS_GSM_DEBUG_){ - printf("[!] Serial port open error\n"); - } - return false; - } - return true; -} - -bool GSMDevice::InitGSMModule(){ - if (wiringPiSetup() == -1){ - /*EXCEPTION: UNABLE TO ACCESS GPIOS*/; - return false; - } - pinMode(this->pwrgpio, OUTPUT); //Set GPIO as digital output - digitalWrite(this->pwrgpio, HIGH); //Set to high so that GSM module stays in standby until TogglePWR is called - pinMode(this->pwrgpio, INPUT); - return true; -} - -bool GSMDevice::SerialSendCompareResponse(char *send, char *expected){ - SerialSendRead(send); //Send a string via serial. - return (strcmp(serialin, expected) == 0); //Compare what got placed in serialin with the expected answer -} - -uint16_t GSMDevice::SerialSendRead(char *send) { - FlushSerialInput(); - if(OPENSTRATOS_GSM_DEBUG_){ - printf("[i] Sending: %s", send); - } - serialPrintf(fdesc, send); - uint16_t readlength = SerialReadLine(); - if(OPENSTRATOS_GSM_DEBUG_){ - printf("[i] Received: %s\n", serialin); - } - return readlength; -} - -void GSMDevice::FlushSerialInput() { - serialFlush(fdesc); -} - -uint16_t GSMDevice::SerialReadLine() { - uint16_t i = 0; - while(serialDataAvail(fdesc)&&i<254) { - char c = serialGetchar(fdesc); - serialin[i++] = c; - } - serialin[i] = 0x0; - return i; -} diff --git a/gsm/GSMDevice.hpp b/gsm/GSMDevice.hpp deleted file mode 100644 index f1a2607..0000000 --- a/gsm/GSMDevice.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef OPENSTRATOS_WIRINGPI_H_ -#define OPENSTRATOS_WIRINGPI_H_ -#include -#endif - -#ifndef OPENSTRATOS_WIRINGSERIAL_H -#define OPENSTRATOS_WIRINGSERIAL_H -#include -#endif - -#ifndef OPENSTRATOS_GSM_INCLUDE_ALL_ -#define OPENSTRATOS_GSM_INCLUDE_ALL_ -#include -#include -#include -#include -#include -#include -#endif - -#define OPENSTRATOS_GSM_DEBUG_ 0 -//0 = disable debug mode -//1 = enable debug mode - -#ifndef OPENSTRATOS_GSM_GSMDEVICE_CLASS_ -#define OPENSTRATOS_GSM_GSMDEVICE_CLASS_ -using namespace std; - -class GSMDevice{ - public: - GSMDevice(); //Instantiates a GSM device controlled using GPIO 4 (default, software pwr control) and /dev/ttyAMA0 for UART - GSMDevice(int pwrgpio, int statusgpio, string serial); //Instantiates a GSM device controlled using a GPIO pin (given by GPIO parameter) and a UART port (given by serial); - void TogglePWR(); //Toggles the power status of the GSM module. Turns it on if it is off and turns it off if it is on. - bool Call(string number); //Calls a given phone number. Returns true if suceeded, false if failed. - bool AbortCall(); //Aborts a phone call. Returns true if suceeded, false if failed or not in a call. - bool SendSMS(string message, string n); //Sends a short message to a phone number. Returns true if suceeded, false if failed - void BroadcastGeolocation(string n); //Tries to perform geolocation and sends coordinates to a phone number via SMS. - bool CheckGSMModule(); //Returns true if module is up and running, false if it is not - private: - uint16_t CheckModuleStatus(); - void TurnOn(); - void TurnOff(); - uint16_t SerialReadLine(); - uint16_t SerialSendRead(char *); - void FlushSerialInput(); //Discards all data received from the serial port. - bool SerialSendCompareResponse(char*, char*); //Sends a string of data via serial port. Checks that the reply matches with another string. - bool InitGSMModule(); //Initializes the gsm module. Returns true if successful. False if failed. - bool InitSerial(); //Initializes the serial interface. Returns true if successful. False if failed. - void InitGPRS(); - void TearDownGPRS(); - int pwrgpio; - int statusgpio; //GPIO pin used for software power control - string serialPort; //Serial port identifier. Tipically /dev/ttyAMA0 in Raspbian. - int fdesc; //Standard unix file descriptor associated with the serial port (see serialPort) - char serialin[255]; //Buffer on which data received via the serial port is placed -}; -#endif - -#ifndef OPENSTRATOS_GSM_DEFAULT_PARAMETERS_ -#define OPENSTRATOS_GSM_DEFAULT_PARAMETERS_ -#define DEFAULT_UART "/dev/ttyAMA0" -#define DEFAULT_GPIO 4 -#define UART_BAUDRATE 4800 -#endif - -#ifndef OPENSTRATOS_GSM_GPIO_VALUES_ -#define OPENSTRATOS_GSM_GPIO_VALUES_ -#define HIGH 1 -#define LOW 0 -#endif diff --git a/openstratos.h b/openstratos.h index edbd55e..e9675bf 100644 --- a/openstratos.h +++ b/openstratos.h @@ -1,10 +1,10 @@ #ifndef OPENSTRATOS_H_ #define OPENSTRATOS_H_ -#include "config.hpp" +#include "config.h" #include using namespace std; -#endif // OPENSTRATOS_H_ \ No newline at end of file +#endif // OPENSTRATOS_H_ diff --git a/serial/Serial.cc b/serial/Serial.cc index d3dc457..60d47b9 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -3,7 +3,6 @@ #include #include -#include #include #include #include @@ -27,6 +26,23 @@ void Serial::initialize(const string& url, int baud, const string endl, function t.detach(); } +bool Serial::initialize(const string& url, int baud) +{ + #ifndef OS_TESTING + this->fd = serialOpen(url.c_str(), baud); + #endif + + if (this->fd == -1) + { + return false; + } + + this->open = true; + this->stopped = false; + + return true; +} + Serial::~Serial() { this->close(); @@ -34,7 +50,7 @@ Serial::~Serial() void Serial::serial_thread() { - string frame; + string response; int endl_pos = 0; while(this->open) @@ -47,17 +63,14 @@ void Serial::serial_thread() for (int i = 0; i < available; i++) { char c = serialGetchar(this->fd); - frame += c; - + response += c; if (c == this->endl[endl_pos]) ++endl_pos; if (endl_pos == this->endl.length()) { - frame = frame.substr(0, frame.length()-endl.length()); - - if (this->is_valid(frame)) this->listener(frame); - // TODO decide what to do in case of non valid frame + response = response.substr(0, response.length()-endl.length()); - frame = ""; + this->listener(response); + response = ""; endl_pos = 0; this_thread::sleep_for(chrono::milliseconds(50)); } @@ -76,17 +89,9 @@ void Serial::serial_thread() this->stopped = true; } -uint_fast8_t Serial::send_frame(string frame) +void Serial::send(const string& str) const { - if (this->is_valid(frame)) - { - frame += endl; - serialPuts(this->fd, frame.c_str()); - } - else - { - // TODO log error - } + serialPuts(this->fd, (str+this->endl).c_str()); } void Serial::close() @@ -99,20 +104,14 @@ void Serial::close() #endif } -bool Serial::is_valid(string frame) +const string Serial::read_line() const { - regex frame_regex("\\$[A-Z][0-9A-Z\\.,-]*\\*[0-9A-F]{1,2}"); - if ( ! regex_match(frame, frame_regex)) return false; - - uint_fast8_t checksum = 0; - for (char c : frame) - { - if (c == '$') continue; - if (c == '*') break; - - checksum ^= c; - } - uint_fast8_t frame_cs = stoi(frame.substr(frame.rfind('*')+1, frame.length()-frame.rfind('*')-1), 0, 16); + // TODO + string response; + return response; +} - return checksum == frame_cs; +void Serial::flush() const +{ + serialFlush(this->fd); } diff --git a/serial/Serial.h b/serial/Serial.h index bd8fc73..b1a9c6b 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -24,10 +24,12 @@ namespace os { Serial(Serial& copy) = delete; ~Serial(); - uint_fast8_t send_frame(string frame); + void send(const string& str) const; void close(); - bool is_valid(string frame); void initialize(const string& serial_URL, int baud, const string endl, function); + bool initialize(const string& serial_URL, int baud); + const string read_line() const; + void flush() const; }; } diff --git a/testing/gps_test.cc b/testing/gps_test.cc index edbd80d..7024140 100644 --- a/testing/gps_test.cc +++ b/testing/gps_test.cc @@ -10,15 +10,25 @@ describe("GPS", [](){ AssertThat(kt_to_mps(0), Equals(0)); }); + it("frame validity test", [&](){ + string valid = "$REPORT,0,23,185213184,1421782514,1,4140.7276,-0404.8853,73,52,43*1E"; + string valid2 = "$PMTK226,3,30*4"; + string not_valid = "$REPORT,0,23,185213184,1421782514,1,4140.7276,-0404.8853,73,52,43*14"; + + AssertThat(GPS::is_valid(valid), Equals(true)); + AssertThat(GPS::is_valid(valid2), Equals(true)); + AssertThat(GPS::is_valid(not_valid), Equals(false)); + }); + it("GGA frame parser test", [&](){ GPS::get_instance().parse("$GPGGA,151025,2011.3454,N,12020.2464,W,1,05,1.53,20134.13,M,20103.45,M,,*56"); AssertThat(GPS::get_instance().is_active(), Equals(true)); - tm* gps_time = GPS::get_instance().get_time(); - AssertThat(gps_time->tm_hour, Equals(15)); - AssertThat(gps_time->tm_min, Equals(10)); - AssertThat(gps_time->tm_sec, Equals(25)); + tm gps_time = GPS::get_instance().get_time(); + AssertThat(gps_time.tm_hour, Equals(15)); + AssertThat(gps_time.tm_min, Equals(10)); + AssertThat(gps_time.tm_sec, Equals(25)); AssertThat(GPS::get_instance().get_satellites(), Equals(5)); AssertThat(GPS::get_instance().get_latitude(), Is().EqualToWithDelta(20.18909, 0.00001)); @@ -30,9 +40,9 @@ describe("GPS", [](){ it("GGA frame parser pass test", [&](){ - int hour = GPS::get_instance().get_time()->tm_hour; - int min = GPS::get_instance().get_time()->tm_min; - int sec = GPS::get_instance().get_time()->tm_sec; + int hour = GPS::get_instance().get_time().tm_hour; + int min = GPS::get_instance().get_time().tm_min; + int sec = GPS::get_instance().get_time().tm_sec; int satellites = GPS::get_instance().get_satellites(); double latitude = GPS::get_instance().get_latitude(); @@ -44,9 +54,9 @@ describe("GPS", [](){ AssertThat(GPS::get_instance().is_active(), Equals(false)); - AssertThat(GPS::get_instance().get_time()->tm_hour, Equals(hour)); - AssertThat(GPS::get_instance().get_time()->tm_min, Equals(min)); - AssertThat(GPS::get_instance().get_time()->tm_sec, Equals(sec)); + AssertThat(GPS::get_instance().get_time().tm_hour, Equals(hour)); + AssertThat(GPS::get_instance().get_time().tm_min, Equals(min)); + AssertThat(GPS::get_instance().get_time().tm_sec, Equals(sec)); AssertThat(GPS::get_instance().get_satellites(), Equals(satellites)); AssertThat(GPS::get_instance().get_latitude(), Equals(latitude)); @@ -79,50 +89,53 @@ describe("GPS", [](){ AssertThat(GPS::get_instance().is_active(), Equals(true)); - tm* gps_time = GPS::get_instance().get_time(); + tm gps_time = GPS::get_instance().get_time(); - AssertThat(gps_time->tm_mday, Equals(19)); - AssertThat(gps_time->tm_mon, Equals(11)); - AssertThat(gps_time->tm_year, Equals(194)); - AssertThat(gps_time->tm_hour, Equals(22)); - AssertThat(gps_time->tm_min, Equals(54)); - AssertThat(gps_time->tm_sec, Equals(46)); + AssertThat(gps_time.tm_mday, Equals(19)); + AssertThat(gps_time.tm_mon, Equals(11)); + AssertThat(gps_time.tm_year, Equals(194)); + AssertThat(gps_time.tm_hour, Equals(22)); + AssertThat(gps_time.tm_min, Equals(54)); + AssertThat(gps_time.tm_sec, Equals(46)); AssertThat(GPS::get_instance().get_latitude(), Is().EqualToWithDelta(49.27417, 0.00001)); AssertThat(GPS::get_instance().get_longitude(), Is().EqualToWithDelta(-123.18533, 0.00001)); - AssertThat(GPS::get_instance().get_velocity()->speed, Is().EqualToWithDelta(0.25722, 0.00001)); - AssertThat(GPS::get_instance().get_velocity()->course, Is().EqualToWithDelta(54.7, 0.001)); + AssertThat(GPS::get_instance().get_velocity().speed, Is().EqualToWithDelta(0.25722, 0.00001)); + AssertThat(GPS::get_instance().get_velocity().course, Is().EqualToWithDelta(54.7, 0.001)); }); it("RMC frame parser pass test", [&](){ - int hour = GPS::get_instance().get_time()->tm_hour; - int min = GPS::get_instance().get_time()->tm_min; - int sec = GPS::get_instance().get_time()->tm_sec; - int mday = GPS::get_instance().get_time()->tm_mday; - int mon = GPS::get_instance().get_time()->tm_mon; - int year = GPS::get_instance().get_time()->tm_year; + tm gps_time = GPS::get_instance().get_time(); + int hour = gps_time.tm_hour; + int min = gps_time.tm_min; + int sec = gps_time.tm_sec; + int mday = gps_time.tm_mday; + int mon = gps_time.tm_mon; + int year = gps_time.tm_year; double latitude = GPS::get_instance().get_latitude(); double longitude = GPS::get_instance().get_longitude(); - float speed = GPS::get_instance().get_velocity()->speed; - float course = GPS::get_instance().get_velocity()->course; + float speed = GPS::get_instance().get_velocity().speed; + float course = GPS::get_instance().get_velocity().course; GPS::get_instance().parse("$GPRMC,081836,V,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*75"); AssertThat(GPS::get_instance().is_active(), Equals(false)); - AssertThat(GPS::get_instance().get_time()->tm_hour, Equals(hour)); - AssertThat(GPS::get_instance().get_time()->tm_min, Equals(min)); - AssertThat(GPS::get_instance().get_time()->tm_sec, Equals(sec)); - AssertThat(GPS::get_instance().get_time()->tm_mday, Equals(mday)); - AssertThat(GPS::get_instance().get_time()->tm_mon, Equals(mon)); - AssertThat(GPS::get_instance().get_time()->tm_year, Equals(year)); + tm new_gps_time = GPS::get_instance().get_time(); + + AssertThat(new_gps_time.tm_hour, Equals(hour)); + AssertThat(new_gps_time.tm_min, Equals(min)); + AssertThat(new_gps_time.tm_sec, Equals(sec)); + AssertThat(new_gps_time.tm_mday, Equals(mday)); + AssertThat(new_gps_time.tm_mon, Equals(mon)); + AssertThat(new_gps_time.tm_year, Equals(year)); AssertThat(GPS::get_instance().get_latitude(), Equals(latitude)); AssertThat(GPS::get_instance().get_longitude(), Equals(longitude)); - AssertThat(GPS::get_instance().get_velocity()->speed, Equals(speed)); - AssertThat(GPS::get_instance().get_velocity()->course, Equals(course)); + AssertThat(GPS::get_instance().get_velocity().speed, Equals(speed)); + AssertThat(GPS::get_instance().get_velocity().course, Equals(course)); }); }); diff --git a/testing/serial_test.cc b/testing/serial_test.cc index bf761d0..329c021 100644 --- a/testing/serial_test.cc +++ b/testing/serial_test.cc @@ -1,17 +1,2 @@ describe("Serial", [](){ - - it("frame validity test", [&](){ - string valid = "$REPORT,0,23,185213184,1421782514,1,4140.7276,-0404.8853,73,52,43*1E"; - string valid2 = "$PMTK226,3,30*4"; - string not_valid = "$REPORT,0,23,185213184,1421782514,1,4140.7276,-0404.8853,73,52,43*14"; - - Serial serial; - serial.initialize("", 9600, "\n", NULL); - - AssertThat(serial.is_valid(valid), Equals(true)); - AssertThat(serial.is_valid(valid2), Equals(true)); - AssertThat(serial.is_valid(not_valid), Equals(false)); - - serial.close(); - }); }); From c96a49546115219ecb9ab7058b1ca255baacba3d Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 21:16:16 +0200 Subject: [PATCH 032/169] Small fixes --- constants.h | 2 ++ gps/GPS.h | 4 ++-- openstratos.cc | 58 ++++++++++++++++++++++++++++++++++++++++---------- openstratos.h | 4 ++++ 4 files changed, 55 insertions(+), 13 deletions(-) diff --git a/constants.h b/constants.h index e1c78fa..376c2ff 100644 --- a/constants.h +++ b/constants.h @@ -20,4 +20,6 @@ #define GSM_STATUS_GPIO 5 #define GSM_BAUDRATE 4800 #define GSM_ENDL "\r\n" + + #define STATE_FILE "data/last_state.txt" #endif // CONSTANTS_H_ diff --git a/gps/GPS.h b/gps/GPS.h index bbcd1ae..1b17d92 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -47,7 +47,7 @@ namespace os { static GPS& get_instance(); static bool is_valid(string frame); - const tm get_time() const {return this->time;} + tm get_time() const {return this->time;} bool is_active() const {return this->active;} uint_fast8_t get_satellites() const {return this->satellites;} double get_latitude() const {return this->latitude;} @@ -55,7 +55,7 @@ namespace os { double get_altitude() const {return this->altitude;} float get_HDOP() const {return this->hdop;} float get_VDOP() const {return this->vdop;} - const euc_vec get_velocity() const {return this->velocity;} + euc_vec get_velocity() const {return this->velocity;} bool initialize(const string& serial_URL); uint_fast8_t parse(const string& frame); diff --git a/openstratos.cc b/openstratos.cc index 03b6b5e..bcfa6c2 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -76,7 +76,7 @@ int main(void) exit(1); } - // 115 MiB per minute +/- + // ~115 MiB per minute logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7235174400) + " hours of fullHD video."); @@ -122,7 +122,8 @@ int main(void) logger.log("Starting video recording..."); Camera::get_instance().record(); - state = ACQUIRING_FIX; + state = set_state(ACQUIRING_FIX); + logger.log("State changed to "+ state_to_string(state) +"."); while ( ! GPS::get_instance().is_active()) { this_thread::sleep_for(1s); @@ -131,7 +132,8 @@ int main(void) this_thread::sleep_for(2s); struct timezone tz = {0, 0}; - struct timeval tv = {timegm(GPS::get_instance().get_time()), 0}; + tm gps_time = GPS::get_instance().get_time(); + struct timeval tv = {timegm(&gps_time), 0}; settimeofday(&tv, &tz); logger.log("System date change."); @@ -142,7 +144,8 @@ int main(void) // TODO send SMS - state = WAITING_LAUNCH; + state = set_state(WAITING_LAUNCH); + logger.log("State changed to "+ state_to_string(state) +"."); logger.log("Waiting for launch..."); // Main logic @@ -164,11 +167,8 @@ int main(void) break; case LANDED: // TODO send SMS with position after 1 minute - // TODO send SMS with position after 15 minutes and shut down - break; - default: - logger.log("State error."); - // TODO try to recover from error. + // TODO send SMS with position after 15 minutes and shut down. + break; } } @@ -209,8 +209,8 @@ void os::gps_thread_fn(State& state) logger.log("Lat: "+ to_string(GPS::get_instance().get_latitude()) +", Lon: "+ to_string(GPS::get_instance().get_longitude()) +", Alt: "+ to_string(GPS::get_instance().get_altitude()) +", Speed: "+ - to_string(GPS::get_instance().get_velocity()->speed) +", Course: "+ - to_string(GPS::get_instance().get_velocity()->course) +", Sat: "+ + to_string(GPS::get_instance().get_velocity().speed) +", Course: "+ + to_string(GPS::get_instance().get_velocity().course) +", Sat: "+ to_string(GPS::get_instance().get_satellites()) +", HDOP: "+ to_string(GPS::get_instance().get_HDOP()) +", VDOP: "+ to_string(GPS::get_instance().get_VDOP())); @@ -218,3 +218,39 @@ void os::gps_thread_fn(State& state) this_thread::sleep_for(50ms); } } + +State os::set_state(State new_state) +{ + ofstream state_file(STATE_FILE); + state_file << new_state; + state_file.close(); + + return new_state; +} + +string os::state_to_string(State state) +{ + switch (state) + { + case INITIALIZING: + return "INITIALIZING"; + break; + case ACQUIRING_FIX: + return "ACQUIRING_FIX"; + break; + case WAITING_LAUNCH: + return "WAITING_LAUNCH"; + break; + case GOING_UP: + return "GOING_UP"; + break; + case GOING_DOWN: + return "GOING_DOWN"; + break; + case LANDED: + return "LANDED"; + break; + case SHUT_DOWN: + return "SHUT_DOWN"; + } +} diff --git a/openstratos.h b/openstratos.h index 395cfa7..5f189e6 100644 --- a/openstratos.h +++ b/openstratos.h @@ -2,6 +2,7 @@ #define OPENSTRATOS_H_ #include +#include #include #include #include @@ -11,6 +12,7 @@ #include #include "config.h" +#include "constants.h" #include "logger/Logger.h" #include "gps/GPS.h" #include "camera/Camera.h" @@ -30,6 +32,8 @@ namespace os inline bool file_exists(const string& name); inline float get_available_disk_space(); void gps_thread_fn(State& state); + State set_state(State new_state); + string state_to_string(State state); } using namespace std; From 95b51a82a73c91e74fb06b8715000f5c7749015f Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 21:38:20 +0200 Subject: [PATCH 033/169] Free space instead of available space --- openstratos.cc | 10 +++++----- openstratos.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index bcfa6c2..e4c0754 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -68,8 +68,8 @@ int main(void) } } - logger.log("Available disk space: " + to_string(get_available_disk_space()/1073741824) + " GiB"); - if (get_available_disk_space() < 21705523200) // Enough for about 3 hours of video + logger.log("Available disk space: " + to_string(get_free_disk_space()/1073741824) + " GiB"); + if (get_free_disk_space() < 21705523200) // Enough for about 3 hours of video { logger.log("Error: Not enough disk space."); cout << "[OpenStratos] Error: Not enough disk space." << endl; @@ -77,7 +77,7 @@ int main(void) } // ~115 MiB per minute - logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7235174400) + + logger.log("Disk space enough for about " + to_string(get_free_disk_space()/7235174400) + " hours of fullHD video."); // logger.log("Turning on GPS..."); @@ -187,12 +187,12 @@ inline bool os::file_exists(const string& name) return (stat (name.c_str(), &buffer) == 0); } -inline float os::get_available_disk_space() +inline float os::get_free_disk_space() { struct statvfs fs; statvfs("data", &fs); - return fs.f_bsize*fs.f_bavail; + return fs.f_bsize*fs.f_bfree; } void os::gps_thread_fn(State& state) diff --git a/openstratos.h b/openstratos.h index 5f189e6..313720a 100644 --- a/openstratos.h +++ b/openstratos.h @@ -30,7 +30,7 @@ namespace os }; inline bool file_exists(const string& name); - inline float get_available_disk_space(); + inline float get_free_disk_space(); void gps_thread_fn(State& state); State set_state(State new_state); string state_to_string(State state); From fb89068c584770b05a3cf3bddfc79ce63f9546dc Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 21:49:01 +0200 Subject: [PATCH 034/169] Available space must be float or overflows in 32 bits --- openstratos.cc | 10 +++++----- openstratos.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index e4c0754..c04f519 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -68,8 +68,8 @@ int main(void) } } - logger.log("Available disk space: " + to_string(get_free_disk_space()/1073741824) + " GiB"); - if (get_free_disk_space() < 21705523200) // Enough for about 3 hours of video + logger.log("Available disk space: " + to_string(get_available_disk_space()/1073741824) + " GiB"); + if (get_available_disk_space() < 21705523200) // Enough for about 3 hours of video { logger.log("Error: Not enough disk space."); cout << "[OpenStratos] Error: Not enough disk space." << endl; @@ -77,7 +77,7 @@ int main(void) } // ~115 MiB per minute - logger.log("Disk space enough for about " + to_string(get_free_disk_space()/7235174400) + + logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7235174400) + " hours of fullHD video."); // logger.log("Turning on GPS..."); @@ -187,12 +187,12 @@ inline bool os::file_exists(const string& name) return (stat (name.c_str(), &buffer) == 0); } -inline float os::get_free_disk_space() +inline float os::get_available_disk_space() { struct statvfs fs; statvfs("data", &fs); - return fs.f_bsize*fs.f_bfree; + return ((float) fs.f_bsize)*fs.f_bavail; } void os::gps_thread_fn(State& state) diff --git a/openstratos.h b/openstratos.h index 313720a..5f189e6 100644 --- a/openstratos.h +++ b/openstratos.h @@ -30,7 +30,7 @@ namespace os }; inline bool file_exists(const string& name); - inline float get_free_disk_space(); + inline float get_available_disk_space(); void gps_thread_fn(State& state); State set_state(State new_state); string state_to_string(State state); From 34cdb9402e7e324bbdfdec8d718dce53045ee161 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 22:28:21 +0200 Subject: [PATCH 035/169] Added a bit of logic --- camera/Camera.cc | 2 ++ openstratos.cc | 30 +++++++++++++++++++++++------- testing/testing.cc | 3 +++ 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 1c4dfd7..6df1f55 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -10,6 +10,8 @@ #include #include +#include "config.h" + using namespace os; using namespace std; diff --git a/openstratos.cc b/openstratos.cc index c04f519..f971122 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -69,7 +69,7 @@ int main(void) } logger.log("Available disk space: " + to_string(get_available_disk_space()/1073741824) + " GiB"); - if (get_available_disk_space() < 21705523200) // Enough for about 3 hours of video + if (get_available_disk_space() < 22649241600) // Enough for about 3 hours of video { logger.log("Error: Not enough disk space."); cout << "[OpenStratos] Error: Not enough disk space." << endl; @@ -77,7 +77,7 @@ int main(void) } // ~115 MiB per minute - logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7235174400) + + logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7549747200) + " hours of fullHD video."); // logger.log("Turning on GPS..."); @@ -154,21 +154,37 @@ int main(void) switch (state) { case WAITING_LAUNCH: - // TODO detect launch and send SMS + // TODO detect launch + this_thread::sleep_for(2s); + logger.log("Balloon launched."); + // TODO send SMS + state = set_state(GOING_UP); + logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_UP: - // TODO detect records and check recording + // TODO detect burst + this_thread::sleep_for(2s); + logger.log("Balloon burst."); + state = set_state(GOING_DOWN); + logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_DOWN: // TODO detect 3 km mark and send SMS // TODO detect 1,5 km mark and send SMS // TODO detect 500m mark and send SMS if not landed // TODO detect landing + this_thread::sleep_for(2s); + logger.log("Landed."); + state = set_state(LANDED); + logger.log("State changed to "+ state_to_string(state) +"."); break; case LANDED: // TODO send SMS with position after 1 minute // TODO send SMS with position after 15 minutes and shut down. - break; + this_thread::sleep_for(2s); + logger.log("Shutting down..."); + state = set_state(SHUT_DOWN); + logger.log("State changed to "+ state_to_string(state) +"."); } } @@ -176,8 +192,8 @@ int main(void) Camera::get_instance().stop(); logger.log("Joining threads..."); - // gps_thread.join(); - logger.log("Finishing execution."); + gps_thread.join(); + logger.log("Finishing execution..."); return 0; } diff --git a/testing/testing.cc b/testing/testing.cc index 6a7551e..f4e9cf8 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -2,6 +2,9 @@ #include +#include "config.h" +#include "constants.h" + #include "serial/Serial.h" #include "camera/Camera.h" #include "temperature/Temperature.h" From d4fda181ca6967a5b00f695d3d01b118bde15c02 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 22:38:18 +0200 Subject: [PATCH 036/169] Added some debug fields --- openstratos.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index f971122..38ec434 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -124,10 +124,10 @@ int main(void) state = set_state(ACQUIRING_FIX); logger.log("State changed to "+ state_to_string(state) +"."); - while ( ! GPS::get_instance().is_active()) - { - this_thread::sleep_for(1s); - } + // while ( ! GPS::get_instance().is_active()) + // { + // this_thread::sleep_for(1s); + // } logger.log("GPS fix acquired, waiting for date change."); this_thread::sleep_for(2s); @@ -188,10 +188,12 @@ int main(void) } } + cout << "Stopping video" << endl; logger.log("Stopping video..."); Camera::get_instance().stop(); logger.log("Joining threads..."); + cout << "Joining threads" << endl; gps_thread.join(); logger.log("Finishing execution..."); return 0; From 97491c20d168415246bb6380fb7d17ca11b0e4ed Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 23:13:06 +0200 Subject: [PATCH 037/169] Added GSM logic --- constants.h | 2 ++ openstratos.cc | 68 ++++++++++++++++++++++++++++++++++++++++---------- openstratos.h | 1 + 3 files changed, 58 insertions(+), 13 deletions(-) diff --git a/constants.h b/constants.h index 376c2ff..1b39c4f 100644 --- a/constants.h +++ b/constants.h @@ -21,5 +21,7 @@ #define GSM_BAUDRATE 4800 #define GSM_ENDL "\r\n" + #define SMS_PHONE "" + #define STATE_FILE "data/last_state.txt" #endif // CONSTANTS_H_ diff --git a/openstratos.cc b/openstratos.cc index 38ec434..21f3e5c 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -80,15 +80,23 @@ int main(void) logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7549747200) + " hours of fullHD video."); - // logger.log("Turning on GPS..."); + logger.log("Turning on GPS..."); // if ( ! GPS::get_instance().initialize("")) // { // logger.log("GPS initialization error."); // exit(1); // } - // logger.log("GPS On."); + logger.log("GPS On."); // TODO start GSM and send message + logger.log("Turning on GSM..."); + // if ( ! GSM::get_instance().initialize(GSM_PWR_GPIO, GSM_STATUS_GPIO, GSM_UART)) + // { + // logger.log("GSM initialization error."); + // exit(1); + // } + // GSM::get_instance().turn_on(); + logger.log("GSM On."); logger.log("Starting camera recording..."); #ifndef RASPIVID @@ -142,7 +150,13 @@ int main(void) thread gps_thread(&gps_thread_fn, ref(state)); logger.log("GPS thread started."); - // TODO send SMS + logger.log("Sending initialization SMS..."); + // if ( ! GSM::get_instance().send_SMS("Initialization finished OK. Recording. Waiting for launch.", SMS_PHONE)) + // { + // logger.log("Error sending initialization SMS."); + // exit(1); + // } + logger.log("Initialization SMS sent."); state = set_state(WAITING_LAUNCH); logger.log("State changed to "+ state_to_string(state) +"."); @@ -162,6 +176,8 @@ int main(void) logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_UP: + // TODO send SMS at 1.5 km mark + // TODO turn off GSM // TODO detect burst this_thread::sleep_for(2s); logger.log("Balloon burst."); @@ -169,8 +185,8 @@ int main(void) logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_DOWN: - // TODO detect 3 km mark and send SMS - // TODO detect 1,5 km mark and send SMS + // TODO detect 2.5 km mark, turn on GSM and send SMS + // TODO detect 1.5 km mark and send SMS // TODO detect 500m mark and send SMS if not landed // TODO detect landing this_thread::sleep_for(2s); @@ -179,24 +195,50 @@ int main(void) logger.log("State changed to "+ state_to_string(state) +"."); break; case LANDED: - // TODO send SMS with position after 1 minute - // TODO send SMS with position after 15 minutes and shut down. - this_thread::sleep_for(2s); + logger.log("Stopping video..."); + Camera::get_instance().stop(); + + logger.log("Waiting 1 minute before sending landed SMS..."); + this_thread::sleep_for(1min); + + logger.log("Sending landed SMS..."); + // if ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + // { + // logger.log("Error sending landed SMS. Trying again in 15 minutes..."); + // } + // else + // { + // logger.log("Landed SMS sent. Sending backup SMS in 15 minutes..."); + // } + + this_thread::sleep_for(15min); + + logger.log("Sending second landed SMS..."); + + // while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + // { + // logger.log("Error sending second SMS, trying again in 5 minutes."); + // this_thread::sleep_for(5min); + // } + + logger.log("Second SMS sent."); + logger.log("Shutting down..."); state = set_state(SHUT_DOWN); logger.log("State changed to "+ state_to_string(state) +"."); } } - cout << "Stopping video" << endl; - logger.log("Stopping video..."); - Camera::get_instance().stop(); + logger.log("Turning GSM off..."); + // GSM::get_instance().turn_off(); + logger.log("GSM off."); logger.log("Joining threads..."); - cout << "Joining threads" << endl; gps_thread.join(); logger.log("Finishing execution..."); - return 0; + return 0; // Gives segmentation fault here } inline bool os::file_exists(const string& name) diff --git a/openstratos.h b/openstratos.h index 5f189e6..75fe6bd 100644 --- a/openstratos.h +++ b/openstratos.h @@ -16,6 +16,7 @@ #include "logger/Logger.h" #include "gps/GPS.h" #include "camera/Camera.h" +#include "gsm/GSM.h" namespace os { From b124ff7372bfde8523049998c79252fd758ac058 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 23:21:51 +0200 Subject: [PATCH 038/169] Uncommented success message --- openstratos.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index 21f3e5c..f00d7fb 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -209,7 +209,7 @@ int main(void) // } // else // { - // logger.log("Landed SMS sent. Sending backup SMS in 15 minutes..."); + logger.log("Landed SMS sent. Sending backup SMS in 15 minutes..."); // } this_thread::sleep_for(15min); From 7bdcac6f38fb9e008a13a0a3934ef5ecc3c59ba7 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 19 Jul 2015 23:50:05 +0200 Subject: [PATCH 039/169] Added off TODO --- openstratos.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/openstratos.cc b/openstratos.cc index f00d7fb..4d4502d 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -238,6 +238,7 @@ int main(void) logger.log("Joining threads..."); gps_thread.join(); logger.log("Finishing execution..."); + // TODO turn raspberry off return 0; // Gives segmentation fault here } From 9b4398e59fbd6190bffd9cd79f1b574557a99192 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 18:30:58 +0200 Subject: [PATCH 040/169] GPS added --- constants.h | 2 ++ openstratos.cc | 22 +++++++++++++--------- openstratos.h | 2 ++ 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/constants.h b/constants.h index 1b39c4f..46924a0 100644 --- a/constants.h +++ b/constants.h @@ -14,6 +14,8 @@ #define BAT_R1 3300 #define BAT_R2 4700 + #define GPS_UART "/dev/ttyAMA0" + #define GSM_LOC_SERV "gprs-service.com" #define GSM_UART "/dev/ttyAMA0" #define GSM_PWR_GPIO 4 diff --git a/openstratos.cc b/openstratos.cc index 4d4502d..e3d44a3 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -80,12 +80,16 @@ int main(void) logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7549747200) + " hours of fullHD video."); + logger.log("Initializing WiringPi..."); + wiringPiSetup(); + logger.log("WiringPi initialized."); + logger.log("Turning on GPS..."); - // if ( ! GPS::get_instance().initialize("")) - // { - // logger.log("GPS initialization error."); - // exit(1); - // } + if ( ! GPS::get_instance().initialize(GPS_UART)) + { + logger.log("GPS initialization error."); + exit(1); + } logger.log("GPS On."); // TODO start GSM and send message @@ -132,10 +136,10 @@ int main(void) state = set_state(ACQUIRING_FIX); logger.log("State changed to "+ state_to_string(state) +"."); - // while ( ! GPS::get_instance().is_active()) - // { - // this_thread::sleep_for(1s); - // } + while ( ! GPS::get_instance().is_active()) + { + this_thread::sleep_for(1s); + } logger.log("GPS fix acquired, waiting for date change."); this_thread::sleep_for(2s); diff --git a/openstratos.h b/openstratos.h index 75fe6bd..9643221 100644 --- a/openstratos.h +++ b/openstratos.h @@ -11,6 +11,8 @@ #include #include +#include + #include "config.h" #include "constants.h" #include "logger/Logger.h" From d77d7c692b57c91bbb865f73de6a6f302dfdd6f3 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 18:36:14 +0200 Subject: [PATCH 041/169] Fixed configure script --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 9244376..8d135c9 100644 --- a/configure.ac +++ b/configure.ac @@ -12,11 +12,13 @@ AC_PROG_CXX AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET -AC_CHECK_PROG(RASPIVID, raspivid, yes) +AC_CHECK_PROG([RASPIVID], [raspivid], [yes]) +AS_IF([test "x$RASPIVID" = xyes], + [AC_DEFINE([HAVE_RASPIVID], [1], [raspivid is available.])]) # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) -AC_CHECK_LIB([wiringPi], [wiringPiSetupSys]) +AC_CHECK_LIB([wiringPi], [wiringPiSetup]) # Checks for header files. AC_CHECK_HEADERS([string.h]) From 6bd326fd8447287c994d07fa4c6c42b5ef64b72c Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 18:51:20 +0200 Subject: [PATCH 042/169] Fixed configure script --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 8d135c9..725dc9a 100644 --- a/configure.ac +++ b/configure.ac @@ -12,9 +12,9 @@ AC_PROG_CXX AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET -AC_CHECK_PROG([RASPIVID], [raspivid], [yes]) -AS_IF([test "x$RASPIVID" = xyes], - [AC_DEFINE([HAVE_RASPIVID], [1], [raspivid is available.])]) +AC_CHECK_PROG([HAVE_RASPIVID], [raspivid], [yes]) +AS_IF([test "x$HAVE_RASPIVID" = xyes], + [AC_DEFINE([RASPIVID], [1], [raspivid is available.])]) # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) From f931ea2032592320fbf7558fabc5d9299db60d22 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 19:28:47 +0200 Subject: [PATCH 043/169] Fixed camera tests and debugging serial --- config.h | 3 +++ configure.ac | 2 +- gps/GPS.h | 2 ++ openstratos.cc | 8 ++++---- serial/Serial.cc | 4 ++++ testing/camera_test.cc | 6 +++--- 6 files changed, 17 insertions(+), 8 deletions(-) diff --git a/config.h b/config.h index 308566b..a3b9ebc 100644 --- a/config.h +++ b/config.h @@ -67,6 +67,9 @@ /* Define to the version of this package. */ #define PACKAGE_VERSION "Alpha-1-dev" +/* Define to 1 if you have raspivid available. */ +/* #undef RASPIVID */ + /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 diff --git a/configure.ac b/configure.ac index 725dc9a..4381e48 100644 --- a/configure.ac +++ b/configure.ac @@ -14,7 +14,7 @@ AC_PROG_INSTALL AC_PROG_MAKE_SET AC_CHECK_PROG([HAVE_RASPIVID], [raspivid], [yes]) AS_IF([test "x$HAVE_RASPIVID" = xyes], - [AC_DEFINE([RASPIVID], [1], [raspivid is available.])]) + [AC_DEFINE([RASPIVID], [1], [Define to 1 if you have raspivid available.])]) # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) diff --git a/gps/GPS.h b/gps/GPS.h index 1b17d92..327489a 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -59,6 +59,8 @@ namespace os { bool initialize(const string& serial_URL); uint_fast8_t parse(const string& frame); + + // TODO Turn ON and OFF }; } diff --git a/openstratos.cc b/openstratos.cc index e3d44a3..0687cae 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -84,23 +84,23 @@ int main(void) wiringPiSetup(); logger.log("WiringPi initialized."); - logger.log("Turning on GPS..."); + logger.log("Initializing GPS..."); if ( ! GPS::get_instance().initialize(GPS_UART)) { logger.log("GPS initialization error."); exit(1); } - logger.log("GPS On."); + logger.log("GPS initialized."); // TODO start GSM and send message - logger.log("Turning on GSM..."); + logger.log("Initializing GSM..."); // if ( ! GSM::get_instance().initialize(GSM_PWR_GPIO, GSM_STATUS_GPIO, GSM_UART)) // { // logger.log("GSM initialization error."); // exit(1); // } // GSM::get_instance().turn_on(); - logger.log("GSM On."); + logger.log("GSM initialized."); logger.log("Starting camera recording..."); #ifndef RASPIVID diff --git a/serial/Serial.cc b/serial/Serial.cc index fdb0016..aeb0f73 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -6,6 +6,8 @@ #include #include +#include + #include using namespace std; @@ -76,6 +78,8 @@ void Serial::serial_thread() { response = response.substr(0, response.length()-endl.length()); + cout << "Received serial line:" << endl << response << endl; + this->listener(response); response = ""; endl_pos = 0; diff --git a/testing/camera_test.cc b/testing/camera_test.cc index e03b606..4311d35 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -1,10 +1,10 @@ describe("Camera", [](){ it("recording test", [&](){ - Camera::get_instance().record(200); + Camera::get_instance().record(2000); AssertThat(Camera::get_instance().is_recording(), Equals(true)); - this_thread::sleep_for(250ms); + this_thread::sleep_for(2.5s); AssertThat(Camera::get_instance().is_recording(), Equals(false)); }); @@ -12,7 +12,7 @@ describe("Camera", [](){ Camera::get_instance().record(); AssertThat(Camera::get_instance().is_recording(), Equals(true)); - this_thread::sleep_for(200ms); + this_thread::sleep_for(2s); Camera::get_instance().stop(); AssertThat(Camera::get_instance().is_recording(), Equals(false)); }); From c9061e60ca82676136bc69ebca389910f51be10d Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 19:30:32 +0200 Subject: [PATCH 044/169] Removed config.h file, it's automatically generated. --- .gitignore | 1 + config.h | 89 ------------------------------------------------------ 2 files changed, 1 insertion(+), 89 deletions(-) delete mode 100644 config.h diff --git a/.gitignore b/.gitignore index 4482287..d4b04de 100644 --- a/.gitignore +++ b/.gitignore @@ -31,6 +31,7 @@ openstratosRoot utesting Makefile data +config.h # http://www.gnu.org/software/automake diff --git a/config.h b/config.h deleted file mode 100644 index a3b9ebc..0000000 --- a/config.h +++ /dev/null @@ -1,89 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to 1 if you have the `alarm' function. */ -#define HAVE_ALARM 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#define HAVE_LIBPTHREAD 1 - -/* Define to 1 if you have the `wiringPi' library (-lwiringPi). */ -#define HAVE_LIBWIRINGPI 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the `stpcpy' function. */ -#define HAVE_STPCPY 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if you have the `strstr' function. */ -#define HAVE_STRSTR 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Name of package */ -#define PACKAGE "openstratos" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "https://openstratos.org/bugtracker" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "OpenStratos" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "OpenStratos Alpha-1-dev" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "openstratos" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "Alpha-1-dev" - -/* Define to 1 if you have raspivid available. */ -/* #undef RASPIVID */ - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Version number of package */ -#define VERSION "Alpha-1-dev" - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -/* #undef inline */ -#endif - -/* Define to `unsigned int' if does not define. */ -/* #undef size_t */ From 2edd05146eae426bdffeada0a06549905a76dfc8 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 20:04:58 +0200 Subject: [PATCH 045/169] Trying to fix GPS --- camera/Camera.cc | 14 ++++++++------ camera/Camera.h | 6 +++--- constants.h | 3 +++ gps/GPS.cc | 2 +- serial/Serial.cc | 20 ++++++++++---------- serial/Serial.h | 5 ++--- testing/serial_test.cc | 2 -- testing/testing.cc | 1 - 8 files changed, 27 insertions(+), 26 deletions(-) delete mode 100644 testing/serial_test.cc diff --git a/camera/Camera.cc b/camera/Camera.cc index 6df1f55..77c2ba7 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -32,7 +32,7 @@ void Camera::record_thread(int time) this->recording = false; } -void Camera::record(int time) +bool Camera::record(int time) { if ( ! this->recording) { @@ -50,7 +50,7 @@ void Camera::record(int time) command = ""; #endif - system(command.c_str()); + int st = system(command.c_str()); this->recording = true; if (time > 0) @@ -58,18 +58,20 @@ void Camera::record(int time) thread t(&Camera::record_thread, this, time); t.detach(); } + + return st == 0; } } -void Camera::record() +bool Camera::record() { - this->record(0); + return this->record(0); } -void Camera::stop() +bool Camera::stop() { - system("pkill raspivid"); this->recording = false; + return system("pkill raspivid") == 0; } int os::get_file_count(const string& path) diff --git a/camera/Camera.h b/camera/Camera.h index de6b350..9a84caa 100644 --- a/camera/Camera.h +++ b/camera/Camera.h @@ -19,9 +19,9 @@ namespace os { Camera(Camera& copy) = delete; static Camera& get_instance(); - void record(int time); - void record(); - void stop(); + bool record(int time); + bool record(); + bool stop(); bool is_recording() const {return this->recording;} }; diff --git a/constants.h b/constants.h index 46924a0..0953c0c 100644 --- a/constants.h +++ b/constants.h @@ -15,6 +15,9 @@ #define BAT_R2 4700 #define GPS_UART "/dev/ttyAMA0" + #define GPS_ENABLE_GPIO 4 + #define GPS_BAUDRATE 4800 + #define GPS_ENDL "\r\n" #define GSM_LOC_SERV "gprs-service.com" #define GSM_UART "/dev/ttyAMA0" diff --git a/gps/GPS.cc b/gps/GPS.cc index d7a13b5..e0b48ba 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -50,7 +50,7 @@ bool GPS::initialize(const string& serial_URL) to_string(now->tm_sec) +".log", "GPS"); this->logger->log("Starting serial connection..."); - if ( ! this->serial.initialize(serial_URL, 9600, "\r\n", bind(&GPS::parse, this, placeholders::_1))) { + if ( ! this->serial.initialize_GPS()) { this->logger->log("GPS serial error."); return false; } else { diff --git a/serial/Serial.cc b/serial/Serial.cc index aeb0f73..d06bd6c 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -10,15 +10,17 @@ #include +#include "constants.h" +#include "gps/GPS.h" + using namespace std; using namespace os; -bool Serial::initialize(const string& url, int baud, const string endl, function) +bool Serial::initialize_GPS() { - this->listener = listener; - this->endl = endl; + this->endl = GPS_ENDL; #ifndef OS_TESTING - this->fd = serialOpen(url.c_str(), baud); + this->fd = serialOpen(GPS_UART, GPS_BAUDRATE); if (this->fd == -1) { this->open = false; @@ -29,7 +31,7 @@ bool Serial::initialize(const string& url, int baud, const string endl, function this->open = true; this->stopped = false; - thread t(&Serial::serial_thread, this); + thread t(&Serial::gps_thread, this); t.detach(); return true; @@ -57,7 +59,7 @@ Serial::~Serial() this->close(); } -void Serial::serial_thread() +void Serial::gps_thread() { string response; int endl_pos = 0; @@ -76,11 +78,9 @@ void Serial::serial_thread() if (c == this->endl[endl_pos]) ++endl_pos; if (endl_pos == this->endl.length()) { - response = response.substr(0, response.length()-endl.length()); - - cout << "Received serial line:" << endl << response << endl; + response = response.substr(response.find("$"), response.length()-endl.length()); - this->listener(response); + GPS::get_instance().parse(response); response = ""; endl_pos = 0; this_thread::sleep_for(50ms); diff --git a/serial/Serial.h b/serial/Serial.h index 5265128..46d3f83 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -13,12 +13,11 @@ namespace os { { private: int fd; - function listener; atomic_bool open; atomic_bool stopped; string endl; - void serial_thread(); + void gps_thread(); public: Serial() = default; Serial(Serial& copy) = delete; @@ -27,7 +26,7 @@ namespace os { void send(const string& str) const; void close(); bool is_open(); - bool initialize(const string& serial_URL, int baud, const string endl, function); + bool initialize_GPS(); bool initialize(const string& serial_URL, int baud); const string read_line() const; void flush() const; diff --git a/testing/serial_test.cc b/testing/serial_test.cc deleted file mode 100644 index 329c021..0000000 --- a/testing/serial_test.cc +++ /dev/null @@ -1,2 +0,0 @@ -describe("Serial", [](){ -}); diff --git a/testing/testing.cc b/testing/testing.cc index f4e9cf8..a138aad 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -23,7 +23,6 @@ int main(int argc, char* argv[]) go_bandit([](){ #include "camera_test.cc" - #include "serial_test.cc" #include "gps_test.cc" #include "temperature_test.cc" #include "battery_test.cc" From 482d30f6ba8fcf98a3a1aa1f700d1d0cc6af2e99 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 20:21:24 +0200 Subject: [PATCH 046/169] Removed unused files from makefile --- Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 122f86e..071d887 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = openstratos -openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc gsm/GSM.cc logger/Logger.cc +openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc openstratos_LDADD = -lwiringPi openstratos_CPPFLAGS = -std=c++14 From c034a34c960b3c8a1df803cd5220561ff5b0b211 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 20:23:32 +0200 Subject: [PATCH 047/169] Fixing GPS serial --- serial/Serial.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index d06bd6c..5c8c4ea 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -78,7 +78,8 @@ void Serial::gps_thread() if (c == this->endl[endl_pos]) ++endl_pos; if (endl_pos == this->endl.length()) { - response = response.substr(response.find("$"), response.length()-endl.length()); + response = response.substr(response.find("$") > 0 ? response.find("$") : 0, + response.length()-endl.length()); GPS::get_instance().parse(response); response = ""; From 53e8f3f8fb7b1a3e730f8adcfea80a9cc3a22b75 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 20:27:32 +0200 Subject: [PATCH 048/169] It was still failing --- serial/Serial.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index 5c8c4ea..40baa20 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -78,7 +78,9 @@ void Serial::gps_thread() if (c == this->endl[endl_pos]) ++endl_pos; if (endl_pos == this->endl.length()) { - response = response.substr(response.find("$") > 0 ? response.find("$") : 0, + response = response.substr(response.find("$") > 0 && + response.find("$") < response.length() + ? response.find("$") : 0, response.length()-endl.length()); GPS::get_instance().parse(response); From 75da2065f5fe45728512ba0cf56833b00bfff708 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 21:18:49 +0200 Subject: [PATCH 049/169] Fixed baudrate for GPS --- constants.h | 4 ++-- openstratos.cc | 17 +++++++++++++---- serial/Serial.cc | 12 +++++------- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/constants.h b/constants.h index 0953c0c..557de40 100644 --- a/constants.h +++ b/constants.h @@ -15,8 +15,8 @@ #define BAT_R2 4700 #define GPS_UART "/dev/ttyAMA0" - #define GPS_ENABLE_GPIO 4 - #define GPS_BAUDRATE 4800 + // #define GPS_ENABLE_GPIO 6 + #define GPS_BAUDRATE 9600 #define GPS_ENDL "\r\n" #define GSM_LOC_SERV "gprs-service.com" diff --git a/openstratos.cc b/openstratos.cc index 0687cae..89039f6 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -108,7 +108,11 @@ int main(void) exit(1); #endif logger.log("Recording 10 seconds as test..."); - Camera::get_instance().record(10000); + if ( ! Camera::get_instance().record(10000)) + { + logger.log("Error starting recording"); + exit(1); + } this_thread::sleep_for(11s); Camera::get_instance().stop(); @@ -131,9 +135,6 @@ int main(void) exit(1); } - logger.log("Starting video recording..."); - Camera::get_instance().record(); - state = set_state(ACQUIRING_FIX); logger.log("State changed to "+ state_to_string(state) +"."); while ( ! GPS::get_instance().is_active()) @@ -150,6 +151,14 @@ int main(void) logger.log("System date change."); + logger.log("Starting video recording..."); + if ( ! Camera::get_instance().record()) + { + logger.log("Error starting recording"); + exit(1); + } + logger.log("Recording started."); + logger.log("Starting GPS Thread..."); thread gps_thread(&gps_thread_fn, ref(state)); logger.log("GPS thread started."); diff --git a/serial/Serial.cc b/serial/Serial.cc index 40baa20..4c5dba5 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -6,8 +6,6 @@ #include #include -#include - #include #include "constants.h" @@ -78,12 +76,12 @@ void Serial::gps_thread() if (c == this->endl[endl_pos]) ++endl_pos; if (endl_pos == this->endl.length()) { - response = response.substr(response.find("$") > 0 && - response.find("$") < response.length() - ? response.find("$") : 0, - response.length()-endl.length()); + response = response.substr(0, response.length()-endl.length()); - GPS::get_instance().parse(response); + if (response.at(0) == '$') + { + GPS::get_instance().parse(response); + } response = ""; endl_pos = 0; this_thread::sleep_for(50ms); From 08f4418e3fc95ff8dd4b8919802c43501e19455d Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 23:04:46 +0200 Subject: [PATCH 050/169] All logic added except for recovery and some error control --- gps/GPS.cc | 4 ++ logger/Logger.cc | 3 +- openstratos.cc | 141 +++++++++++++++++++++++++++++++++++++++++------ openstratos.h | 5 ++ 4 files changed, 136 insertions(+), 17 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index e0b48ba..1b6c85d 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -62,8 +62,12 @@ bool GPS::initialize(const string& serial_URL) } #ifndef OS_TESTING + this->logger->log("Sending configuration frames..."); this->serial.send("$PMTK220,100*2F"); + this->frame_logger->log("Sent: $PMTK220,100*2F"); this->serial.send("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->frame_logger->log("Sent: $PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->logger->log("Configuration frames sent."); #endif } diff --git a/logger/Logger.cc b/logger/Logger.cc index bc17e3d..2ca1bd3 100644 --- a/logger/Logger.cc +++ b/logger/Logger.cc @@ -30,5 +30,6 @@ void Logger::log(const string& message) this->log_stream << "[" << log_prefix << "] - " << setfill('0') << setw(2) << now->tm_mon << "/" << setfill('0') << setw(2) << now->tm_mday << "/" << (now->tm_year+1900) << " " << setfill('0') << setw(2) << now->tm_hour << ":" << setfill('0') << setw(2) << now->tm_min << ":" << - setfill('0') << setw(2) << now->tm_sec << "." << timer.tv_usec << " - " << message << endl; + setfill('0') << setw(2) << now->tm_sec << "." << setfill('0') << setw(6) << timer.tv_usec << + " - " << message << endl; } diff --git a/openstratos.cc b/openstratos.cc index 89039f6..2f4df08 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -181,28 +181,104 @@ int main(void) switch (state) { case WAITING_LAUNCH: - // TODO detect launch - this_thread::sleep_for(2s); + while ( ! has_launched()); logger.log("Balloon launched."); - // TODO send SMS + + logger.log("Trying to send launch confirmation SMS..."); + // if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ + // to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ + // to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + // { + // logger.log("Error sending launch confirmation SMS."); + // } + // else + // { + logger.log("Launch confirmation SMS sent."); + // } + state = set_state(GOING_UP); logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_UP: - // TODO send SMS at 1.5 km mark - // TODO turn off GSM - // TODO detect burst - this_thread::sleep_for(2s); + while (GPS::get_instance().get_altitude() < 1500) + { + this_thread::sleep_for(2s); + } + logger.log("1.5 km mark."); + logger.log("Trying to send \"going up\" SMS..."); + // if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ + // to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ + // to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + // { + // logger.log("Error sending \"going up\" SMS."); + // } + // else + // { + logger.log("\"Going up\" SMS sent."); + // } + + logger.log("Turning off GSM..."); + // GSM::get_instance().turn_off(); + logger.log("GSM off."); + + while ( ! has_bursted()); logger.log("Balloon burst."); state = set_state(GOING_DOWN); logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_DOWN: - // TODO detect 2.5 km mark, turn on GSM and send SMS - // TODO detect 1.5 km mark and send SMS - // TODO detect 500m mark and send SMS if not landed - // TODO detect landing - this_thread::sleep_for(2s); + while (GPS::get_instance().get_altitude() > 2500) + { + this_thread::sleep_for(10s); + } + logger.log("2.5 km mark."); + logger.log("Turning on GSM..."); + // GSM::get_instance().turn_on(); + logger.log("GSM on."); + logger.log("Trying to send first SMS..."); + // if ( ! GSM::get_instance().send_SMS("2.5 km mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + // { + // logger.log("Error sending first SMS."); + // } + // else + // { + logger.log("First SMS sent."); + // } + + while (GPS::get_instance().get_altitude() > 1500) + { + this_thread::sleep_for(5s); + } + logger.log("1.5 km mark."); + logger.log("Trying to send second SMS..."); + // if ( ! GSM::get_instance().send_SMS("1.5 km mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + // { + // logger.log("Error sending second SMS."); + // } + // else + // { + logger.log("Second SMS sent."); + // } + + while ( ! has_landed() && GPS::get_instance().get_altitude() > 500); + if ( ! has_landed()) + { + logger.log("500 m mark."); + logger.log("Trying to send third SMS..."); + // if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + // { + // logger.log("Error sending third SMS."); + // } + // else + // { + logger.log("Third SMS sent."); + // } + } + + while ( ! has_landed()); logger.log("Landed."); state = set_state(LANDED); logger.log("State changed to "+ state_to_string(state) +"."); @@ -250,9 +326,12 @@ int main(void) logger.log("Joining threads..."); gps_thread.join(); - logger.log("Finishing execution..."); - // TODO turn raspberry off - return 0; // Gives segmentation fault here + logger.log("Threads joined."); + + logger.log("Powering off..."); + sync(); + //reboot(RB_POWER_OFF); + return 0; } inline bool os::file_exists(const string& name) @@ -279,7 +358,7 @@ void os::gps_thread_fn(State& state) to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPSPosition"); - while (state != LANDED) { + while (state != SHUT_DOWN) { logger.log("Lat: "+ to_string(GPS::get_instance().get_latitude()) +", Lon: "+ to_string(GPS::get_instance().get_longitude()) +", Alt: "+ to_string(GPS::get_instance().get_altitude()) +", Speed: "+ @@ -328,3 +407,33 @@ string os::state_to_string(State state) return "SHUT_DOWN"; } } + +bool os::has_launched() +{ + double first_altitude = GPS::get_instance().get_altitude(); + this_thread::sleep_for(3s); + double second_altitude = GPS::get_instance().get_altitude(); + + return true; + // return second_altitude > first_altitude + 10; +} + +bool os::has_bursted() +{ + double first_altitude = GPS::get_instance().get_altitude(); + this_thread::sleep_for(3s); + double second_altitude = GPS::get_instance().get_altitude(); + + return true; + // return second_altitude < first_altitude - 15; +} + +bool os::has_landed() +{ + double first_altitude = GPS::get_instance().get_altitude(); + this_thread::sleep_for(5s); + double second_altitude = GPS::get_instance().get_altitude(); + + return true; + // return first_altitude-second_altitude < 5; +} diff --git a/openstratos.h b/openstratos.h index 9643221..1483b7e 100644 --- a/openstratos.h +++ b/openstratos.h @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include @@ -37,6 +39,9 @@ namespace os void gps_thread_fn(State& state); State set_state(State new_state); string state_to_string(State state); + bool has_launched(); + bool has_bursted(); + bool has_landed(); } using namespace std; From 444849c211bc2b3513cdca435931002b9f737e59 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 23:15:43 +0200 Subject: [PATCH 051/169] Readme polished. --- .travis.yml | 2 -- README | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 1b624c1..4a22ace 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,8 +26,6 @@ notifications: email: recipients: - iban.eguia@opendeusto.es - - jordan.aranda@me.com - - aritzbilbao@deusto.es - eneko.cruz@opendeusto.es on_success: change on_failure: always diff --git a/README b/README index 80f7c34..4b2ff08 100644 --- a/README +++ b/README @@ -2,4 +2,4 @@ [![Build Status](https://travis-ci.org/OpenStratos/server.svg?branch=develop)](https://travis-ci.org/OpenStratos/server) -Server implemented in C++11. It will be in charge of the management of the balloon. +Server implemented in C++14. It will be in charge of the management of the balloon. From ff8640e922e434518d947e76765ac663495fbf72 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 23:24:34 +0200 Subject: [PATCH 052/169] Improved camera tests --- openstratos.cc | 3 +-- testing/camera_test.cc | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 2f4df08..0af0460 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -76,7 +76,6 @@ int main(void) exit(1); } - // ~115 MiB per minute logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7549747200) + " hours of fullHD video."); @@ -102,7 +101,7 @@ int main(void) // GSM::get_instance().turn_on(); logger.log("GSM initialized."); - logger.log("Starting camera recording..."); + logger.log("Testing camera recording..."); #ifndef RASPIVID logger.log("Error: No raspivid found. Is this a Raspberry?"); exit(1); diff --git a/testing/camera_test.cc b/testing/camera_test.cc index 2bdcece..eb1c71b 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -19,13 +19,14 @@ describe("Camera", [](){ #ifdef RASPIVID it("file creation test", [&](){ - Camera::get_instance().record(10); + Camera::get_instance().record(10000); this_thread::sleep_for(chrono::seconds(11)); struct stat buf; - int result = stat("os_video.h264", &buf); + int result = stat("data/video/test.h264", &buf); AssertThat(result, Equals(0)); + remove("data/video/test.h264"); }); #else it_skip("file creation test", [&](){}); From c23aa1d18ae667c293375b53f38c7862722e3ca2 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 23:28:42 +0200 Subject: [PATCH 053/169] Updated bandit --- testing/bandit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/bandit b/testing/bandit index dbcfc1a..a856864 160000 --- a/testing/bandit +++ b/testing/bandit @@ -1 +1 @@ -Subproject commit dbcfc1a59319ea7733d6f393b99807a0903b6fbe +Subproject commit a8568640859b1a15e8d6b0a7b9d42c9d6806088d From 54cd7e26bf4a2f160aa3449638c8ebac789b2971 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 23:34:14 +0200 Subject: [PATCH 054/169] Trying to fix build --- configure.ac | 1 - 1 file changed, 1 deletion(-) diff --git a/configure.ac b/configure.ac index 60627b2..4ff814f 100644 --- a/configure.ac +++ b/configure.ac @@ -27,7 +27,6 @@ AC_LANG([C++]) AX_CXX_COMPILE_STDCXX_11() # Checks for typedefs, structures, and compiler characteristics. -AC_CHECK_HEADER_STDBOOL AC_C_INLINE AC_TYPE_SIZE_T From 03d740dbf8112c58c581663827092c6d962030d4 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 20 Jul 2015 23:48:52 +0200 Subject: [PATCH 055/169] Fixing build in Raspberry --- openstratos-root.cc | 8 -------- openstratos.cc | 2 +- testing/testing.cc | 3 ++- 3 files changed, 3 insertions(+), 10 deletions(-) delete mode 100644 openstratos-root.cc diff --git a/openstratos-root.cc b/openstratos-root.cc deleted file mode 100644 index fab1860..0000000 --- a/openstratos-root.cc +++ /dev/null @@ -1,8 +0,0 @@ -#include "openstratos.h" - -int main(void) -{ - cout << "[OpenStratos][ROOT] Starting" << endl; - cout << "[OpenStratos][ROOT] Starting checks (not really)" << endl; - return 0; -} \ No newline at end of file diff --git a/openstratos.cc b/openstratos.cc index 0af0460..af66acb 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -336,7 +336,7 @@ int main(void) inline bool os::file_exists(const string& name) { struct stat buffer; - return (stat (name.c_str(), &buffer) == 0); + return stat(name.c_str(), &buffer) == 0; } inline float os::get_available_disk_space() diff --git a/testing/testing.cc b/testing/testing.cc index a138aad..5f38fc4 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -1,11 +1,12 @@ #include +#include + #include #include "config.h" #include "constants.h" -#include "serial/Serial.h" #include "camera/Camera.h" #include "temperature/Temperature.h" #include "gps/GPS.h" From 1fa4ca6cbfa1aaf377ee2d8fd4d3587246971749 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 21 Jul 2015 00:05:04 +0200 Subject: [PATCH 056/169] Removed unused autogen.sh --- autogen.sh | 6 ------ 1 file changed, 6 deletions(-) delete mode 100755 autogen.sh diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 86f4f99..0000000 --- a/autogen.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -aclocal --install -I m4 && - autoreconf && - automake --add-missing --copy && - ./configure "$@" \ No newline at end of file From 938a244467e8b58b16cb4e7361daf1889bd67a20 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 21 Jul 2015 00:31:58 +0200 Subject: [PATCH 057/169] Commented some logic to be able to test it --- openstratos.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index af66acb..f366ab5 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -199,10 +199,10 @@ int main(void) logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_UP: - while (GPS::get_instance().get_altitude() < 1500) - { + // while (GPS::get_instance().get_altitude() < 1500) + // { this_thread::sleep_for(2s); - } + // } logger.log("1.5 km mark."); logger.log("Trying to send \"going up\" SMS..."); // if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ @@ -226,10 +226,10 @@ int main(void) logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_DOWN: - while (GPS::get_instance().get_altitude() > 2500) - { + // while (GPS::get_instance().get_altitude() > 2500) + // { this_thread::sleep_for(10s); - } + // } logger.log("2.5 km mark."); logger.log("Turning on GSM..."); // GSM::get_instance().turn_on(); @@ -245,10 +245,10 @@ int main(void) logger.log("First SMS sent."); // } - while (GPS::get_instance().get_altitude() > 1500) - { + // while (GPS::get_instance().get_altitude() > 1500) + // { this_thread::sleep_for(5s); - } + // } logger.log("1.5 km mark."); logger.log("Trying to send second SMS..."); // if ( ! GSM::get_instance().send_SMS("1.5 km mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) From e806d9b778dac93990cbef8bb5e61f647986d8a5 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 21 Jul 2015 00:38:55 +0200 Subject: [PATCH 058/169] Better GPS logging and recording stop flag. --- openstratos.cc | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index f366ab5..5a7508b 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -284,7 +284,16 @@ int main(void) break; case LANDED: logger.log("Stopping video..."); - Camera::get_instance().stop(); + if ( ! Camera::get_instance().stop()) + { + logger.log("Error stopping video."); + // TODO try again? + } + else + { + logger.log("Video stopped.") + } + logger.log("Waiting 1 minute before sending landed SMS..."); this_thread::sleep_for(1min); @@ -367,7 +376,7 @@ void os::gps_thread_fn(State& state) to_string(GPS::get_instance().get_HDOP()) +", VDOP: "+ to_string(GPS::get_instance().get_VDOP())); - this_thread::sleep_for(50ms); + this_thread::sleep_for(100ms); } } From ad2bf2fdb06765544b1592e8fb41496e3fe1e84e Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 21 Jul 2015 00:41:08 +0200 Subject: [PATCH 059/169] There were too many repeated logs. --- openstratos.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index 5a7508b..0979969 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -376,7 +376,7 @@ void os::gps_thread_fn(State& state) to_string(GPS::get_instance().get_HDOP()) +", VDOP: "+ to_string(GPS::get_instance().get_VDOP())); - this_thread::sleep_for(100ms); + this_thread::sleep_for(250ms); } } From 1086d97425b5e3b18bb1950053cda8c2d1cdeaa5 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 21 Jul 2015 00:46:59 +0200 Subject: [PATCH 060/169] 15 minutes was too much --- openstratos.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 0979969..c64052e 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -302,14 +302,14 @@ int main(void) // if ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) // { - // logger.log("Error sending landed SMS. Trying again in 15 minutes..."); + // logger.log("Error sending landed SMS. Trying again in 10 minutes..."); // } // else // { - logger.log("Landed SMS sent. Sending backup SMS in 15 minutes..."); + logger.log("Landed SMS sent. Sending backup SMS in 10 minutes..."); // } - this_thread::sleep_for(15min); + this_thread::sleep_for(10min); logger.log("Sending second landed SMS..."); From 38ca2fdfde1a9cbcfe0043afad229c9c02f02977 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 21 Jul 2015 00:56:37 +0200 Subject: [PATCH 061/169] GPS was not being correctly configured. --- gps/GPS.cc | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index 1b6c85d..b552900 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -58,17 +58,18 @@ bool GPS::initialize(const string& serial_URL) this->frame_logger = new Logger("data/logs/GPS/GPSFrames."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPS Frame"); + + #ifndef OS_TESTING + this->logger->log("Sending configuration frames..."); + this->serial.send("$PMTK220,100*2F"); + this->frame_logger->log("Sent: $PMTK220,100*2F"); + this->serial.send("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->frame_logger->log("Sent: $PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->logger->log("Configuration frames sent."); + #endif + return true; } - - #ifndef OS_TESTING - this->logger->log("Sending configuration frames..."); - this->serial.send("$PMTK220,100*2F"); - this->frame_logger->log("Sent: $PMTK220,100*2F"); - this->serial.send("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); - this->frame_logger->log("Sent: $PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); - this->logger->log("Configuration frames sent."); - #endif } bool GPS::is_valid(string frame) From a4eb627e26bd6c5daee5e2357aca886f62027653 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 23 Jul 2015 13:46:11 +0200 Subject: [PATCH 062/169] Added more options to camera --- camera/Camera.cc | 12 +++++++++--- constants.h | 10 ++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 77c2ba7..832db98 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -11,6 +11,7 @@ #include #include "config.h" +#include "constants.h" using namespace os; using namespace std; @@ -44,7 +45,8 @@ bool Camera::record(int time) else { command = "raspivid -o data/video/video-"+ to_string(get_file_count("data/video/")) - +".h264 -t " + to_string(time) + " &"; + +".h264 -t " + to_string(time) + " -w "+ to_string(VIDEO_WIDTH) +" -h "+ to_string(VIDEO_HEIGHT) + +" -b "+ to_string(VIDEO_BITRATE*1000000) +" -fps "+ to_string(VIDEO_FPS) +" &"; } #ifndef RASPIVID command = ""; @@ -70,8 +72,12 @@ bool Camera::record() bool Camera::stop() { - this->recording = false; - return system("pkill raspivid") == 0; + if (system("pkill raspivid") == 0) + { + this->recording = false; + return true; + } + return false; } int os::get_file_count(const string& path) diff --git a/constants.h b/constants.h index 557de40..5866271 100644 --- a/constants.h +++ b/constants.h @@ -14,6 +14,16 @@ #define BAT_R1 3300 #define BAT_R2 4700 + #define VIDEO_WIDTH 1920 + #define VIDEO_HEIGHT 1080 + #define VIDEO_BITRATE 17 //Mbps + #define VIDEO_FPS 30 + + // #define PHOTO_WIDTH 2592 + // #define PHOTO_HEIGHT 1944 + // #define PHOTO_QUALITY 90 + // #define PHOTO_RAW 0 + #define GPS_UART "/dev/ttyAMA0" // #define GPS_ENABLE_GPIO 6 #define GPS_BAUDRATE 9600 From a4e7b61b96cd7b7981c06e6ee1d3da527a9d4119 Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 24 Jul 2015 00:06:13 +0200 Subject: [PATCH 063/169] Fixed small issues --- camera/Camera.cc | 13 +++++--- logger/Logger.cc | 1 - openstratos.cc | 3 +- serial/Serial.cc | 72 ++++++++++++++++++------------------------ serial/Serial.h | 1 - testing/camera_test.cc | 1 + testing/testing.cc | 1 + 7 files changed, 43 insertions(+), 49 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 832db98..64f3815 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -72,12 +72,17 @@ bool Camera::record() bool Camera::stop() { - if (system("pkill raspivid") == 0) - { + #ifdef RASPIVID + if (system("pkill raspivid") == 0) + { + this->recording = false; + return true; + } + return false; + #else this->recording = false; return true; - } - return false; + #endif } int os::get_file_count(const string& path) diff --git a/logger/Logger.cc b/logger/Logger.cc index 2ca1bd3..3d905ad 100644 --- a/logger/Logger.cc +++ b/logger/Logger.cc @@ -1,7 +1,6 @@ #include "logger/Logger.h" #include -#include #include #include diff --git a/openstratos.cc b/openstratos.cc index c64052e..e25e0a2 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -291,10 +291,9 @@ int main(void) } else { - logger.log("Video stopped.") + logger.log("Video stopped."); } - logger.log("Waiting 1 minute before sending landed SMS..."); this_thread::sleep_for(1min); diff --git a/serial/Serial.cc b/serial/Serial.cc index 4c5dba5..77ce670 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -16,7 +16,6 @@ using namespace os; bool Serial::initialize_GPS() { - this->endl = GPS_ENDL; #ifndef OS_TESTING this->fd = serialOpen(GPS_UART, GPS_BAUDRATE); @@ -25,12 +24,15 @@ bool Serial::initialize_GPS() this->stopped = true; return false; } - #endif - this->open = true; - this->stopped = false; - thread t(&Serial::gps_thread, this); - t.detach(); + this->open = true; + this->stopped = false; + thread t(&Serial::gps_thread, this); + t.detach(); + #else + this->open = false; + this->stopped = true; + #endif return true; } @@ -64,46 +66,15 @@ void Serial::gps_thread() while(this->open) { - #ifndef OS_TESTING - int available = serialDataAvail(this->fd); - - if (available > 0) - { - for (int i = 0; i < available; i++) - { - char c = serialGetchar(this->fd); - response += c; - if (c == this->endl[endl_pos]) ++endl_pos; - if (endl_pos == this->endl.length()) - { - response = response.substr(0, response.length()-endl.length()); - - if (response.at(0) == '$') - { - GPS::get_instance().parse(response); - } - response = ""; - endl_pos = 0; - this_thread::sleep_for(50ms); - } - } - } - else if (available == 0) - { - this_thread::sleep_for(25ms); - } - else if (available < 0) - { - // TODO log error - } - #endif + GPS::get_instance().parse(this->read_line()); + this_thread::sleep_for(50ms); } this->stopped = true; } void Serial::send(const string& str) const { - serialPuts(this->fd, (str+this->endl).c_str()); + serialPuts(this->fd, (str+"\r\n").c_str()); } void Serial::close() @@ -125,8 +96,27 @@ bool Serial::is_open() const string Serial::read_line() const { - // TODO string response; + + #ifndef OS_TESTING + int available = serialDataAvail(this->fd); + + if (available > 0) + { + int endl_pos = 0; + for (int i = 0; i < available; i++) + { + char c = serialGetchar(this->fd); + response += c; + if (c == '\r') ++endl_pos; + if (endl_pos == 2) + { + response = response.substr(0, response.length()-2); + } + } + } + #endif + return response; } diff --git a/serial/Serial.h b/serial/Serial.h index 46d3f83..cb1142d 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -15,7 +15,6 @@ namespace os { int fd; atomic_bool open; atomic_bool stopped; - string endl; void gps_thread(); public: diff --git a/testing/camera_test.cc b/testing/camera_test.cc index eb1c71b..ae850f6 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -14,6 +14,7 @@ describe("Camera", [](){ this_thread::sleep_for(2s); Camera::get_instance().stop(); + AssertThat(Camera::get_instance().is_recording(), Equals(false)); }); diff --git a/testing/testing.cc b/testing/testing.cc index 5f38fc4..8792a1a 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -28,3 +28,4 @@ go_bandit([](){ #include "temperature_test.cc" #include "battery_test.cc" }); + From 1ef69b3efd86ec2752bc179f60df996a42f6d61b Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 24 Jul 2015 00:49:52 +0200 Subject: [PATCH 064/169] GPS parser failed on configuration frames --- gps/GPS.cc | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index b552900..7e20717 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -92,20 +92,23 @@ bool GPS::is_valid(string frame) uint_fast8_t GPS::parse(const string& frame) { - this->frame_logger->log(frame); - string frame_type = frame.substr(1, frame.find_first_of(',')-1); - - if (frame_type == "GPGGA") - { - this->parse_GGA(frame); - } - else if (frame_type == "GPGSA") - { - this->parse_GSA(frame); - } - else if (frame_type == "GPRMC") + if (frame.length() > 1) { - this->parse_RMC(frame); + this->frame_logger->log(frame); + string frame_type = frame.substr(1, frame.find_first_of(',')-1); + + if (frame_type == "GPGGA") + { + this->parse_GGA(frame); + } + else if (frame_type == "GPGSA") + { + this->parse_GSA(frame); + } + else if (frame_type == "GPRMC") + { + this->parse_RMC(frame); + } } return ERR_OK; From e93f1b19ce61965e660ff7966d19e11acdc2fc0b Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 28 Jul 2015 21:21:57 +0200 Subject: [PATCH 065/169] Fixed more things and started real testing --- Makefile.am | 2 +- openstratos.cc | 30 +++++++++++++++++++----------- serial/Serial.cc | 37 ++++++++++++++++++++++++++++++++++--- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/Makefile.am b/Makefile.am index 071d887..bc8e866 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ bin_PROGRAMS = openstratos -openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc +openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc gsm/GSM.cc openstratos_LDADD = -lwiringPi openstratos_CPPFLAGS = -std=c++14 diff --git a/openstratos.cc b/openstratos.cc index e25e0a2..81c5777 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -91,14 +91,13 @@ int main(void) } logger.log("GPS initialized."); - // TODO start GSM and send message logger.log("Initializing GSM..."); - // if ( ! GSM::get_instance().initialize(GSM_PWR_GPIO, GSM_STATUS_GPIO, GSM_UART)) - // { - // logger.log("GSM initialization error."); - // exit(1); - // } - // GSM::get_instance().turn_on(); + if ( ! GSM::get_instance().initialize(GSM_PWR_GPIO, GSM_STATUS_GPIO, GSM_UART)) + { + logger.log("GSM initialization error."); + exit(1); + } + GSM::get_instance().turn_on(); logger.log("GSM initialized."); logger.log("Testing camera recording..."); @@ -164,10 +163,19 @@ int main(void) logger.log("Sending initialization SMS..."); // if ( ! GSM::get_instance().send_SMS("Initialization finished OK. Recording. Waiting for launch.", SMS_PHONE)) - // { - // logger.log("Error sending initialization SMS."); - // exit(1); - // } + // { + // logger.log("Error sending initialization SMS."); + // logger.log("Stoping video recording."); + // if (Camera::get_instance().stop()) + // { + // logger.log("Recording stopped."); + // } + // else + // { + // logger.log("Error stopping recording."); + // } + // exit(1); + // } logger.log("Initialization SMS sent."); state = set_state(WAITING_LAUNCH); diff --git a/serial/Serial.cc b/serial/Serial.cc index 77ce670..4b24b36 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -66,8 +66,39 @@ void Serial::gps_thread() while(this->open) { - GPS::get_instance().parse(this->read_line()); - this_thread::sleep_for(50ms); + #ifndef OS_TESTING + int available = serialDataAvail(this->fd); + + if (available > 0) + { + for (int i = 0; i < available; i++) + { + char c = serialGetchar(this->fd); + response += c; + if (c == this->endl[endl_pos]) ++endl_pos; + if (endl_pos == this->endl.length()) + { + response = response.substr(0, response.length()-endl.length()); + + if (response.at(0) == '$') + { + GPS::get_instance().parse(response); + } + response = ""; + endl_pos = 0; + this_thread::sleep_for(50ms); + } + } + } + else if (available == 0) + { + this_thread::sleep_for(25ms); + } + else if (available < 0) + { + // TODO log error + } + #endif } this->stopped = true; } @@ -109,7 +140,7 @@ const string Serial::read_line() const char c = serialGetchar(this->fd); response += c; if (c == '\r') ++endl_pos; - if (endl_pos == 2) + if (endl_pos == 1 && c == '\n') { response = response.substr(0, response.length()-2); } From aa8496881a8d19604d74c41ced816cff738db737 Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 31 Jul 2015 12:09:02 +0200 Subject: [PATCH 066/169] More progress in the server script. Still some SMS failing. --- camera/Camera.h | 2 +- constants.h | 8 +- gps/GPS.cc | 32 ++++---- gps/GPS.h | 2 +- gsm/GSM.cc | 86 ++++++++++++++++++--- gsm/GSM.h | 8 +- openstratos.cc | 196 +++++++++++++++++++++++++++-------------------- serial/Serial.cc | 75 +++++++++++++++--- serial/Serial.h | 1 + 9 files changed, 286 insertions(+), 124 deletions(-) diff --git a/camera/Camera.h b/camera/Camera.h index 9a84caa..1617375 100644 --- a/camera/Camera.h +++ b/camera/Camera.h @@ -11,12 +11,12 @@ namespace os { { private: Camera() = default; - ~Camera(); void record_thread(int time); bool recording = false; public: Camera(Camera& copy) = delete; + ~Camera(); static Camera& get_instance(); bool record(int time); diff --git a/constants.h b/constants.h index 5866271..222f3f4 100644 --- a/constants.h +++ b/constants.h @@ -30,10 +30,10 @@ #define GPS_ENDL "\r\n" #define GSM_LOC_SERV "gprs-service.com" - #define GSM_UART "/dev/ttyAMA0" - #define GSM_PWR_GPIO 4 - #define GSM_STATUS_GPIO 5 - #define GSM_BAUDRATE 4800 + #define GSM_UART "/dev/ttyUSB0" + #define GSM_PWR_GPIO 7 + #define GSM_STATUS_GPIO 21 + #define GSM_BAUDRATE 9600 #define GSM_ENDL "\r\n" #define SMS_PHONE "" diff --git a/gps/GPS.cc b/gps/GPS.cc index 7e20717..15ae1d3 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -53,23 +53,23 @@ bool GPS::initialize(const string& serial_URL) if ( ! this->serial.initialize_GPS()) { this->logger->log("GPS serial error."); return false; - } else { - this->logger->log("Serial connection started."); - this->frame_logger = new Logger("data/logs/GPS/GPSFrames."+ to_string(now->tm_year+1900) +"-"+ - to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ - to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPS Frame"); - - #ifndef OS_TESTING - this->logger->log("Sending configuration frames..."); - this->serial.send("$PMTK220,100*2F"); - this->frame_logger->log("Sent: $PMTK220,100*2F"); - this->serial.send("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); - this->frame_logger->log("Sent: $PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); - this->logger->log("Configuration frames sent."); - #endif - - return true; } + + this->logger->log("Serial connection started."); + this->frame_logger = new Logger("data/logs/GPS/GPSFrames."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPSFrame"); + + #ifndef OS_TESTING + this->logger->log("Sending configuration frames..."); + this->serial.send("$PMTK220,100*2F"); + this->frame_logger->log("Sent: $PMTK220,100*2F"); + this->serial.send("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->frame_logger->log("Sent: $PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->logger->log("Configuration frames sent."); + #endif + + return true; } bool GPS::is_valid(string frame) diff --git a/gps/GPS.h b/gps/GPS.h index 327489a..f61c8f6 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -36,7 +36,6 @@ namespace os { euc_vec velocity; GPS() = default; - ~GPS(); void parse_GGA(const string& frame); void parse_GSA(const string& frame); @@ -44,6 +43,7 @@ namespace os { public: GPS(GPS& copy) = delete; + ~GPS(); static GPS& get_instance(); static bool is_valid(string frame); diff --git a/gsm/GSM.cc b/gsm/GSM.cc index a51351e..87a7da8 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -5,6 +5,8 @@ #include #include +#include + #include #include @@ -19,32 +21,60 @@ GSM& GSM::get_instance() GSM::~GSM() { - this->serial.close(); + if (this->serial.is_open()) + { + this->logger->log("Closing serial interface..."); + this->serial.close(); + this->logger->log("Serial interface closed."); + + this->logger->log("Deallocating command logger..."); + delete this->command_logger; + } + this->logger->log("Shutting down..."); + this->turn_off(); + this->logger->log("Shut down finished."); + delete this->logger; } bool GSM::initialize(int pwr_gpio, int status_gpio, const string& serial_URL) { + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + this->logger = new Logger("data/logs/GSM/GSM."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "GSM"); + this->pwr_gpio = pwr_gpio; this->status_gpio = status_gpio; - if ( ! this->serial.initialize(serial_URL, 9600)) + this->logger->log("Starting serial connection..."); + if ( ! this->serial.initialize(serial_URL, GSM_BAUDRATE)) { + this->logger->log("GSM serial error."); return false; } + this->logger->log("Serial connection started."); + + this->command_logger = new Logger("data/logs/GSM/GSMCommands."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GSMCommand"); pinMode(this->pwr_gpio, OUTPUT); digitalWrite(this->pwr_gpio, HIGH); - pinMode(this->pwr_gpio, INPUT); - - this_thread::sleep_for(3s); - + pinMode(this->status_gpio, INPUT); return true; } bool GSM::send_SMS(const string& message, const string& number) const { + this->logger->log("Sending SMS: \""+message+"\" to number "+number+"."); + if (this->send_command_read("AT+CMGF=1") != "OK") { + this->logger->log("Error sending SMS"); + this->logger->log("Primer condicional"); return false; } @@ -52,14 +82,17 @@ bool GSM::send_SMS(const string& message, const string& number) const send_command << "AT+CMGS=\"" << number << "\""; - if (this->send_command_read(send_command.str()) != "> ") + if ( ! this->send_command_read_only(send_command.str(), ">")) { + this->logger->log("Error sending SMS."); + this->logger->log("Segundo condicional"); return false; } - this->serial.send(message+"\x1a"+GSM_ENDL); + this->send_command(message+"\x1a\r\n"); this->serial.flush(); + this->logger->log("SMS sent."); return true; } @@ -87,7 +120,13 @@ bool GSM::get_status() const bool GSM::is_up() const { - return this->send_command_read("AT") == "OK"; + return this->send_command_read_only("AT", "OK"); +} + +bool GSM::has_connectivity() const +{ + string response = this->send_command_read("AT+CREG?"); + return response == "+CREG: 0,1" || response == "+CREG: 0,5"; } bool GSM::turn_on() const @@ -143,9 +182,38 @@ bool GSM::tear_down_GPRS() const const string GSM::send_command_read(const string& command) const { + this->command_logger->log("Sent: '"+command+"'"); this->serial.flush(); this->serial.send(command); + // Sent command + this->serial.read_line(); string response = this->serial.read_line(); + this->command_logger->log("Received: '"+response+"'"); + this->serial.flush(); + return response; +} + +bool GSM::send_command_read_only(const string& command, const string& only) const +{ + this->command_logger->log("Sent: '"+command+"'"); + this->serial.flush(); + this->serial.send(command); + // Sent command + this->serial.read_line(); + bool response = this->serial.read_only(only); + if (response) + { + this->command_logger->log("Received: '"+only+"'"); + } this->serial.flush(); return response; } + +void GSM::send_command(const string& command) const +{ + this->command_logger->log("Sent: '"+command+"'"); + this->serial.flush(); + this->serial.send(command); + this_thread::sleep_for(25ms); + this->serial.flush(); +} diff --git a/gsm/GSM.h b/gsm/GSM.h index a72ff60..78a679f 100644 --- a/gsm/GSM.h +++ b/gsm/GSM.h @@ -4,6 +4,7 @@ #include #include "serial/Serial.h" +#include "logger/Logger.h" using namespace std; @@ -13,19 +14,23 @@ namespace os { { private: Serial serial; + Logger* logger; + Logger* command_logger; int pwr_gpio; int status_gpio; int fh; GSM() = default; - ~GSM(); const string send_command_read(const string& command) const; + bool send_command_read_only(const string& command, const string& only) const; + void send_command(const string& command) const; bool init_GPRS() const; bool tear_down_GPRS() const; public: GSM(GSM& copy) = delete; + ~GSM(); static GSM& get_instance(); bool initialize(int pwr_gpio, int status_gpio, const string& serial_URL); @@ -33,6 +38,7 @@ namespace os { bool get_location(double& latitude, double& longitude) const; bool get_status() const; bool is_up() const; + bool has_connectivity() const; bool turn_on() const; bool turn_off() const; }; diff --git a/openstratos.cc b/openstratos.cc index 81c5777..add7e81 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -31,7 +31,8 @@ int main(void) { cout << "[OpenStratos] No log directory, creating..." << endl; if (mkdir("data/logs", 0755) == 0 && mkdir("data/logs/main", 0755) == 0 && - mkdir("data/logs/camera", 0755) == 0 && mkdir("data/logs/GPS", 0755) == 0) + mkdir("data/logs/camera", 0755) == 0 && mkdir("data/logs/GPS", 0755) == 0 + && mkdir("data/logs/GSM", 0755) == 0) { cout << "[OpenStratos] Log directory created." << endl; } @@ -97,8 +98,22 @@ int main(void) logger.log("GSM initialization error."); exit(1); } + logger.log("GSM initialized"); + + logger.log("Turning on GSM..."); GSM::get_instance().turn_on(); - logger.log("GSM initialized."); + this_thread::sleep_for(25ms); + while ( ! GSM::get_instance().is_up()); + logger.log("GSM on."); + + logger.log("Waiting for GSM connectivity..."); + this_thread::sleep_for(25ms); + while ( ! GSM::get_instance().has_connectivity()) + { + this_thread::sleep_for(1s); + } + this_thread::sleep_for(25ms); + logger.log("GSM connected."); logger.log("Testing camera recording..."); #ifndef RASPIVID @@ -112,8 +127,6 @@ int main(void) exit(1); } this_thread::sleep_for(11s); - Camera::get_instance().stop(); - if (file_exists("data/video/test.h264")) { logger.log("Camera test OK."); @@ -162,20 +175,26 @@ int main(void) logger.log("GPS thread started."); logger.log("Sending initialization SMS..."); - // if ( ! GSM::get_instance().send_SMS("Initialization finished OK. Recording. Waiting for launch.", SMS_PHONE)) - // { - // logger.log("Error sending initialization SMS."); - // logger.log("Stoping video recording."); - // if (Camera::get_instance().stop()) - // { - // logger.log("Recording stopped."); - // } - // else - // { - // logger.log("Error stopping recording."); - // } - // exit(1); - // } + if ( ! GSM::get_instance().send_SMS("Initialization finished OK. Recording. Waiting for launch.", SMS_PHONE)) + { + logger.log("Error sending initialization SMS."); + + logger.log("Stoping video recording."); + if (Camera::get_instance().stop()) + { + logger.log("Recording stopped."); + } + else + { + logger.log("Error stopping recording."); + } + + logger.log("Shuting down GSM..."); + GSM::get_instance().turn_off(); + logger.log("GSM off."); + + exit(1); + } logger.log("Initialization SMS sent."); state = set_state(WAITING_LAUNCH); @@ -192,16 +211,16 @@ int main(void) logger.log("Balloon launched."); logger.log("Trying to send launch confirmation SMS..."); - // if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ - // to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ - // to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - // { - // logger.log("Error sending launch confirmation SMS."); - // } - // else - // { + if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ + to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ + to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending launch confirmation SMS."); + } + else + { logger.log("Launch confirmation SMS sent."); - // } + } state = set_state(GOING_UP); logger.log("State changed to "+ state_to_string(state) +"."); @@ -213,19 +232,19 @@ int main(void) // } logger.log("1.5 km mark."); logger.log("Trying to send \"going up\" SMS..."); - // if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ - // to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ - // to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - // { - // logger.log("Error sending \"going up\" SMS."); - // } - // else - // { + if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ + to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ + to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending \"going up\" SMS."); + } + else + { logger.log("\"Going up\" SMS sent."); - // } + } logger.log("Turning off GSM..."); - // GSM::get_instance().turn_off(); + GSM::get_instance().turn_off(); logger.log("GSM off."); while ( ! has_bursted()); @@ -239,50 +258,60 @@ int main(void) this_thread::sleep_for(10s); // } logger.log("2.5 km mark."); + logger.log("Turning on GSM..."); - // GSM::get_instance().turn_on(); + GSM::get_instance().turn_on(); + while ( ! GSM::get_instance().is_up()); logger.log("GSM on."); + + logger.log("Waiting for GSM connectivity..."); + while ( ! GSM::get_instance().has_connectivity()) + { + this_thread::sleep_for(1s); + } + logger.log("GSM connected."); + logger.log("Trying to send first SMS..."); - // if ( ! GSM::get_instance().send_SMS("2.5 km mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - // { - // logger.log("Error sending first SMS."); - // } - // else - // { + if ( ! GSM::get_instance().send_SMS("2.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending first SMS."); + } + else + { logger.log("First SMS sent."); - // } + } - // while (GPS::get_instance().get_altitude() > 1500) - // { + while (GPS::get_instance().get_altitude() > 1500) + { this_thread::sleep_for(5s); - // } + } logger.log("1.5 km mark."); logger.log("Trying to send second SMS..."); - // if ( ! GSM::get_instance().send_SMS("1.5 km mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - // { - // logger.log("Error sending second SMS."); - // } - // else - // { + if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending second SMS."); + } + else + { logger.log("Second SMS sent."); - // } + } while ( ! has_landed() && GPS::get_instance().get_altitude() > 500); if ( ! has_landed()) { logger.log("500 m mark."); logger.log("Trying to send third SMS..."); - // if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - // { - // logger.log("Error sending third SMS."); - // } - // else - // { + if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending third SMS."); + } + else + { logger.log("Third SMS sent."); - // } + } } while ( ! has_landed()); @@ -306,26 +335,26 @@ int main(void) this_thread::sleep_for(1min); logger.log("Sending landed SMS..."); - // if ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - // { - // logger.log("Error sending landed SMS. Trying again in 10 minutes..."); - // } - // else - // { + if ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending landed SMS. Trying again in 10 minutes..."); + } + else + { logger.log("Landed SMS sent. Sending backup SMS in 10 minutes..."); - // } + } this_thread::sleep_for(10min); logger.log("Sending second landed SMS..."); - // while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - // +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - // { - // logger.log("Error sending second SMS, trying again in 5 minutes."); - // this_thread::sleep_for(5min); - // } + while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending second SMS, trying again in 5 minutes."); + this_thread::sleep_for(5min); + } logger.log("Second SMS sent."); @@ -336,16 +365,21 @@ int main(void) } logger.log("Turning GSM off..."); - // GSM::get_instance().turn_off(); + GSM::get_instance().turn_off(); logger.log("GSM off."); logger.log("Joining threads..."); gps_thread.join(); logger.log("Threads joined."); + logger.log("Deleting objects..."); + delete &GPS::get_instance(); + delete &GSM::get_instance(); + delete &Camera::get_instance(); + logger.log("Objects deleted."); logger.log("Powering off..."); sync(); - //reboot(RB_POWER_OFF); + // reboot(RB_POWER_OFF); return 0; } diff --git a/serial/Serial.cc b/serial/Serial.cc index 4b24b36..b413f83 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -6,6 +6,8 @@ #include #include +#include + #include #include "constants.h" @@ -62,7 +64,7 @@ Serial::~Serial() void Serial::gps_thread() { string response; - int endl_pos = 0; + bool endl_found = false; while(this->open) { @@ -75,17 +77,17 @@ void Serial::gps_thread() { char c = serialGetchar(this->fd); response += c; - if (c == this->endl[endl_pos]) ++endl_pos; - if (endl_pos == this->endl.length()) + if (c == '\r') endl_found = true; + if (endl_found && c == '\n') { - response = response.substr(0, response.length()-endl.length()); + response = response.substr(0, response.length()-2); if (response.at(0) == '$') { GPS::get_instance().parse(response); } response = ""; - endl_pos = 0; + endl_found = false; this_thread::sleep_for(50ms); } } @@ -131,26 +133,77 @@ const string Serial::read_line() const #ifndef OS_TESTING int available = serialDataAvail(this->fd); + struct timeval t1, t2; + double elapsed_time = 0; + bool endl_found = false; - if (available > 0) + while (true) { - int endl_pos = 0; + gettimeofday(&t1, NULL); + while (available == 0) + { + this_thread::sleep_for(25ms); + gettimeofday(&t2, NULL); + elapsed_time = (t2.tv_sec - t1.tv_sec); + elapsed_time += (t2.tv_usec - t1.tv_usec) / 1000000.0; + + if (elapsed_time > 5) return ""; + available = serialDataAvail(this->fd); + } + + if (available < 0) + { + // TODO log error + } + for (int i = 0; i < available; i++) { char c = serialGetchar(this->fd); + response += c; - if (c == '\r') ++endl_pos; - if (endl_pos == 1 && c == '\n') + if (c == '\r') endl_found = true; + if (endl_found && c == '\n') { - response = response.substr(0, response.length()-2); + return response.substr(0, response.length()-2); } } } #endif - return response; } +bool Serial::read_only(const string& only) const +{ + int available = serialDataAvail(this->fd); + struct timeval t1, t2; + double elapsed_time = 0; + bool endl_found = false; + + while (true) + { + gettimeofday(&t1, NULL); + while (available == 0) + { + this_thread::sleep_for(25ms); + gettimeofday(&t2, NULL); + elapsed_time = (t2.tv_sec - t1.tv_sec); + elapsed_time += (t2.tv_usec - t1.tv_usec) / 1000000.0; + + if (elapsed_time > 5) return false; + available = serialDataAvail(this->fd); + } + + if (available >= only.length()) + { + for (int i = 0; i < only.length(); i++) + { + if (serialGetchar(this->fd) != only[i]) return false; + } + return true; + } + } +} + void Serial::flush() const { serialFlush(this->fd); diff --git a/serial/Serial.h b/serial/Serial.h index cb1142d..23f2724 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -28,6 +28,7 @@ namespace os { bool initialize_GPS(); bool initialize(const string& serial_URL, int baud); const string read_line() const; + bool read_only(const string& only) const; void flush() const; }; } From d4b08504067ba057042a50dcd837459944b4116d Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 31 Jul 2015 23:20:48 +0200 Subject: [PATCH 067/169] Added camera logger and picture taking. Closed #27 and base created for #26. --- camera/Camera.cc | 99 ++++++++++++++++++++++++++++++++++++++---- camera/Camera.h | 8 +++- configure.ac | 6 +-- constants.h | 16 ++++--- openstratos.cc | 2 +- testing/camera_test.cc | 39 ++++++++++++++--- 6 files changed, 146 insertions(+), 24 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 64f3815..b3af1ff 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -9,6 +9,7 @@ #include #include +#include #include "config.h" #include "constants.h" @@ -22,21 +23,50 @@ Camera& Camera::get_instance() return instance; } +Camera::Camera() +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + this->logger = new Logger("data/logs/Camera/Camera."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "Camera"); +} + Camera::~Camera() { - if (this->recording) this->stop(); + this->logger->log("Shuting down..."); + if (this->recording) + { + this->logger->log("Stopping video recording..."); + if ( ! this->stop()) + { + this->logger->log("Error soping video recording."); + } + else + { + this->logger->log("Video recording stopped."); + } + } + this->logger->log("Shut down finished"); + delete this->logger; } void Camera::record_thread(int time) { + this->logger->log("Recording thread started."); this_thread::sleep_for(chrono::milliseconds(time)); this->recording = false; + this->logger->log("Finished recording thread."); } bool Camera::record(int time) { + if (time != 0) this->logger->log("Recording for "+to_string(time/1000)+" seconds..."); if ( ! this->recording) { + this->logger->log("Not already recording, creating command..."); string command; if (time > 0) { @@ -44,42 +74,95 @@ bool Camera::record(int time) } else { - command = "raspivid -o data/video/video-"+ to_string(get_file_count("data/video/")) - +".h264 -t " + to_string(time) + " -w "+ to_string(VIDEO_WIDTH) +" -h "+ to_string(VIDEO_HEIGHT) - +" -b "+ to_string(VIDEO_BITRATE*1000000) +" -fps "+ to_string(VIDEO_FPS) +" &"; + command = "raspivid -n -o data/video/video-"+ to_string(get_file_count("data/video/")) + + ".h264 -t " + to_string(time) + " -w "+ to_string(VIDEO_WIDTH) +" -h " + + to_string(VIDEO_HEIGHT) +" -b "+ to_string(VIDEO_BITRATE*1000000) + + " -fps "+ to_string(VIDEO_FPS) +" -co "+ to_string(VIDEO_CONTRAST) + + " -ex "+ VIDEO_EXPOSURE +" -br "+ to_string(VIDEO_BRIGHTNESS) +" &"; } - #ifndef RASPIVID + this->logger->log("Video command: '"+command+"'"); + + #ifndef RASPICAM + this->logger->log("Test mode, video recording simulated."); command = ""; #endif int st = system(command.c_str()); this->recording = true; - if (time > 0) + bool result = st == 0; + + if (result && time > 0) { + this->logger->log("Starting recording thread..."); thread t(&Camera::record_thread, this, time); t.detach(); } - return st == 0; + if (result) this->logger->log("Video recording correctly started."); + else this->logger->log("Error starting video recording."); + + return result; } } bool Camera::record() { + this->logger->log("Recording indefinitely..."); return this->record(0); } +bool Camera::take_picture() +{ + bool was_recording = this->recording; + if (was_recording) this->logger->log("Recording video, stopping..."); + if (was_recording && ! this->stop()) return false; + this->logger->log("Video recording stopped."); + + string command = "raspistill -n -o data/img/img-"+ to_string(get_file_count("data/img/")) + +".jpg " + (PHOTO_RAW ? "-r" : "") + " -w "+ to_string(PHOTO_WIDTH) + +" -h "+ to_string(PHOTO_HEIGHT) +" -q "+ to_string(PHOTO_QUALITY) + +" -co "+ to_string(PHOTO_CONTRAST) +" -br "+ to_string(PHOTO_BRIGHTNESS) + +" -ex "+ PHOTO_EXPOSURE; + + this->logger->log("Picture command: '"+command+"'"); + + #ifndef RASPICAM + this->logger->log("Test mode, picture taking simulated."); + command = ""; + #endif + + int st = system(command.c_str()); + bool result = st == 0; + + if (result) this->logger->log("Picture taken correctly."); + else this->logger->log("Error taking picture."); + + if (was_recording) this->logger->log("Video recording was active before taking picture. Resuming..."); + if (was_recording && ! this->record()) + { + this->logger->log("Error resuming video recording."); + return false; + } + this->logger->log("Video recording resumed."); + + return result; +} + bool Camera::stop() { - #ifdef RASPIVID + this->logger->log("Stopping video recording..."); + #ifdef RASPICAM if (system("pkill raspivid") == 0) { + this->logger->log("Video recording stopped correctly."); this->recording = false; return true; } + this->logger->log("Error stopping video recording."); return false; #else + this->logger->log("Test mode. Video recording stop simulated."); this->recording = false; return true; #endif diff --git a/camera/Camera.h b/camera/Camera.h index 1617375..99c4cfc 100644 --- a/camera/Camera.h +++ b/camera/Camera.h @@ -3,6 +3,8 @@ #include +#include "logger/Logger.h" + using namespace std; namespace os { @@ -10,10 +12,11 @@ namespace os { class Camera { private: - Camera() = default; - void record_thread(int time); + Logger* logger; bool recording = false; + Camera(); + void record_thread(int time); public: Camera(Camera& copy) = delete; ~Camera(); @@ -21,6 +24,7 @@ namespace os { bool record(int time); bool record(); + bool take_picture(); bool stop(); bool is_recording() const {return this->recording;} }; diff --git a/configure.ac b/configure.ac index 4ff814f..f04480f 100644 --- a/configure.ac +++ b/configure.ac @@ -12,9 +12,9 @@ AC_PROG_CXX AC_PROG_CC AC_PROG_INSTALL AC_PROG_MAKE_SET -AC_CHECK_PROG([HAVE_RASPIVID], [raspivid], [yes]) -AS_IF([test "x$HAVE_RASPIVID" = xyes], - [AC_DEFINE([RASPIVID], [1], [Define to 1 if you have raspivid available.])]) +AC_CHECK_PROG([HAVE_RASPICAM], [raspivid], [yes]) +AS_IF([test "x$HAVE_RASPICAM" = xyes], + [AC_DEFINE([RASPICAM], [1], [Define to 1 if you have raspivid available.])]) # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) diff --git a/constants.h b/constants.h index 222f3f4..8f56ce6 100644 --- a/constants.h +++ b/constants.h @@ -18,11 +18,17 @@ #define VIDEO_HEIGHT 1080 #define VIDEO_BITRATE 17 //Mbps #define VIDEO_FPS 30 - - // #define PHOTO_WIDTH 2592 - // #define PHOTO_HEIGHT 1944 - // #define PHOTO_QUALITY 90 - // #define PHOTO_RAW 0 + #define VIDEO_CONTRAST 50 + #define VIDEO_BRIGHTNESS 50 + #define VIDEO_EXPOSURE "antishake" + + #define PHOTO_WIDTH 2592 + #define PHOTO_HEIGHT 1944 + #define PHOTO_QUALITY 90 + #define PHOTO_RAW true + #define PHOTO_CONTRAST 50 + #define PHOTO_BRIGHTNESS 50 + #define PHOTO_EXPOSURE "antishake" #define GPS_UART "/dev/ttyAMA0" // #define GPS_ENABLE_GPIO 6 diff --git a/openstratos.cc b/openstratos.cc index add7e81..a52f30a 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -116,7 +116,7 @@ int main(void) logger.log("GSM connected."); logger.log("Testing camera recording..."); - #ifndef RASPIVID + #ifndef RASPICAM logger.log("Error: No raspivid found. Is this a Raspberry?"); exit(1); #endif diff --git a/testing/camera_test.cc b/testing/camera_test.cc index ae850f6..68e8519 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -6,6 +6,10 @@ describe("Camera", [](){ this_thread::sleep_for(2.5s); AssertThat(Camera::get_instance().is_recording(), Equals(false)); + + #ifdef RASPICAM + remove("data/video/video-"+ to_string(get_file_count("data/video/")-1) +".h264"); + #endif }); it("recording and stopping test", [&](){ @@ -13,14 +17,26 @@ describe("Camera", [](){ AssertThat(Camera::get_instance().is_recording(), Equals(true)); this_thread::sleep_for(2s); - Camera::get_instance().stop(); + AssertThat(Camera::get_instance().stop(), Equals(true)); AssertThat(Camera::get_instance().is_recording(), Equals(false)); + + #ifdef RASPICAM + remove("data/video/video-"+ to_string(get_file_count("data/video/")-1) +".h264"); + #endif + }); + + it("picture taking test", [&](){ + AssertThat(Camera::get_instance().record(), Equals(true)); + + #ifdef RASPICAM + remove("data/img/img-"+ to_string(get_file_count("data/img/")-1) +".jpg"); + #endif }); - #ifdef RASPIVID - it("file creation test", [&](){ - Camera::get_instance().record(10000); + #ifdef RASPICAM + it("video file creation test", [&](){ + AssertThat(Camera::get_instance().record(10000), Equals(true)); this_thread::sleep_for(chrono::seconds(11)); struct stat buf; @@ -30,6 +46,19 @@ describe("Camera", [](){ remove("data/video/test.h264"); }); #else - it_skip("file creation test", [&](){}); + it_skip("video file creation test", [&](){}); + #endif + + #ifdef RASPICAM + it("picture file creation test", [&](){ + start_file_count = get_file_count("data/img/"); + AssertThat(Camera::get_instance().take_picture(), Equals(true)); + end_file_count = get_file_count("data/img/"); + + AssertThat(end_file_count, Equals(start_file_count+1)); + remove("data/img/img-"+ to_string(get_file_count("data/img/")-1) +".jpg"); + }); + #else + it_skip("picture file creation test", [&](){}); #endif }); From 5486f34e767b465f16c57008acfb4d2d0f9aa001 Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 31 Jul 2015 23:32:06 +0200 Subject: [PATCH 068/169] Changed configuration script to new bug tracker. --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index f04480f..4ed6251 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT(OpenStratos, Alpha-1-dev, https://openstratos.org/bugtracker) +AC_INIT(OpenStratos, 1.0.0-dev, https://github.com/OpenStratos/server/issues) AC_CONFIG_SRCDIR([openstratos.cc]) AM_INIT_AUTOMAKE([subdir-objects]) AC_CONFIG_HEADERS([config.h]) @@ -14,7 +14,7 @@ AC_PROG_INSTALL AC_PROG_MAKE_SET AC_CHECK_PROG([HAVE_RASPICAM], [raspivid], [yes]) AS_IF([test "x$HAVE_RASPICAM" = xyes], - [AC_DEFINE([RASPICAM], [1], [Define to 1 if you have raspivid available.])]) + [AC_DEFINE([RASPICAM], [1], [Define to 1 if you have raspicam available.])]) # Checks for libraries. AC_CHECK_LIB([pthread], [pthread_create]) From 914dfbabb0b0b1cce67a4516b6276ec0f41ccec0 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 2 Aug 2015 22:16:10 +0200 Subject: [PATCH 069/169] Added state recovery --- openstratos.cc | 35 +++++++++++++++++++++++++++++++++-- openstratos.h | 3 +++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index a52f30a..c15eba2 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -4,7 +4,13 @@ int main(void) { cout << "[OpenStratos] Starting..." << endl; // Only if verbose - State state = INITIALIZING; + State last_state; + if (file_exists(STATE_FILE)) + last_state = get_state(); + else + last_state = SHUT_DOWN; + + State state = set_state(INITIALIZING); struct timeval timer; gettimeofday(&timer, NULL); @@ -424,12 +430,31 @@ void os::gps_thread_fn(State& state) State os::set_state(State new_state) { ofstream state_file(STATE_FILE); - state_file << new_state; + state_file << state_to_string(new_state); state_file.close(); return new_state; } +State os::get_state() +{ + ifstream state_file(STATE_FILE); + string str_state((istreambuf_iterator(state_file)), + istreambuf_iterator()); + state_file.close(); + + if (str_state == "INITIALIZING") return INITIALIZING; + if (str_state == "ACQUIRING_FIX") return ACQUIRING_FIX; + if (str_state == "WAITING_LAUNCH") return WAITING_LAUNCH; + if (str_state == "GOING_UP") return GOING_UP; + if (str_state == "GOING_DOWN") return GOING_DOWN; + if (str_state == "LANDED") return LANDED; + if (str_state == "SHUT_DOWN") return SHUT_DOWN; + if (str_state == "SAFE_MODE") return SAFE_MODE; + + return RECOVERY; +} + string os::state_to_string(State state) { switch (state) @@ -454,6 +479,12 @@ string os::state_to_string(State state) break; case SHUT_DOWN: return "SHUT_DOWN"; + break; + case SAFE_MODE: + return "SAFE_MODE"; + break; + case RECOVERY: + return "RECOVERY"; } } diff --git a/openstratos.h b/openstratos.h index 1483b7e..59539e6 100644 --- a/openstratos.h +++ b/openstratos.h @@ -32,12 +32,15 @@ namespace os GOING_DOWN, LANDED, SHUT_DOWN, + SAFE_MODE, + RECOVERY, }; inline bool file_exists(const string& name); inline float get_available_disk_space(); void gps_thread_fn(State& state); State set_state(State new_state); + State get_state(); string state_to_string(State state); bool has_launched(); bool has_bursted(); From be69666db6b63a8848aab770aa768b144c0ac5dd Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 6 Aug 2015 18:07:05 +0200 Subject: [PATCH 070/169] Much progress with batteries and camera. Still SMSs failing. --- Makefile.am | 2 +- battery/Battery.cc | 72 ------ battery/Battery.h | 34 --- camera/Camera.cc | 73 +++--- camera/Camera.h | 1 + constants.h | 18 +- gps/GPS.cc | 47 +++- gps/GPS.h | 10 +- gsm/GSM.cc | 64 +++-- gsm/GSM.h | 5 +- openstratos.cc | 473 +++++++++++++++++++++++++++++++------ openstratos.h | 8 +- temperature/Temperature.cc | 71 ------ temperature/Temperature.h | 36 --- testing/bandit | 2 +- testing/camera_test.cc | 19 +- testing/gps_test.cc | 2 +- testing/testing.cc | 28 ++- 18 files changed, 586 insertions(+), 379 deletions(-) delete mode 100644 battery/Battery.cc delete mode 100644 battery/Battery.h delete mode 100644 temperature/Temperature.cc delete mode 100644 temperature/Temperature.h diff --git a/Makefile.am b/Makefile.am index bc8e866..eda7769 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,5 +4,5 @@ openstratos_LDADD = -lwiringPi openstratos_CPPFLAGS = -std=c++14 EXTRA_PROGRAMS = utesting -utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc battery/Battery.cc temperature/Temperature.cc gsm/GSM.cc logger/Logger.cc +utesting_SOURCES = testing/testing.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc utesting_CPPFLAGS = -std=c++14 -Itesting/bandit -Wno-unused-result -DOS_TESTING diff --git a/battery/Battery.cc b/battery/Battery.cc deleted file mode 100644 index 05c63c8..0000000 --- a/battery/Battery.cc +++ /dev/null @@ -1,72 +0,0 @@ -#include "battery/Battery.h" - -#include -#include - -#include - -#include "constants.h" - -using namespace std; -using namespace os; - -Battery::~Battery() -{ - if (this->reading) - this->stop_reading(); -} - -Battery::Battery(const int address) -{ - this->reading = false; - this->stopped = true; - #ifndef OS_TESTING - int fh = wiringPiI2CSetup(address); - if (fh != -1) - { - this->address = address; - this->filehandle = fh; - } - else - { - // TODO Log error - //printf("An error ocurred initializing I2C Battery module\n"); - } - #endif -} - -void Battery::start_reading() -{ - if ( ! this->reading) - { - this->reading = true; - this->stopped = false; - thread t(&Battery::read_battery, this); - t.detach(); - } -} - -void Battery::stop_reading() -{ - this->reading = false; - while( ! this->stopped); -} - -void Battery::read_battery() -{ - while (this->reading) - { - #ifndef OS_TESTING - int value = wiringPiI2CRead(this->filehandle); - #else - int value = 32768*(0.5*(BAT_MAX+BAT_MIN))*BAT_R2/(BAT_R1+BAT_R2)/5; - #endif - - float voltage5 = value * 5.0 / 32768; // 2^15 - - this->battery = volt_to_percent(voltage5*(BAT_R1+BAT_R2)/BAT_R2); - - this_thread::sleep_for(50ms); - } - this->stopped = true; -} diff --git a/battery/Battery.h b/battery/Battery.h deleted file mode 100644 index be549c6..0000000 --- a/battery/Battery.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef BATTERY_BATTERY_H_ -#define BATTERY_BATTERY_H_ - -#include - -#include "constants.h" -using namespace std; - -namespace os { - class Battery - { - private: - int address; - int filehandle; - float battery; - atomic_bool reading; - atomic_bool stopped; - - void read_battery(); - public: - Battery(const int address); - ~Battery(); - Battery(Battery& copy) = delete; - - float get_battery() {return this->battery;} - void start_reading(); - void stop_reading(); - bool is_reading() {return this->reading;} - }; - - inline float volt_to_percent(float voltage) {return (voltage-BAT_MIN)/(BAT_MAX-BAT_MIN)*100;} -} - -#endif // BATTERY_BATTERY_H_ diff --git a/camera/Camera.cc b/camera/Camera.cc index b3af1ff..004d28d 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -29,7 +29,7 @@ Camera::Camera() gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); - this->logger = new Logger("data/logs/Camera/Camera."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + this->logger = new Logger("data/logs/camera/Camera."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "Camera"); } @@ -67,25 +67,21 @@ bool Camera::record(int time) if ( ! this->recording) { this->logger->log("Not already recording, creating command..."); - string command; - if (time > 0) - { - command = "raspivid -o data/video/test.h264 -t " + to_string(time) + " &"; - } - else - { - command = "raspivid -n -o data/video/video-"+ to_string(get_file_count("data/video/")) - + ".h264 -t " + to_string(time) + " -w "+ to_string(VIDEO_WIDTH) +" -h " - + to_string(VIDEO_HEIGHT) +" -b "+ to_string(VIDEO_BITRATE*1000000) - + " -fps "+ to_string(VIDEO_FPS) +" -co "+ to_string(VIDEO_CONTRAST) - + " -ex "+ VIDEO_EXPOSURE +" -br "+ to_string(VIDEO_BRIGHTNESS) +" &"; - } + string filename = time > 0 ? "data/video/test.h264" : "data/video/video-"+ + to_string(get_file_count("data/video/")) +".h264"; + #ifdef OS_TESTING + filename = "data/video/test.h264"; + #endif + string command = "raspivid -n -o "+ filename +" -t " + to_string(time) + " -w "+ to_string(VIDEO_WIDTH) +" -h " + + to_string(VIDEO_HEIGHT) +" -b "+ to_string(VIDEO_BITRATE*1000000) + + " -fps "+ to_string(VIDEO_FPS) +" -co "+ to_string(VIDEO_CONTRAST) + + " -ex "+ VIDEO_EXPOSURE +" -br "+ to_string(VIDEO_BRIGHTNESS) +" &"; this->logger->log("Video command: '"+command+"'"); - #ifndef RASPICAM + // #ifndef RASPICAM this->logger->log("Test mode, video recording simulated."); command = ""; - #endif + // #endif int st = system(command.c_str()); this->recording = true; @@ -112,25 +108,31 @@ bool Camera::record() return this->record(0); } -bool Camera::take_picture() +bool Camera::take_picture(const string& exif) { bool was_recording = this->recording; if (was_recording) this->logger->log("Recording video, stopping..."); if (was_recording && ! this->stop()) return false; this->logger->log("Video recording stopped."); - string command = "raspistill -n -o data/img/img-"+ to_string(get_file_count("data/img/")) - +".jpg " + (PHOTO_RAW ? "-r" : "") + " -w "+ to_string(PHOTO_WIDTH) + string filename = "data/img/img-"+ to_string(get_file_count("data/img/")) +".jpg"; + #ifdef OS_TESTING + filename = "data/img/test.jpg"; + #endif + + string exif_command = exif != "" ? " -x "+ exif : ""; + + string command = "raspistill -n -o "+ filename +" " + (PHOTO_RAW ? "-r" : "") + " -w "+ to_string(PHOTO_WIDTH) +" -h "+ to_string(PHOTO_HEIGHT) +" -q "+ to_string(PHOTO_QUALITY) +" -co "+ to_string(PHOTO_CONTRAST) +" -br "+ to_string(PHOTO_BRIGHTNESS) - +" -ex "+ PHOTO_EXPOSURE; + +" -ex "+ PHOTO_EXPOSURE + exif_command; this->logger->log("Picture command: '"+command+"'"); - #ifndef RASPICAM + // #ifndef RASPICAM this->logger->log("Test mode, picture taking simulated."); command = ""; - #endif + // #endif int st = system(command.c_str()); bool result = st == 0; @@ -149,23 +151,28 @@ bool Camera::take_picture() return result; } +bool Camera::take_picture() +{ + return Camera::take_picture(""); +} + bool Camera::stop() { this->logger->log("Stopping video recording..."); - #ifdef RASPICAM - if (system("pkill raspivid") == 0) - { - this->logger->log("Video recording stopped correctly."); - this->recording = false; - return true; - } - this->logger->log("Error stopping video recording."); - return false; - #else + // #ifdef RASPICAM + // if (system("pkill raspivid") == 0) + // { + // this->logger->log("Video recording stopped correctly."); + // this->recording = false; + // return true; + // } + // this->logger->log("Error stopping video recording."); + // return false; + // #else this->logger->log("Test mode. Video recording stop simulated."); this->recording = false; return true; - #endif + // #endif } int os::get_file_count(const string& path) diff --git a/camera/Camera.h b/camera/Camera.h index 99c4cfc..bbd1fca 100644 --- a/camera/Camera.h +++ b/camera/Camera.h @@ -24,6 +24,7 @@ namespace os { bool record(int time); bool record(); + bool take_picture(const string& exif); bool take_picture(); bool stop(); bool is_recording() const {return this->recording;} diff --git a/constants.h b/constants.h index 8f56ce6..f165275 100644 --- a/constants.h +++ b/constants.h @@ -1,18 +1,12 @@ #ifndef CONSTANTS_H_ #define CONSTANTS_H_ - #define ERR_OK 0 - #define ERR_CHK 1 - #define ERR_INT 2 - #define ERR_PWD 3 + #define FLIGHT_LENGTH 3.5 - #define TEMP_VIN 5 - #define TEMP_R 500 - - #define BAT_MAX 8.4 - #define BAT_MIN 7.4 - #define BAT_R1 3300 - #define BAT_R2 4700 + #define BAT_GSM_MAX 4.2 + #define BAT_GSM_MIN 3.7 + #define BAT_MAIN_MAX 8.4*2660/(2660+7420) // Measured Ohms in voltage divider + #define BAT_MAIN_MIN 7.4*BAT_MAIN_MAX/8.4 #define VIDEO_WIDTH 1920 #define VIDEO_HEIGHT 1080 @@ -31,7 +25,7 @@ #define PHOTO_EXPOSURE "antishake" #define GPS_UART "/dev/ttyAMA0" - // #define GPS_ENABLE_GPIO 6 + #define GPS_ENABLE_GPIO 2 #define GPS_BAUDRATE 9600 #define GPS_ENDL "\r\n" diff --git a/gps/GPS.cc b/gps/GPS.cc index 15ae1d3..d3d2fe5 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -1,4 +1,5 @@ #include "gps/GPS.h" +#include "constants.h" #include #include @@ -8,6 +9,8 @@ #include +#include + #include "constants.h" #include "serial/Serial.h" #include "logger/Logger.h" @@ -33,13 +36,13 @@ GPS::~GPS() this->logger->log("Deallocating frame logger..."); delete this->frame_logger; } - this->logger->log("Shutting down..."); - // TODO shut down GPS - this->logger->log("Shut down finished."); + this->logger->log("Turning off GPS..."); + this->turn_off(); + this->logger->log("GPS off."); delete this->logger; } -bool GPS::initialize(const string& serial_URL) +bool GPS::initialize() { struct timeval timer; gettimeofday(&timer, NULL); @@ -61,6 +64,8 @@ bool GPS::initialize(const string& serial_URL) to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPSFrame"); #ifndef OS_TESTING + pinMode(GPS_ENABLE_GPIO, OUTPUT); + this->logger->log("Sending configuration frames..."); this->serial.send("$PMTK220,100*2F"); this->frame_logger->log("Sent: $PMTK220,100*2F"); @@ -72,6 +77,32 @@ bool GPS::initialize(const string& serial_URL) return true; } +bool GPS::turn_on() const +{ + if (digitalRead(GPS_ENABLE_GPIO) == LOW) + { + digitalWrite(GPS_ENABLE_GPIO, HIGH); + return true; + } + else + { + return false; + } +} + +bool GPS::turn_off() const +{ + if (digitalRead(GPS_ENABLE_GPIO) == HIGH) + { + digitalWrite(GPS_ENABLE_GPIO, LOW); + return true; + } + else + { + return false; + } +} + bool GPS::is_valid(string frame) { regex frame_regex("\\$[A-Z][0-9A-Z\\.,-]*\\*[0-9A-F]{1,2}"); @@ -90,7 +121,7 @@ bool GPS::is_valid(string frame) return checksum == frame_cs; } -uint_fast8_t GPS::parse(const string& frame) +void GPS::parse(const string& frame) { if (frame.length() > 1) { @@ -110,8 +141,6 @@ uint_fast8_t GPS::parse(const string& frame) this->parse_RMC(frame); } } - - return ERR_OK; } void GPS::parse_GGA(const string& frame) @@ -121,8 +150,7 @@ void GPS::parse_GGA(const string& frame) vector s_data; // We put all fields in a vector - while(getline(ss, data, ',')) - s_data.push_back(data); + while(getline(ss, data, ',')) s_data.push_back(data); // Is the data valid? this->active = s_data[6] > "0"; @@ -166,6 +194,7 @@ void GPS::parse_GSA(const string& frame) if (this->active) { // Update DOP + this->pdop = stof(s_data[15]); this->hdop = stof(s_data[16]); this->vdop = stof(s_data[17].substr(0, s_data[17].find_first_of('*'))); } diff --git a/gps/GPS.h b/gps/GPS.h index f61c8f6..33fed27 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -31,6 +31,7 @@ namespace os { double latitude; double longitude; double altitude; + float pdop; float hdop; float vdop; euc_vec velocity; @@ -53,14 +54,15 @@ namespace os { double get_latitude() const {return this->latitude;} double get_longitude() const {return this->longitude;} double get_altitude() const {return this->altitude;} + float get_PDOP() const {return this->pdop;} float get_HDOP() const {return this->hdop;} float get_VDOP() const {return this->vdop;} euc_vec get_velocity() const {return this->velocity;} - bool initialize(const string& serial_URL); - uint_fast8_t parse(const string& frame); - - // TODO Turn ON and OFF + bool initialize(); + bool turn_on() const; + bool turn_off() const; + void parse(const string& frame); }; } diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 87a7da8..e16f1fd 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -4,6 +4,7 @@ #include #include #include +#include #include @@ -36,7 +37,7 @@ GSM::~GSM() delete this->logger; } -bool GSM::initialize(int pwr_gpio, int status_gpio, const string& serial_URL) +bool GSM::initialize() { struct timeval timer; gettimeofday(&timer, NULL); @@ -46,11 +47,8 @@ bool GSM::initialize(int pwr_gpio, int status_gpio, const string& serial_URL) to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GSM"); - this->pwr_gpio = pwr_gpio; - this->status_gpio = status_gpio; - this->logger->log("Starting serial connection..."); - if ( ! this->serial.initialize(serial_URL, GSM_BAUDRATE)) + if ( ! this->serial.initialize(GSM_UART, GSM_BAUDRATE)) { this->logger->log("GSM serial error."); return false; @@ -61,9 +59,7 @@ bool GSM::initialize(int pwr_gpio, int status_gpio, const string& serial_URL) to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GSMCommand"); - pinMode(this->pwr_gpio, OUTPUT); - digitalWrite(this->pwr_gpio, HIGH); - pinMode(this->status_gpio, INPUT); + pinMode(GSM_PWR_GPIO, OUTPUT); return true; } @@ -71,10 +67,10 @@ bool GSM::send_SMS(const string& message, const string& number) const { this->logger->log("Sending SMS: \""+message+"\" to number "+number+"."); + this->serial.flush(); if (this->send_command_read("AT+CMGF=1") != "OK") { this->logger->log("Error sending SMS"); - this->logger->log("Primer condicional"); return false; } @@ -85,7 +81,6 @@ bool GSM::send_SMS(const string& message, const string& number) const if ( ! this->send_command_read_only(send_command.str(), ">")) { this->logger->log("Error sending SMS."); - this->logger->log("Segundo condicional"); return false; } @@ -115,7 +110,46 @@ bool GSM::get_location(double& latitude, double& longitude) const bool GSM::get_status() const { - return digitalRead(this->status_gpio) == HIGH; + return digitalRead(GSM_STATUS_GPIO) == HIGH; +} + +bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage) const +{ + this->logger->log("Checking Battery status..."); + if (this->get_status()) + { + string gsm_response = this->send_command_read("AT+CBC"); + string adc_response = this->send_command_read("AT+CADC?"); + while (adc_response.substr(0, 6) != "+CADC:") + { + this->logger->log("OK received, reading next line..."); + adc_response = this->serial.read_line(); + } + + if (gsm_response.substr(0, 5) == "+CBC:" && adc_response.substr(0, 6) == "+CADC:") + { + stringstream gsm_ss(gsm_response); + string data; + vector gsm_data; + + while(getline(gsm_ss, data, ',')) gsm_data.push_back(data); + + int gsm_bat_voltage = stoi(gsm_data[2]); + int main_bat_voltage = stoi(adc_response.substr(9, 4)); + gsm_bat_percentage = (gsm_bat_voltage/1000.0-BAT_GSM_MIN)/(BAT_GSM_MAX-BAT_GSM_MIN); + main_bat_percentage = (main_bat_voltage/1000.0-BAT_MAIN_MIN)/(BAT_MAIN_MAX-BAT_MAIN_MIN); + + this->logger->log("Main battery percentage: "+ to_string(main_bat_percentage) + + "% - GSM battery percentage: "+ to_string(gsm_bat_percentage) +"%"); + + return true; + } + } + else + { + this->logger->log("Error: module is off."); + } + return false; } bool GSM::is_up() const @@ -133,9 +167,9 @@ bool GSM::turn_on() const { if ( ! this->get_status()) { - digitalWrite(this->pwr_gpio, LOW); + digitalWrite(GSM_PWR_GPIO, LOW); this_thread::sleep_for(2s); - digitalWrite(this->pwr_gpio, HIGH); + digitalWrite(GSM_PWR_GPIO, HIGH); this_thread::sleep_for(500ms); return true; } @@ -149,9 +183,9 @@ bool GSM::turn_off() const { if (this->get_status()) { - digitalWrite(this->pwr_gpio, LOW); + digitalWrite(GSM_PWR_GPIO, LOW); this_thread::sleep_for(2s); - digitalWrite(this->pwr_gpio, HIGH); + digitalWrite(GSM_PWR_GPIO, HIGH); this_thread::sleep_for(500ms); return true; } diff --git a/gsm/GSM.h b/gsm/GSM.h index 78a679f..b8d6fbc 100644 --- a/gsm/GSM.h +++ b/gsm/GSM.h @@ -17,8 +17,6 @@ namespace os { Logger* logger; Logger* command_logger; - int pwr_gpio; - int status_gpio; int fh; GSM() = default; @@ -33,10 +31,11 @@ namespace os { ~GSM(); static GSM& get_instance(); - bool initialize(int pwr_gpio, int status_gpio, const string& serial_URL); + bool initialize(); bool send_SMS(const string& message, const string& number) const; bool get_location(double& latitude, double& longitude) const; bool get_status() const; + bool get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage) const; bool is_up() const; bool has_connectivity() const; bool turn_on() const; diff --git a/openstratos.cc b/openstratos.cc index c15eba2..d67957f 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -16,8 +16,10 @@ int main(void) gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); - cout << "[OpenStratos] Current time: " << now->tm_hour << ":" << now->tm_min << ":" << now->tm_sec << - " UTC of " << now->tm_mon << "/" << now->tm_mday << "/" << (now->tm_year+1900) << endl; // Only if verbose + cout << "[OpenStratos] Current time: " << setfill('0') << setw(2) << now->tm_hour << ":" << + setfill('0') << setw(2) << now->tm_min << ":" << setfill('0') << setw(2) << now->tm_sec << + " UTC of " << setfill('0') << setw(2) << now->tm_mon << "/" << + setfill('0') << setw(2) << now->tm_mday << "/" << (now->tm_year+1900) << endl; // Only if verbose if ( ! file_exists("data")) { @@ -70,17 +72,33 @@ int main(void) else { logger.log("Error creating video directory."); - cout << "[OpenStratos] Error creating video directory." << endl; + exit(1); + } + } + + if (file_exists("data/img")) + { + logger.log("Image directory exists."); + } + else + { + logger.log("No image directory, creating..."); + if (mkdir("data/img", 0755) == 0) + { + logger.log("Image directory created."); + } + else + { + logger.log("Error creating image directory."); exit(1); } } logger.log("Available disk space: " + to_string(get_available_disk_space()/1073741824) + " GiB"); - if (get_available_disk_space() < 22649241600) // Enough for about 3 hours of video + if (get_available_disk_space() < FLIGHT_LENGTH*9437184000) // 1.25 times the flight length { logger.log("Error: Not enough disk space."); - cout << "[OpenStratos] Error: Not enough disk space." << endl; - exit(1); + // exit(1); } logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7549747200) + @@ -91,17 +109,27 @@ int main(void) logger.log("WiringPi initialized."); logger.log("Initializing GPS..."); - if ( ! GPS::get_instance().initialize(GPS_UART)) + if ( ! GPS::get_instance().initialize()) { logger.log("GPS initialization error."); exit(1); } logger.log("GPS initialized."); + logger.log("Turning on GPS..."); + GPS::get_instance().turn_on(); + logger.log("GPS on."); + logger.log("Initializing GSM..."); - if ( ! GSM::get_instance().initialize(GSM_PWR_GPIO, GSM_STATUS_GPIO, GSM_UART)) + if ( ! GSM::get_instance().initialize()) { logger.log("GSM initialization error."); + logger.log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger.log("GPS off."); + else + logger.log("Error turning GPS off."); + exit(1); } logger.log("GSM initialized"); @@ -109,9 +137,39 @@ int main(void) logger.log("Turning on GSM..."); GSM::get_instance().turn_on(); this_thread::sleep_for(25ms); - while ( ! GSM::get_instance().is_up()); + while ( ! GSM::get_instance().is_up()) + { + this_thread::sleep_for(1s); + } logger.log("GSM on."); + this_thread::sleep_for(3s); // Sleeping for letting GSM initialize + + logger.log("Checking batteries..."); + double main_battery, gsm_battery; + GSM::get_instance().get_battery_status(main_battery, gsm_battery); + logger.log("Batteries checked => Main battery: "+ to_string(main_battery) + + "% - GSM battery: "+ to_string(gsm_battery) +"%"); + + if (main_battery < 0.95 || gsm_battery < 0.95) + { + logger.log("Error: Not enough battery."); + + logger.log("Turning GSM off..."); + if (GSM::get_instance().turn_off()) + logger.log("GSM off."); + else + logger.log("Error turning GSM off."); + + logger.log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger.log("GPS off."); + else + logger.log("Error turning GPS off."); + + exit(1); + } + logger.log("Waiting for GSM connectivity..."); this_thread::sleep_for(25ms); while ( ! GSM::get_instance().has_connectivity()) @@ -121,6 +179,10 @@ int main(void) this_thread::sleep_for(25ms); logger.log("GSM connected."); + logger.log("Starting battery thread..."); + thread battery_thread(&battery_thread_fn, ref(state)); + logger.log("Battery thread started."); + logger.log("Testing camera recording..."); #ifndef RASPICAM logger.log("Error: No raspivid found. Is this a Raspberry?"); @@ -133,24 +195,36 @@ int main(void) exit(1); } this_thread::sleep_for(11s); - if (file_exists("data/video/test.h264")) - { + // if (file_exists("data/video/test.h264")) + // { logger.log("Camera test OK."); logger.log("Removing test file..."); - if (remove("data/video/test.h264")) - { - logger.log("Error removing test file."); - } - else - { + // if (remove("data/video/test.h264")) + // { + // logger.log("Error removing test file."); + // } + // else + // { logger.log("Test file removed."); - } - } - else - { - logger.log("Test recording error."); - exit(1); - } + // } + // } + // else + // { + // logger.log("Test recording error."); + // logger.log("Turning GSM off..."); + // if (GSM::get_instance().turn_off()) + // logger.log("GSM off."); + // else + // logger.log("Error turning GSM off."); + + // logger.log("Turning GPS off..."); + // if (GPS::get_instance().turn_off()) + // logger.log("GPS off."); + // else + // logger.log("Error turning GPS off."); + + // exit(1); + // } state = set_state(ACQUIRING_FIX); logger.log("State changed to "+ state_to_string(state) +"."); @@ -172,10 +246,26 @@ int main(void) if ( ! Camera::get_instance().record()) { logger.log("Error starting recording"); + logger.log("Turning GSM off..."); + if (GSM::get_instance().turn_off()) + logger.log("GSM off."); + else + logger.log("Error turning GSM off."); + + logger.log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger.log("GPS off."); + else + logger.log("Error turning GPS off."); + exit(1); } logger.log("Recording started."); + logger.log("Starting picture thread..."); + thread picture_thread(&picture_thread_fn, ref(state)); + logger.log("Picture thread started."); + logger.log("Starting GPS Thread..."); thread gps_thread(&gps_thread_fn, ref(state)); logger.log("GPS thread started."); @@ -195,9 +285,17 @@ int main(void) logger.log("Error stopping recording."); } - logger.log("Shuting down GSM..."); - GSM::get_instance().turn_off(); - logger.log("GSM off."); + logger.log("Turning GSM off..."); + if (GSM::get_instance().turn_off()) + logger.log("GSM off."); + else + logger.log("Error turning GSM off."); + + logger.log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger.log("GPS off."); + else + logger.log("Error turning GPS off."); exit(1); } @@ -208,14 +306,23 @@ int main(void) logger.log("Waiting for launch..."); // Main logic + int count = 0; while (state != SHUT_DOWN) { switch (state) { case WAITING_LAUNCH: - while ( ! has_launched()); + while ( ! has_launched()) + { + this_thread::sleep_for(1s); + } + this_thread::sleep_for(1min); // TODO delete logger.log("Balloon launched."); + state = set_state(GOING_UP); + logger.log("State changed to "+ state_to_string(state) +"."); + break; + case GOING_UP: logger.log("Trying to send launch confirmation SMS..."); if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ @@ -228,14 +335,11 @@ int main(void) logger.log("Launch confirmation SMS sent."); } - state = set_state(GOING_UP); - logger.log("State changed to "+ state_to_string(state) +"."); - break; - case GOING_UP: // while (GPS::get_instance().get_altitude() < 1500) // { - this_thread::sleep_for(2s); + this_thread::sleep_for(5s); // } + this_thread::sleep_for(3min); // TODO: delete logger.log("1.5 km mark."); logger.log("Trying to send \"going up\" SMS..."); if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ @@ -253,74 +357,177 @@ int main(void) GSM::get_instance().turn_off(); logger.log("GSM off."); + this_thread::sleep_for(15min); // TODO delete + while ( ! has_bursted()); logger.log("Balloon burst."); state = set_state(GOING_DOWN); logger.log("State changed to "+ state_to_string(state) +"."); break; case GOING_DOWN: - // while (GPS::get_instance().get_altitude() > 2500) - // { - this_thread::sleep_for(10s); - // } + while (GPS::get_instance().get_altitude() > 2500) + { + this_thread::sleep_for(5s); + } + this_thread::sleep_for(5min); // TODO: delete logger.log("2.5 km mark."); logger.log("Turning on GSM..."); GSM::get_instance().turn_on(); - while ( ! GSM::get_instance().is_up()); - logger.log("GSM on."); + count = 0; + while ( ! GSM::get_instance().is_up()) + { + if (count > 5) break; + this_thread::sleep_for(1s); + ++count; + }; + + if (GSM::get_instance().is_up()) + logger.log("GSM on."); + else + logger.log("GSM has not turned on yet, not waiting anymore."); logger.log("Waiting for GSM connectivity..."); + count = 0; while ( ! GSM::get_instance().has_connectivity()) { + if (count > 15) break; this_thread::sleep_for(1s); + ++count; } - logger.log("GSM connected."); - - logger.log("Trying to send first SMS..."); - if ( ! GSM::get_instance().send_SMS("2.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + if ( ! GSM::get_instance().has_connectivity()) { - logger.log("Error sending first SMS."); + logger.log("No connectivity, waiting for 1.5 km mark."); } else { - logger.log("First SMS sent."); + logger.log("GSM connected."); + + logger.log("Trying to send first SMS..."); + if ( ! GSM::get_instance().send_SMS("2.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending first SMS."); + } + else + { + logger.log("First SMS sent."); + } } - while (GPS::get_instance().get_altitude() > 1500) + while (GPS::get_instance().get_altitude() > 1500)// && ! has_landed()) { this_thread::sleep_for(5s); } - logger.log("1.5 km mark."); - logger.log("Trying to send second SMS..."); - if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - { - logger.log("Error sending second SMS."); - } - else + // if ( ! has_landed()) + // { + logger.log("1.5 km mark."); + + if ( ! GSM::get_instance().is_up()) + { + logger.log("GSM is off. Turning on GSM..."); + GSM::get_instance().turn_on(); + count = 0; + while ( ! GSM::get_instance().is_up()) + { + if (count > 5) break; + this_thread::sleep_for(1s); + ++count; + }; + + if (GSM::get_instance().is_up()) + logger.log("GSM on."); + else + logger.log("GSM has not turned on yet, not waiting anymore."); + } + + count = 0; + while ( ! GSM::get_instance().has_connectivity()) + { + if (count > 15) break; + this_thread::sleep_for(1s); + ++count; + } + if ( ! GSM::get_instance().has_connectivity()) + { + logger.log("No connectivity, waiting for 500 m mark or landing."); + } + else + { + logger.log("GSM connected."); + + logger.log("Trying to send second SMS..."); + if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending second SMS."); + } + else + { + logger.log("Second SMS sent."); + } + } + // } + + while ( ! has_landed() && GPS::get_instance().get_altitude() > 500) { - logger.log("Second SMS sent."); + this_thread::sleep_for(5s); } - while ( ! has_landed() && GPS::get_instance().get_altitude() > 500); if ( ! has_landed()) { logger.log("500 m mark."); - logger.log("Trying to send third SMS..."); - if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + + if ( ! GSM::get_instance().is_up()) { - logger.log("Error sending third SMS."); + logger.log("GSM is off. Turning on GSM..."); + GSM::get_instance().turn_on(); + count = 0; + while ( ! GSM::get_instance().is_up()) + { + if (count > 5) break; + this_thread::sleep_for(1s); + ++count; + }; + + if (GSM::get_instance().is_up()) + logger.log("GSM on."); + else + logger.log("GSM has not turned on yet, not waiting anymore."); + } + + count = 0; + while ( ! GSM::get_instance().has_connectivity()) + { + if (count > 15) break; + this_thread::sleep_for(1s); + ++count; + } + if ( ! GSM::get_instance().has_connectivity()) + { + logger.log("No connectivity, waiting for landing."); } else { - logger.log("Third SMS sent."); + logger.log("GSM connected."); + + logger.log("Trying to send third SMS..."); + if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger.log("Error sending third SMS."); + } + else + { + logger.log("Third SMS sent."); + } } } - while ( ! has_landed()); + while ( ! has_landed()) + { + this_thread::sleep_for(5s); + } logger.log("Landed."); state = set_state(LANDED); logger.log("State changed to "+ state_to_string(state) +"."); @@ -356,13 +563,24 @@ int main(void) logger.log("Sending second landed SMS..."); while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE) && + main_battery >= 0.05 && gsm_battery >= 0.05) { logger.log("Error sending second SMS, trying again in 5 minutes."); this_thread::sleep_for(5min); + GSM::get_instance().get_battery_status(main_battery, gsm_battery); } - logger.log("Second SMS sent."); + if (main_battery < 0.05 || gsm_battery < 0.05) + { + logger.log("Not enough battery."); + logger.log("Main battery: "+ to_string(main_battery) + + "% - GSM battery: "+ to_string(gsm_battery) +"%"); + } + else + { + logger.log("Second SMS sent."); + } logger.log("Shutting down..."); state = set_state(SHUT_DOWN); @@ -371,17 +589,27 @@ int main(void) } logger.log("Turning GSM off..."); - GSM::get_instance().turn_off(); - logger.log("GSM off."); + if (GSM::get_instance().turn_off()) + logger.log("GSM off."); + else + logger.log("Error turning GSM off."); + + logger.log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger.log("GPS off."); + else + logger.log("Error turning GPS off."); logger.log("Joining threads..."); + picture_thread.join(); gps_thread.join(); + battery_thread.join(); logger.log("Threads joined."); logger.log("Deleting objects..."); delete &GPS::get_instance(); delete &GSM::get_instance(); - delete &Camera::get_instance(); + // delete &Camera::get_instance(); logger.log("Objects deleted."); logger.log("Powering off..."); sync(); @@ -419,14 +647,89 @@ void os::gps_thread_fn(State& state) to_string(GPS::get_instance().get_altitude()) +", Speed: "+ to_string(GPS::get_instance().get_velocity().speed) +", Course: "+ to_string(GPS::get_instance().get_velocity().course) +", Sat: "+ - to_string(GPS::get_instance().get_satellites()) +", HDOP: "+ - to_string(GPS::get_instance().get_HDOP()) +", VDOP: "+ - to_string(GPS::get_instance().get_VDOP())); + to_string(GPS::get_instance().get_satellites()) +", PDOP: "+ + to_string(GPS::get_instance().get_PDOP())); this_thread::sleep_for(250ms); } } +void os::picture_thread_fn(State& state) +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + Logger logger("data/logs/camera/Pictures."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "Pictures"); + + logger.log("Waiting for launch..."); + + while (state != GOING_UP) + { + this_thread::sleep_for(10s); + } + + logger.log("Launched, waiting 2 minutes for first picture..."); + this_thread::sleep_for(2min); + + while (state == GOING_UP) + { + logger.log("Taking picture..."); + + if ( ! Camera::get_instance().take_picture(generate_exif_data())) + { + logger.log("Error taking picture. Trying again in 30 seconds..."); + } + else + { + logger.log("Picture taken correctly. Next picture in 30 seconds..."); + } + + this_thread::sleep_for(30s); + logger.log("Taking picture..."); + + if ( ! Camera::get_instance().take_picture(generate_exif_data())) + { + logger.log("Error taking picture. Next picture in 4 minutes..."); + } + else + { + logger.log("Picture taken correctly. Next picture in 4 minutes..."); + } + + this_thread::sleep_for(4min); + } + + logger.log("Going down, no more pictures are being taken, picture thread is closing."); +} + +void os::battery_thread_fn(State& state) +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + Logger logger("data/logs/GSM/Battery."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "Battery"); + + double main_battery, gsm_battery; + + while (state != SHUT_DOWN) + { + if (GSM::get_instance().get_status()) + { + GSM::get_instance().get_battery_status(main_battery, gsm_battery); + logger.log("Main: "+ to_string(main_battery)); + logger.log("GSM: "+ to_string(gsm_battery)); + } + + this_thread::sleep_for(3min); + } +} + State os::set_state(State new_state) { ofstream state_file(STATE_FILE); @@ -455,7 +758,7 @@ State os::get_state() return RECOVERY; } -string os::state_to_string(State state) +const string os::state_to_string(State state) { switch (state) { @@ -517,3 +820,29 @@ bool os::has_landed() return true; // return first_altitude-second_altitude < 5; } + +const string os::generate_exif_data() +{ + string exif; + while (GPS::get_instance().get_PDOP() > 5) + { + this_thread::sleep_for(1s); + } + double gps_lat = GPS::get_instance().get_latitude(); + double gps_lon = GPS::get_instance().get_longitude(); + double gps_alt = GPS::get_instance().get_altitude(); + uint_fast8_t gps_sat = GPS::get_instance().get_satellites(); + float gps_pdop = GPS::get_instance().get_PDOP(); + euc_vec gps_velocity = GPS::get_instance().get_velocity(); + + exif += "GPSLatitudeRef="+to_string(gps_lat > 0 ? 'N' : 'S'); + exif += " GPSLatitude="+to_string(abs((int) gps_lat*1000000))+"/1000000,0/1,0/1"; + exif += " GPSLongitudeRef="+to_string(gps_lon > 0 ? 'E' : 'W'); + exif += " GPSLongitude="+to_string(abs((int) gps_lon*1000000))+"/1000000,0/1,0/1"; + exif += " GPSAltitudeRef=0 GPSAltitude="+to_string(gps_alt); + exif += " GPSSatellites="+to_string(gps_sat); + exif += " GPSDOP="+to_string(gps_pdop); + exif += " GPSSpeedRef=K GPSSpeed="+to_string(gps_velocity.speed*3.6); + exif += " GPSTrackRef=T GPSTrack="+to_string(gps_velocity.course); + exif += " GPSDifferential=0"; +} diff --git a/openstratos.h b/openstratos.h index 59539e6..a5884b1 100644 --- a/openstratos.h +++ b/openstratos.h @@ -1,7 +1,10 @@ #ifndef OPENSTRATOS_H_ #define OPENSTRATOS_H_ +#include + #include +#include #include #include #include @@ -39,12 +42,15 @@ namespace os inline bool file_exists(const string& name); inline float get_available_disk_space(); void gps_thread_fn(State& state); + void picture_thread_fn(State& state); + void battery_thread_fn(State& state); State set_state(State new_state); State get_state(); - string state_to_string(State state); + const string state_to_string(State state); bool has_launched(); bool has_bursted(); bool has_landed(); + const string generate_exif_data(); } using namespace std; diff --git a/temperature/Temperature.cc b/temperature/Temperature.cc deleted file mode 100644 index 78c702f..0000000 --- a/temperature/Temperature.cc +++ /dev/null @@ -1,71 +0,0 @@ -#include "temperature/Temperature.h" - -#include -#include - -#include - -#include "constants.h" - -using namespace std; -using namespace os; - -Temperature::~Temperature() -{ - if (this->reading) - this->stop_reading(); -} - -Temperature::Temperature(const int address) -{ - this->reading = false; - this->stopped = true; - #ifndef OS_TESTING - int fh = wiringPiI2CSetup(address); - if (fh != -1) - { - this->address = address; - this->filehandle = fh; - } - else - { - // TODO Log error - //printf("An error ocurred initializing I2C Temperature module\n"); - } - #endif -} - -void Temperature::start_reading() -{ - if ( ! this->reading) - { - this->reading = true; - this->stopped = false; - thread t(&Temperature::read_temperature, this); - t.detach(); - } -} - -void Temperature::stop_reading() -{ - this->reading = false; - while( ! this->stopped); -} - -void Temperature::read_temperature() -{ - while (this->reading) - { - #ifndef OS_TESTING - int value = wiringPiI2CRead(this->filehandle); - #else - int value = 16000; - #endif - - float voltage = value * 5 / 32768; // 2^15 - this->temperature = r_to_c(TEMP_R * (TEMP_VIN / voltage - 1)); - - this_thread::sleep_for(50ms); - } - this->stopped = true; -} diff --git a/temperature/Temperature.h b/temperature/Temperature.h deleted file mode 100644 index 3d943dd..0000000 --- a/temperature/Temperature.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef TEMPERATURE_TEMPERATURE_H_ -#define TEMPERATURE_TEMPERATURE_H_ - -#include -using namespace std; - -namespace os { - class Temperature - { - private: - int address; - int filehandle; - float temperature; - atomic_bool reading; - atomic_bool stopped; - - void read_temperature(); - public: - Temperature(const int address); - ~Temperature(); - Temperature(Temperature& copy) = delete; - - int get_temperature() {return this->temperature;} - void start_reading(); - void stop_reading(); - bool is_reading() {return this->reading;} - }; -} - -inline float r_to_c(float r) -{ - float value = r - 1000; - return (value / 3.91 + value * value / 100000); -} - -#endif // TEMPERATURE_TEMPERATURE_H_ diff --git a/testing/bandit b/testing/bandit index a856864..76f1e76 160000 --- a/testing/bandit +++ b/testing/bandit @@ -1 +1 @@ -Subproject commit a8568640859b1a15e8d6b0a7b9d42c9d6806088d +Subproject commit 76f1e76d9842d4bee1742ee2b01fdcceed3421d4 diff --git a/testing/camera_test.cc b/testing/camera_test.cc index 68e8519..ed4e12a 100644 --- a/testing/camera_test.cc +++ b/testing/camera_test.cc @@ -1,36 +1,35 @@ describe("Camera", [](){ it("recording test", [&](){ - Camera::get_instance().record(2000); + AssertThat(Camera::get_instance().record(2000), Equals(true)); AssertThat(Camera::get_instance().is_recording(), Equals(true)); this_thread::sleep_for(2.5s); AssertThat(Camera::get_instance().is_recording(), Equals(false)); #ifdef RASPICAM - remove("data/video/video-"+ to_string(get_file_count("data/video/")-1) +".h264"); + remove("data/video/test.h264"); #endif }); it("recording and stopping test", [&](){ - Camera::get_instance().record(); + AssertThat(Camera::get_instance().record(), Equals(true)); AssertThat(Camera::get_instance().is_recording(), Equals(true)); this_thread::sleep_for(2s); AssertThat(Camera::get_instance().stop(), Equals(true)); - AssertThat(Camera::get_instance().is_recording(), Equals(false)); #ifdef RASPICAM - remove("data/video/video-"+ to_string(get_file_count("data/video/")-1) +".h264"); + remove("data/video/test.h264"); #endif }); it("picture taking test", [&](){ - AssertThat(Camera::get_instance().record(), Equals(true)); + AssertThat(Camera::get_instance().take_picture(), Equals(true)); #ifdef RASPICAM - remove("data/img/img-"+ to_string(get_file_count("data/img/")-1) +".jpg"); + remove("data/img/test.jpg"); #endif }); @@ -51,12 +50,12 @@ describe("Camera", [](){ #ifdef RASPICAM it("picture file creation test", [&](){ - start_file_count = get_file_count("data/img/"); + int start_file_count = get_file_count("data/img/"); AssertThat(Camera::get_instance().take_picture(), Equals(true)); - end_file_count = get_file_count("data/img/"); + int end_file_count = get_file_count("data/img/"); AssertThat(end_file_count, Equals(start_file_count+1)); - remove("data/img/img-"+ to_string(get_file_count("data/img/")-1) +".jpg"); + remove(("data/img/img-"+ to_string(get_file_count("data/img/")-1) +".jpg").c_str()); }); #else it_skip("picture file creation test", [&](){}); diff --git a/testing/gps_test.cc b/testing/gps_test.cc index 7024140..25457a4 100644 --- a/testing/gps_test.cc +++ b/testing/gps_test.cc @@ -1,7 +1,7 @@ describe("GPS", [](){ before_each([&](){ - GPS::get_instance().initialize(""); + GPS::get_instance().initialize(); }); it("Knots to m/s conversion test", [&](){ diff --git a/testing/testing.cc b/testing/testing.cc index 8792a1a..712b2d1 100644 --- a/testing/testing.cc +++ b/testing/testing.cc @@ -8,14 +8,13 @@ #include "constants.h" #include "camera/Camera.h" -#include "temperature/Temperature.h" #include "gps/GPS.h" -#include "battery/Battery.h" using namespace bandit; using namespace os; using namespace std; +inline bool file_exists(const string& name); int main(int argc, char* argv[]) { @@ -23,9 +22,30 @@ int main(int argc, char* argv[]) } go_bandit([](){ + if ( ! file_exists("data")) + mkdir("data", 0755); + + if ( ! file_exists("data/logs")) + { + mkdir("data/logs", 0755); + mkdir("data/logs/main", 0755); + mkdir("data/logs/camera", 0755); + mkdir("data/logs/GPS", 0755); + mkdir("data/logs/GSM", 0755); + } + + if ( ! file_exists("data/video")) + mkdir("data/video", 0755); + + if ( ! file_exists("data/img")) + mkdir("data/img", 0755); + #include "camera_test.cc" #include "gps_test.cc" - #include "temperature_test.cc" - #include "battery_test.cc" }); +inline bool file_exists(const string& name) +{ + struct stat buffer; + return stat(name.c_str(), &buffer) == 0; +} From ab7e993fcc6e9461b2e3c05fbc3b301c234069f1 Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 7 Aug 2015 02:08:27 +0200 Subject: [PATCH 071/169] Added sleep in serial close for stability. --- serial/Serial.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index b413f83..7307c0e 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -114,7 +114,8 @@ void Serial::close() { if (this->open) { this->open = false; - while( ! this->stopped); + while( ! this->stopped) + this_thread::sleep_for(1ms); #ifndef OS_TESTING serialClose(this->fd); From 3668126073d855d1a56d60decd001a2c66e62c8a Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 7 Aug 2015 02:25:25 +0200 Subject: [PATCH 072/169] Fixed build --- install-wiringpi.sh | 4 ++-- openstratos.cc | 22 +++++++++++----------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/install-wiringpi.sh b/install-wiringpi.sh index 9026a01..89ceca6 100644 --- a/install-wiringpi.sh +++ b/install-wiringpi.sh @@ -3,5 +3,5 @@ printf "Installing WiringPi\n" git clone https://github.com/OpenStratos/WiringPi.git > /dev/null cd WiringPi -./build > /dev/null -cd .. \ No newline at end of file +sudo ./build > /dev/null +cd .. diff --git a/openstratos.cc b/openstratos.cc index d67957f..4d1b06a 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -155,19 +155,19 @@ int main(void) { logger.log("Error: Not enough battery."); - logger.log("Turning GSM off..."); - if (GSM::get_instance().turn_off()) - logger.log("GSM off."); - else - logger.log("Error turning GSM off."); + // logger.log("Turning GSM off..."); + // if (GSM::get_instance().turn_off()) + // logger.log("GSM off."); + // else + // logger.log("Error turning GSM off."); - logger.log("Turning GPS off..."); - if (GPS::get_instance().turn_off()) - logger.log("GPS off."); - else - logger.log("Error turning GPS off."); + // logger.log("Turning GPS off..."); + // if (GPS::get_instance().turn_off()) + // logger.log("GPS off."); + // else + // logger.log("Error turning GPS off."); - exit(1); + // exit(1); } logger.log("Waiting for GSM connectivity..."); From 233ef1a60c00b182c8bb23ebd522ff4ed5107c9c Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 8 Aug 2015 22:30:03 +0200 Subject: [PATCH 073/169] Added USB powering mode --- openstratos.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 4d1b06a..663aff2 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -151,7 +151,7 @@ int main(void) logger.log("Batteries checked => Main battery: "+ to_string(main_battery) + "% - GSM battery: "+ to_string(gsm_battery) +"%"); - if (main_battery < 0.95 || gsm_battery < 0.95) + if ((main_battery < 0.95 && main_battery > -1) || gsm_battery < 0.95) { logger.log("Error: Not enough battery."); @@ -564,14 +564,14 @@ int main(void) while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE) && - main_battery >= 0.05 && gsm_battery >= 0.05) + (main_battery >= 0.05 || main_battery < -1) && gsm_battery >= 0.05) { logger.log("Error sending second SMS, trying again in 5 minutes."); this_thread::sleep_for(5min); GSM::get_instance().get_battery_status(main_battery, gsm_battery); } - if (main_battery < 0.05 || gsm_battery < 0.05) + if ((main_battery < 0.05 && main_battery > -1) || gsm_battery < 0.05) { logger.log("Not enough battery."); logger.log("Main battery: "+ to_string(main_battery) + From 0b5668227ecf3beebab6b8b53e0815284ad986b5 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 8 Aug 2015 22:33:40 +0200 Subject: [PATCH 074/169] Fixed GSM serial --- serial/Serial.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index 7307c0e..92afa84 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -51,7 +51,7 @@ bool Serial::initialize(const string& url, int baud) } this->open = true; - this->stopped = false; + this->stopped = true; return true; } From d85618c916699a7a83f0e1b77ec46af2232dbfb7 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 8 Aug 2015 23:37:12 +0200 Subject: [PATCH 075/169] Better logging and trying to fix SMSs (#20). --- gsm/GSM.cc | 18 +++++++++++++----- openstratos.cc | 22 +++++++++++----------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index e16f1fd..55e61b4 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -84,7 +84,8 @@ bool GSM::send_SMS(const string& message, const string& number) const return false; } - this->send_command(message+"\x1a\r\n"); + this->serial.flush(); + this->send_command_read(message+"\x1a\r\n"); this->serial.flush(); this->logger->log("SMS sent."); @@ -115,7 +116,7 @@ bool GSM::get_status() const bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage) const { - this->logger->log("Checking Battery status..."); + this->logger->log("Checking Battery status."); if (this->get_status()) { string gsm_response = this->send_command_read("AT+CBC"); @@ -139,9 +140,6 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen gsm_bat_percentage = (gsm_bat_voltage/1000.0-BAT_GSM_MIN)/(BAT_GSM_MAX-BAT_GSM_MIN); main_bat_percentage = (main_bat_voltage/1000.0-BAT_MAIN_MIN)/(BAT_MAIN_MAX-BAT_MAIN_MIN); - this->logger->log("Main battery percentage: "+ to_string(main_bat_percentage) + - "% - GSM battery percentage: "+ to_string(gsm_bat_percentage) +"%"); - return true; } } @@ -167,14 +165,19 @@ bool GSM::turn_on() const { if ( ! this->get_status()) { + this->logger->log("Turning GSM on..."); + digitalWrite(GSM_PWR_GPIO, LOW); this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, HIGH); this_thread::sleep_for(500ms); + + this->logger->log("GSM on."); return true; } else { + this->logger->log("Error: Turning on GSM but GSM already on."); return false; } } @@ -183,14 +186,19 @@ bool GSM::turn_off() const { if (this->get_status()) { + this->logger->log("Turning GSM off..."); + digitalWrite(GSM_PWR_GPIO, LOW); this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, HIGH); this_thread::sleep_for(500ms); + + this->logger.log("GSM off."); return true; } else { + this->logger->log("Error: Turning off GSM but GSM already off."); return false; } } diff --git a/openstratos.cc b/openstratos.cc index 663aff2..84a98bc 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -155,19 +155,19 @@ int main(void) { logger.log("Error: Not enough battery."); - // logger.log("Turning GSM off..."); - // if (GSM::get_instance().turn_off()) - // logger.log("GSM off."); - // else - // logger.log("Error turning GSM off."); + logger.log("Turning GSM off..."); + if (GSM::get_instance().turn_off()) + logger.log("GSM off."); + else + logger.log("Error turning GSM off."); - // logger.log("Turning GPS off..."); - // if (GPS::get_instance().turn_off()) - // logger.log("GPS off."); - // else - // logger.log("Error turning GPS off."); + logger.log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger.log("GPS off."); + else + logger.log("Error turning GPS off."); - // exit(1); + exit(1); } logger.log("Waiting for GSM connectivity..."); From 5376f8d9f804d5f966bbfb6a85df32b501f7d4b5 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 8 Aug 2015 23:42:37 +0200 Subject: [PATCH 076/169] Fixed logger call --- gsm/GSM.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 55e61b4..181d404 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -193,7 +193,7 @@ bool GSM::turn_off() const digitalWrite(GSM_PWR_GPIO, HIGH); this_thread::sleep_for(500ms); - this->logger.log("GSM off."); + this->logger->log("GSM off."); return true; } else From 1bf26fa815921dcd932cd6a9387eadd8797f969b Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 9 Aug 2015 00:04:07 +0200 Subject: [PATCH 077/169] Some polishing. Should be easier to spot errors, and should be more stable and reliable. --- gsm/GSM.cc | 5 +---- openstratos.cc | 24 ++++++++++++++++++------ serial/Serial.cc | 10 ++-------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 181d404..329f55d 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -85,7 +85,7 @@ bool GSM::send_SMS(const string& message, const string& number) const } this->serial.flush(); - this->send_command_read(message+"\x1a\r\n"); + this->send_command_read(message+'\x1A'); this->serial.flush(); this->logger->log("SMS sent."); @@ -122,10 +122,7 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen string gsm_response = this->send_command_read("AT+CBC"); string adc_response = this->send_command_read("AT+CADC?"); while (adc_response.substr(0, 6) != "+CADC:") - { - this->logger->log("OK received, reading next line..."); adc_response = this->serial.read_line(); - } if (gsm_response.substr(0, 5) == "+CBC:" && adc_response.substr(0, 6) == "+CADC:") { diff --git a/openstratos.cc b/openstratos.cc index 84a98bc..2a8a177 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -383,9 +383,15 @@ int main(void) }; if (GSM::get_instance().is_up()) + { logger.log("GSM on."); + + this_thread::sleep_for(3s); // Sleeping for letting GSM initialize + } else + { logger.log("GSM has not turned on yet, not waiting anymore."); + } logger.log("Waiting for GSM connectivity..."); count = 0; @@ -436,9 +442,15 @@ int main(void) }; if (GSM::get_instance().is_up()) + { logger.log("GSM on."); + + this_thread::sleep_for(3s); // Sleeping for letting GSM initialize + } else + { logger.log("GSM has not turned on yet, not waiting anymore."); + } } count = 0; @@ -491,9 +503,15 @@ int main(void) }; if (GSM::get_instance().is_up()) + { logger.log("GSM on."); + + this_thread::sleep_for(3s); // Sleeping for letting GSM initialize + } else + { logger.log("GSM has not turned on yet, not waiting anymore."); + } } count = 0; @@ -605,12 +623,6 @@ int main(void) gps_thread.join(); battery_thread.join(); logger.log("Threads joined."); - - logger.log("Deleting objects..."); - delete &GPS::get_instance(); - delete &GSM::get_instance(); - // delete &Camera::get_instance(); - logger.log("Objects deleted."); logger.log("Powering off..."); sync(); // reboot(RB_POWER_OFF); diff --git a/serial/Serial.cc b/serial/Serial.cc index 92afa84..0103cd8 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -64,7 +64,6 @@ Serial::~Serial() void Serial::gps_thread() { string response; - bool endl_found = false; while(this->open) { @@ -77,8 +76,7 @@ void Serial::gps_thread() { char c = serialGetchar(this->fd); response += c; - if (c == '\r') endl_found = true; - if (endl_found && c == '\n') + if (response[response.length()-1] == '\r' && c == '\n') { response = response.substr(0, response.length()-2); @@ -87,7 +85,6 @@ void Serial::gps_thread() GPS::get_instance().parse(response); } response = ""; - endl_found = false; this_thread::sleep_for(50ms); } } @@ -136,7 +133,6 @@ const string Serial::read_line() const int available = serialDataAvail(this->fd); struct timeval t1, t2; double elapsed_time = 0; - bool endl_found = false; while (true) { @@ -162,8 +158,7 @@ const string Serial::read_line() const char c = serialGetchar(this->fd); response += c; - if (c == '\r') endl_found = true; - if (endl_found && c == '\n') + if (response[response.length()-1] == '\r' && c == '\n') { return response.substr(0, response.length()-2); } @@ -178,7 +173,6 @@ bool Serial::read_only(const string& only) const int available = serialDataAvail(this->fd); struct timeval t1, t2; double elapsed_time = 0; - bool endl_found = false; while (true) { From a4d9aa97dbe9c3e029ff1f839aa08f1aa1f17459 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 9 Aug 2015 00:21:09 +0200 Subject: [PATCH 078/169] Better logging in read_only GSM command --- gsm/GSM.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 329f55d..f1d9251 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -241,9 +241,10 @@ bool GSM::send_command_read_only(const string& command, const string& only) cons this->serial.read_line(); bool response = this->serial.read_only(only); if (response) - { this->command_logger->log("Received: '"+only+"'"); - } + else + this->command_logger->log("Error: not received '"+only+"'") + this->serial.flush(); return response; } From d2e63380ed6c656de653f9aba3652f72b8c2474b Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 9 Aug 2015 00:22:35 +0200 Subject: [PATCH 079/169] Fixed syntax error --- gsm/GSM.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index f1d9251..7df5635 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -243,7 +243,7 @@ bool GSM::send_command_read_only(const string& command, const string& only) cons if (response) this->command_logger->log("Received: '"+only+"'"); else - this->command_logger->log("Error: not received '"+only+"'") + this->command_logger->log("Error: not received '"+only+"'"); this->serial.flush(); return response; From 59079a7a54d47243076d154d643668c0027fbe34 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 9 Aug 2015 00:56:45 +0200 Subject: [PATCH 080/169] Fixed GSM on/off commands --- gsm/GSM.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 7df5635..c451f4a 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -164,9 +164,9 @@ bool GSM::turn_on() const { this->logger->log("Turning GSM on..."); - digitalWrite(GSM_PWR_GPIO, LOW); - this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, HIGH); + this_thread::sleep_for(2s); + digitalWrite(GSM_PWR_GPIO, LOW); this_thread::sleep_for(500ms); this->logger->log("GSM on."); @@ -185,9 +185,9 @@ bool GSM::turn_off() const { this->logger->log("Turning GSM off..."); - digitalWrite(GSM_PWR_GPIO, LOW); - this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, HIGH); + this_thread::sleep_for(2s); + digitalWrite(GSM_PWR_GPIO, LOW); this_thread::sleep_for(500ms); this->logger->log("GSM off."); From 11a5c37fb7fd38a3feb242e9fbeb7d73194fd8b9 Mon Sep 17 00:00:00 2001 From: Razican Date: Sun, 9 Aug 2015 01:16:57 +0200 Subject: [PATCH 081/169] (I hope finally) fixed GSM on/off switch --- gsm/GSM.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index c451f4a..5e10e02 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -60,6 +60,7 @@ bool GSM::initialize() to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GSMCommand"); pinMode(GSM_PWR_GPIO, OUTPUT); + digitalWrite(GSM_PWR_GPIO, HIGH); return true; } @@ -164,10 +165,9 @@ bool GSM::turn_on() const { this->logger->log("Turning GSM on..."); - digitalWrite(GSM_PWR_GPIO, HIGH); - this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, LOW); - this_thread::sleep_for(500ms); + this_thread::sleep_for(2s); + digitalWrite(GSM_PWR_GPIO, HIGH); this->logger->log("GSM on."); return true; @@ -185,10 +185,9 @@ bool GSM::turn_off() const { this->logger->log("Turning GSM off..."); - digitalWrite(GSM_PWR_GPIO, HIGH); - this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, LOW); - this_thread::sleep_for(500ms); + this_thread::sleep_for(2s); + digitalWrite(GSM_PWR_GPIO, HIGH); this->logger->log("GSM off."); return true; From 2f967350b70416848925a7c6fbf5a45606550267 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 19 Aug 2015 12:04:03 +0200 Subject: [PATCH 082/169] Re-enabled camera --- camera/Camera.cc | 30 +++++++++++++------------- constants.h | 2 +- openstratos.cc | 56 ++++++++++++++++++++++++------------------------ 3 files changed, 44 insertions(+), 44 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 004d28d..495c1e2 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -78,10 +78,10 @@ bool Camera::record(int time) + " -ex "+ VIDEO_EXPOSURE +" -br "+ to_string(VIDEO_BRIGHTNESS) +" &"; this->logger->log("Video command: '"+command+"'"); - // #ifndef RASPICAM + #ifndef RASPICAM this->logger->log("Test mode, video recording simulated."); command = ""; - // #endif + #endif int st = system(command.c_str()); this->recording = true; @@ -129,10 +129,10 @@ bool Camera::take_picture(const string& exif) this->logger->log("Picture command: '"+command+"'"); - // #ifndef RASPICAM + #ifndef RASPICAM this->logger->log("Test mode, picture taking simulated."); command = ""; - // #endif + #endif int st = system(command.c_str()); bool result = st == 0; @@ -159,20 +159,20 @@ bool Camera::take_picture() bool Camera::stop() { this->logger->log("Stopping video recording..."); - // #ifdef RASPICAM - // if (system("pkill raspivid") == 0) - // { - // this->logger->log("Video recording stopped correctly."); - // this->recording = false; - // return true; - // } - // this->logger->log("Error stopping video recording."); - // return false; - // #else + #ifdef RASPICAM + if (system("pkill raspivid") == 0) + { + this->logger->log("Video recording stopped correctly."); + this->recording = false; + return true; + } + this->logger->log("Error stopping video recording."); + return false; + #else this->logger->log("Test mode. Video recording stop simulated."); this->recording = false; return true; - // #endif + #endif } int os::get_file_count(const string& path) diff --git a/constants.h b/constants.h index f165275..85e19aa 100644 --- a/constants.h +++ b/constants.h @@ -1,7 +1,7 @@ #ifndef CONSTANTS_H_ #define CONSTANTS_H_ - #define FLIGHT_LENGTH 3.5 + #define FLIGHT_LENGTH 4.8 // Hours #define BAT_GSM_MAX 4.2 #define BAT_GSM_MIN 3.7 diff --git a/openstratos.cc b/openstratos.cc index 2a8a177..301a07f 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -98,7 +98,7 @@ int main(void) if (get_available_disk_space() < FLIGHT_LENGTH*9437184000) // 1.25 times the flight length { logger.log("Error: Not enough disk space."); - // exit(1); + exit(1); } logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7549747200) + @@ -195,36 +195,36 @@ int main(void) exit(1); } this_thread::sleep_for(11s); - // if (file_exists("data/video/test.h264")) - // { + if (file_exists("data/video/test.h264")) + { logger.log("Camera test OK."); logger.log("Removing test file..."); - // if (remove("data/video/test.h264")) - // { - // logger.log("Error removing test file."); - // } - // else - // { + if (remove("data/video/test.h264")) + { + logger.log("Error removing test file."); + } + else + { logger.log("Test file removed."); - // } - // } - // else - // { - // logger.log("Test recording error."); - // logger.log("Turning GSM off..."); - // if (GSM::get_instance().turn_off()) - // logger.log("GSM off."); - // else - // logger.log("Error turning GSM off."); - - // logger.log("Turning GPS off..."); - // if (GPS::get_instance().turn_off()) - // logger.log("GPS off."); - // else - // logger.log("Error turning GPS off."); - - // exit(1); - // } + } + } + else + { + logger.log("Test recording error."); + logger.log("Turning GSM off..."); + if (GSM::get_instance().turn_off()) + logger.log("GSM off."); + else + logger.log("Error turning GSM off."); + + logger.log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger.log("GPS off."); + else + logger.log("Error turning GPS off."); + + exit(1); + } state = set_state(ACQUIRING_FIX); logger.log("State changed to "+ state_to_string(state) +"."); From 74aef9a3cea644cf88f70690fde18b739524151a Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 19 Aug 2015 21:02:05 +0200 Subject: [PATCH 083/169] Refactored GSM code --- gps/GPS.cc | 4 +- gsm/GSM.cc | 139 ++++++++++++++++++++++++++++------------------- openstratos.cc | 11 ---- serial/Serial.cc | 85 +++++++++++------------------ serial/Serial.h | 5 +- 5 files changed, 122 insertions(+), 122 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index d3d2fe5..b8ff076 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -67,9 +67,9 @@ bool GPS::initialize() pinMode(GPS_ENABLE_GPIO, OUTPUT); this->logger->log("Sending configuration frames..."); - this->serial.send("$PMTK220,100*2F"); + this->serial.println("$PMTK220,100*2F"); this->frame_logger->log("Sent: $PMTK220,100*2F"); - this->serial.send("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->serial.println("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); this->frame_logger->log("Sent: $PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); this->logger->log("Configuration frames sent."); #endif diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 5e10e02..24050c6 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -22,6 +22,7 @@ GSM& GSM::get_instance() GSM::~GSM() { + this->turn_off(); if (this->serial.is_open()) { this->logger->log("Closing serial interface..."); @@ -47,6 +48,33 @@ bool GSM::initialize() to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GSM"); + this->command_logger = new Logger("data/logs/GSM/GSMCommands."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GSMCommand"); + + pinMode(GSM_PWR_GPIO, OUTPUT); + digitalWrite(GSM_PWR_GPIO, HIGH); + pinMode(GSM_STATUS_GPIO, INPUT); + + this->logger->log("Rebooting module for stability."); + this->turn_off(); + this->logger->log("Module off. Sleeping 3 seconds before turning it on..."); + this_thread::sleep_for(3s); + + this->logger->log("Turning module on..."); + this->turn_on(); + this->logger->log("Module on. Sleeping 3 seconds to let it turn completely on..."); + this_thread::sleep_for(3s); + if (this->get_status()) + { + this->logger->log("Status checked. Module is on."); + } + else + { + this->logger->log("Error: Status checked. Module is off. Finishing initialization."); + return false; + } + this->logger->log("Starting serial connection..."); if ( ! this->serial.initialize(GSM_UART, GSM_BAUDRATE)) { @@ -55,39 +83,77 @@ bool GSM::initialize() } this->logger->log("Serial connection started."); - this->command_logger = new Logger("data/logs/GSM/GSMCommands."+ to_string(now->tm_year+1900) +"-"+ - to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ - to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GSMCommand"); + this->logger->log("Deleting possible serial characters..."); + this->serial.flush(); + + this->logger->log("Checking OK initialization (3 times)..."); + if (this->send_command_read("AT") != "OK") + { + this->logger->log("Error on initialization."); + return false; + } + this_thread::sleep_for(100ms); + + if (this->send_command_read("AT") != "OK") + { + this->logger->log("Error on initialization."); + return false; + } + this_thread::sleep_for(100ms); + + if (this->send_command_read("AT") != "OK") + { + this->logger->log("Error on initialization."); + return false; + } + this_thread::sleep_for(100ms); + this->logger->log("Initialization OK."); + + this->logger->log("Turning echo off..."); + if (this->send_command_read("ATE0") != "OK") + { + this->logger->log("Error turning echo off."); + return false; + } + this_thread::sleep_for(100ms); + this->logger->log("Echo is off."); - pinMode(GSM_PWR_GPIO, OUTPUT); - digitalWrite(GSM_PWR_GPIO, HIGH); return true; } bool GSM::send_SMS(const string& message, const string& number) const { this->logger->log("Sending SMS: \""+message+"\" to number "+number+"."); - - this->serial.flush(); if (this->send_command_read("AT+CMGF=1") != "OK") { this->logger->log("Error sending SMS"); return false; } - stringstream send_command; + string send_command = "AT+CMGS=\""+number+"\""; + if (this->send_command_read(send_command) != "> ") + { + this->logger->log("Error sending SMS"); + return false; + } - send_command << "AT+CMGS=\"" << number << "\""; + this->serial.println(message); + this->serial.println(); + this->serial.write(to_string((char) 0x1A)); - if ( ! this->send_command_read_only(send_command.str(), ">")) + // Read line (timeout 10 seconds) + if (this->serial.read_line(10).find("+CMGS") == string::npos) { - this->logger->log("Error sending SMS."); + this->logger->log("Error sending SMS"); return false; } - this->serial.flush(); - this->send_command_read(message+'\x1A'); - this->serial.flush(); + // Read line (timeout 10 seconds) + if (this->serial.read_line(10) != "OK") + { + this->logger->log("Error sending SMS"); + return false; + } this->logger->log("SMS sent."); return true; @@ -148,11 +214,6 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen return false; } -bool GSM::is_up() const -{ - return this->send_command_read_only("AT", "OK"); -} - bool GSM::has_connectivity() const { string response = this->send_command_read("AT+CREG?"); @@ -201,16 +262,10 @@ bool GSM::turn_off() const bool GSM::init_GPRS() const { - if (this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") != "OK" || + return !(this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") != "OK" || this->send_command_read("AT+SAPBR=3,1,\"APN\",\"" + string(GSM_LOC_SERV) + ";") != "OK" || this->send_command_read("AT+SAPBR=1,1") != "OK" || - this->send_command_read("AT+SAPBR=2,1") != "OK") - { - this->serial.flush(); - return false; - } - this->serial.flush(); - return true; + this->send_command_read("AT+SAPBR=2,1") != "OK"); } bool GSM::tear_down_GPRS() const @@ -222,37 +277,9 @@ const string GSM::send_command_read(const string& command) const { this->command_logger->log("Sent: '"+command+"'"); this->serial.flush(); - this->serial.send(command); + this->serial.println(command); // Sent command - this->serial.read_line(); string response = this->serial.read_line(); this->command_logger->log("Received: '"+response+"'"); - this->serial.flush(); return response; } - -bool GSM::send_command_read_only(const string& command, const string& only) const -{ - this->command_logger->log("Sent: '"+command+"'"); - this->serial.flush(); - this->serial.send(command); - // Sent command - this->serial.read_line(); - bool response = this->serial.read_only(only); - if (response) - this->command_logger->log("Received: '"+only+"'"); - else - this->command_logger->log("Error: not received '"+only+"'"); - - this->serial.flush(); - return response; -} - -void GSM::send_command(const string& command) const -{ - this->command_logger->log("Sent: '"+command+"'"); - this->serial.flush(); - this->serial.send(command); - this_thread::sleep_for(25ms); - this->serial.flush(); -} diff --git a/openstratos.cc b/openstratos.cc index 301a07f..5db7973 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -134,17 +134,6 @@ int main(void) } logger.log("GSM initialized"); - logger.log("Turning on GSM..."); - GSM::get_instance().turn_on(); - this_thread::sleep_for(25ms); - while ( ! GSM::get_instance().is_up()) - { - this_thread::sleep_for(1s); - } - logger.log("GSM on."); - - this_thread::sleep_for(3s); // Sleeping for letting GSM initialize - logger.log("Checking batteries..."); double main_battery, gsm_battery; GSM::get_instance().get_battery_status(main_battery, gsm_battery); diff --git a/serial/Serial.cc b/serial/Serial.cc index 0103cd8..5531cac 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -102,11 +102,21 @@ void Serial::gps_thread() this->stopped = true; } -void Serial::send(const string& str) const +void Serial::println(const string& str) const { serialPuts(this->fd, (str+"\r\n").c_str()); } +void Serial::println() const +{ + serialPuts(this->fd, "\r\n"); +} + +void Serial::write(const string& str) const +{ + serialPuts(this->fd, str.c_str()); +} + void Serial::close() { if (this->open) { @@ -127,78 +137,49 @@ bool Serial::is_open() const string Serial::read_line() const { - string response; + return this->read_line(0.5); +} + +const string Serial::read_line(double timeout) const +{ + string response = ""; #ifndef OS_TESTING - int available = serialDataAvail(this->fd); struct timeval t1, t2; double elapsed_time = 0; + gettimeofday(&t1, NULL); while (true) { - gettimeofday(&t1, NULL); - while (available == 0) - { - this_thread::sleep_for(25ms); - gettimeofday(&t2, NULL); - elapsed_time = (t2.tv_sec - t1.tv_sec); - elapsed_time += (t2.tv_usec - t1.tv_usec) / 1000000.0; - - if (elapsed_time > 5) return ""; - available = serialDataAvail(this->fd); - } + gettimeofday(&t2, NULL); + elapsed_time = (t2.tv_sec - t1.tv_sec); + elapsed_time += (t2.tv_usec - t1.tv_usec) / 1000000.0; - if (available < 0) + if (elapsed_time > timeout) { - // TODO log error + // TODO log timeout error + break; } - for (int i = 0; i < available; i++) + while (serialDataAvail(this->fd) > 0) { char c = serialGetchar(this->fd); + if (c == '\r') continue; + if (c == '\n') { + if (response.length() == 0) // the first \n is ignored + continue; - response += c; - if (response[response.length()-1] == '\r' && c == '\n') - { - return response.substr(0, response.length()-2); + timeout = 0; // the second \n is the end of the line + break; } + + response += c; } } #endif return response; } -bool Serial::read_only(const string& only) const -{ - int available = serialDataAvail(this->fd); - struct timeval t1, t2; - double elapsed_time = 0; - - while (true) - { - gettimeofday(&t1, NULL); - while (available == 0) - { - this_thread::sleep_for(25ms); - gettimeofday(&t2, NULL); - elapsed_time = (t2.tv_sec - t1.tv_sec); - elapsed_time += (t2.tv_usec - t1.tv_usec) / 1000000.0; - - if (elapsed_time > 5) return false; - available = serialDataAvail(this->fd); - } - - if (available >= only.length()) - { - for (int i = 0; i < only.length(); i++) - { - if (serialGetchar(this->fd) != only[i]) return false; - } - return true; - } - } -} - void Serial::flush() const { serialFlush(this->fd); diff --git a/serial/Serial.h b/serial/Serial.h index 23f2724..3fe0a94 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -22,12 +22,15 @@ namespace os { Serial(Serial& copy) = delete; ~Serial(); - void send(const string& str) const; + void println(const string& str) const; + void println() const; + void write(const string& str) const; void close(); bool is_open(); bool initialize_GPS(); bool initialize(const string& serial_URL, int baud); const string read_line() const; + const string read_line(double timeout) const; bool read_only(const string& only) const; void flush() const; }; From dfa0dbd5490f193d81e4a51037c6bf2be752acb2 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 19 Aug 2015 21:20:17 +0200 Subject: [PATCH 084/169] Fixed some code --- gsm/GSM.cc | 4 ++++ openstratos.cc | 65 -------------------------------------------------- 2 files changed, 4 insertions(+), 65 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 24050c6..8dff1e4 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -230,6 +230,8 @@ bool GSM::turn_on() const this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, HIGH); + this_thread::sleep_for(3s); + this->logger->log("GSM on."); return true; } @@ -250,6 +252,8 @@ bool GSM::turn_off() const this_thread::sleep_for(2s); digitalWrite(GSM_PWR_GPIO, HIGH); + this_thread::sleep_for(3s); + this->logger->log("GSM off."); return true; } diff --git a/openstratos.cc b/openstratos.cc index 5db7973..9300d72 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -364,23 +364,6 @@ int main(void) logger.log("Turning on GSM..."); GSM::get_instance().turn_on(); count = 0; - while ( ! GSM::get_instance().is_up()) - { - if (count > 5) break; - this_thread::sleep_for(1s); - ++count; - }; - - if (GSM::get_instance().is_up()) - { - logger.log("GSM on."); - - this_thread::sleep_for(3s); // Sleeping for letting GSM initialize - } - else - { - logger.log("GSM has not turned on yet, not waiting anymore."); - } logger.log("Waiting for GSM connectivity..."); count = 0; @@ -418,30 +401,6 @@ int main(void) // { logger.log("1.5 km mark."); - if ( ! GSM::get_instance().is_up()) - { - logger.log("GSM is off. Turning on GSM..."); - GSM::get_instance().turn_on(); - count = 0; - while ( ! GSM::get_instance().is_up()) - { - if (count > 5) break; - this_thread::sleep_for(1s); - ++count; - }; - - if (GSM::get_instance().is_up()) - { - logger.log("GSM on."); - - this_thread::sleep_for(3s); // Sleeping for letting GSM initialize - } - else - { - logger.log("GSM has not turned on yet, not waiting anymore."); - } - } - count = 0; while ( ! GSM::get_instance().has_connectivity()) { @@ -479,30 +438,6 @@ int main(void) { logger.log("500 m mark."); - if ( ! GSM::get_instance().is_up()) - { - logger.log("GSM is off. Turning on GSM..."); - GSM::get_instance().turn_on(); - count = 0; - while ( ! GSM::get_instance().is_up()) - { - if (count > 5) break; - this_thread::sleep_for(1s); - ++count; - }; - - if (GSM::get_instance().is_up()) - { - logger.log("GSM on."); - - this_thread::sleep_for(3s); // Sleeping for letting GSM initialize - } - else - { - logger.log("GSM has not turned on yet, not waiting anymore."); - } - } - count = 0; while ( ! GSM::get_instance().has_connectivity()) { From 21b2e1cbe6be0b965ce66011770dbdb6d2608421 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 19 Aug 2015 21:31:02 +0200 Subject: [PATCH 085/169] Fixed initialization --- gsm/GSM.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 8dff1e4..a092910 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -284,6 +284,8 @@ const string GSM::send_command_read(const string& command) const this->serial.println(command); // Sent command string response = this->serial.read_line(); + if (response == command) + response = this->serial.read_line(); this->command_logger->log("Received: '"+response+"'"); return response; } From f3ab6fe8461ff2b24b47058ff8b953850fa0df1e Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 19 Aug 2015 21:39:51 +0200 Subject: [PATCH 086/169] Fixed percentage log --- openstratos.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 9300d72..e3ec35f 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -137,8 +137,8 @@ int main(void) logger.log("Checking batteries..."); double main_battery, gsm_battery; GSM::get_instance().get_battery_status(main_battery, gsm_battery); - logger.log("Batteries checked => Main battery: "+ to_string(main_battery) + - "% - GSM battery: "+ to_string(gsm_battery) +"%"); + logger.log("Batteries checked => Main battery: "+ to_string(main_battery*100) + + "% - GSM battery: "+ to_string(gsm_battery*100) +"%"); if ((main_battery < 0.95 && main_battery > -1) || gsm_battery < 0.95) { From 88dfe3342dbdc24c30b5cddfd87a895a4c799404 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 09:06:20 +0200 Subject: [PATCH 087/169] This should implement #31 --- serial/Serial.cc | 51 +++++++++++++++++++++++++++++++++++++++--------- serial/Serial.h | 4 ++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index 5531cac..dec21ee 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -41,6 +41,14 @@ bool Serial::initialize_GPS() bool Serial::initialize(const string& url, int baud) { + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + this->logger = new Logger("data/logs/GSM/Serial."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "GSMSerial"); + #ifndef OS_TESTING this->fd = serialOpen(url.c_str(), baud); #endif @@ -59,6 +67,7 @@ bool Serial::initialize(const string& url, int baud) Serial::~Serial() { this->close(); + delete this->logger; } void Serial::gps_thread() @@ -104,16 +113,19 @@ void Serial::gps_thread() void Serial::println(const string& str) const { + this->logger->log("Sent: '"+str+"\\r\\n'"); serialPuts(this->fd, (str+"\r\n").c_str()); } void Serial::println() const { + this->logger->log("Sent: '\\r\\n'"); serialPuts(this->fd, "\r\n"); } void Serial::write(const string& str) const { + this->logger->log("Sent: '"+str+"'"); serialPuts(this->fd, str.c_str()); } @@ -143,13 +155,16 @@ const string Serial::read_line() const const string Serial::read_line(double timeout) const { string response = ""; + string logstr = ""; + bool rfound = false, endl_found = false; + int available = 0; #ifndef OS_TESTING struct timeval t1, t2; double elapsed_time = 0; gettimeofday(&t1, NULL); - while (true) + while ( ! endl_found) { gettimeofday(&t2, NULL); elapsed_time = (t2.tv_sec - t1.tv_sec); @@ -157,26 +172,44 @@ const string Serial::read_line(double timeout) const if (elapsed_time > timeout) { - // TODO log timeout error + this->logger->log("Error: Serial timeout. ("+to_string(timeout)+" s)"); break; } - while (serialDataAvail(this->fd) > 0) + while (available = serialDataAvail(this->fd) > 0) { char c = serialGetchar(this->fd); - if (c == '\r') continue; - if (c == '\n') { - if (response.length() == 0) // the first \n is ignored - continue; - timeout = 0; // the second \n is the end of the line - break; + if (c == '\r') logstr += "\\r"; + else if (c == '\n') logstr += "\\n"; + else logstr += c; + + if (c == '\r') + { + rfound = true; + continue; + } + else if (c == '\n') + { + if (rfound) + { + endl_found = true; + break; + } } + rfound = false; response += c; } + + if (available < 0) + { + this->logger->log("Error: Serial available < 0."); + break; + } } #endif + this->logger->log("Received: '"+logstr+"\\r\\n'"); return response; } diff --git a/serial/Serial.h b/serial/Serial.h index 3fe0a94..6187c25 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -6,6 +6,8 @@ #include #include #include + +#include "logger/Logger.h" using namespace std; namespace os { @@ -16,6 +18,8 @@ namespace os { atomic_bool open; atomic_bool stopped; + Logger* logger; + void gps_thread(); public: Serial() = default; From a041c249d09535648e0eed49227d5794db2528ae Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 10:12:04 +0200 Subject: [PATCH 088/169] Fixed GPS serial initialization --- serial/Serial.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index dec21ee..0dc1292 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -24,6 +24,7 @@ bool Serial::initialize_GPS() if (this->fd == -1) { this->open = false; this->stopped = true; + return false; } @@ -36,6 +37,7 @@ bool Serial::initialize_GPS() this->stopped = true; #endif + this->logger = NULL; return true; } @@ -67,7 +69,7 @@ bool Serial::initialize(const string& url, int baud) Serial::~Serial() { this->close(); - delete this->logger; + if (this->logger) delete this->logger; } void Serial::gps_thread() From 61ef3810012bbdb63704ae01dd592f9e4c72759f Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 10:17:35 +0200 Subject: [PATCH 089/169] If GPS was of it would try to configure it giving segmentation fault --- gps/GPS.cc | 4 ++++ openstratos.cc | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index b8ff076..6e93e29 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -66,6 +66,10 @@ bool GPS::initialize() #ifndef OS_TESTING pinMode(GPS_ENABLE_GPIO, OUTPUT); + this->logger->log("Turning GPS on..."); + this->turn_on(); + this->logger->log("GPS on."); + this->logger->log("Sending configuration frames..."); this->serial.println("$PMTK220,100*2F"); this->frame_logger->log("Sent: $PMTK220,100*2F"); diff --git a/openstratos.cc b/openstratos.cc index e3ec35f..830ead9 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -116,10 +116,6 @@ int main(void) } logger.log("GPS initialized."); - logger.log("Turning on GPS..."); - GPS::get_instance().turn_on(); - logger.log("GPS on."); - logger.log("Initializing GSM..."); if ( ! GSM::get_instance().initialize()) { From 5dc40eabd489e617c077b7c96b9d45e984b9f139 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 10:31:35 +0200 Subject: [PATCH 090/169] Did not create logger for GPS serial --- serial/Serial.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index 0dc1292..35dc70a 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -18,6 +18,14 @@ using namespace os; bool Serial::initialize_GPS() { + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + this->logger = new Logger("data/logs/GPS/Serial."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "GPSSerial"); + #ifndef OS_TESTING this->fd = serialOpen(GPS_UART, GPS_BAUDRATE); @@ -69,7 +77,7 @@ bool Serial::initialize(const string& url, int baud) Serial::~Serial() { this->close(); - if (this->logger) delete this->logger; + delete this->logger; } void Serial::gps_thread() From 8c28dcae89f63aba9f5edbc0b1d01457ced3f058 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 10:37:00 +0200 Subject: [PATCH 091/169] Still shows segmentation fault --- serial/Serial.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/serial/Serial.cc b/serial/Serial.cc index 35dc70a..6f63270 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -38,6 +38,7 @@ bool Serial::initialize_GPS() this->open = true; this->stopped = false; + this->flush(); thread t(&Serial::gps_thread, this); t.detach(); #else @@ -98,6 +99,7 @@ void Serial::gps_thread() if (response[response.length()-1] == '\r' && c == '\n') { response = response.substr(0, response.length()-2); + this->logger->log("Received: '"+response+"\\r\\n'"); if (response.at(0) == '$') { From d6ff602fc6749bc4a92e5acf1806d351fd118d5d Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 10:51:31 +0200 Subject: [PATCH 092/169] Fixed segmentation fault (I hope so, at least) --- serial/Serial.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index 6f63270..4d6dc89 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -46,7 +46,6 @@ bool Serial::initialize_GPS() this->stopped = true; #endif - this->logger = NULL; return true; } @@ -116,7 +115,7 @@ void Serial::gps_thread() } else if (available < 0) { - // TODO log error + this->logger->log("Error: Serial available < 0."); } #endif } From cad5b6de90b1d26718ba95b2e61e656ec606e6b2 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 16:34:59 +0200 Subject: [PATCH 093/169] Added second try on empty commands --- gsm/GSM.cc | 2 +- serial/Serial.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index a092910..2ff4acf 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -284,7 +284,7 @@ const string GSM::send_command_read(const string& command) const this->serial.println(command); // Sent command string response = this->serial.read_line(); - if (response == command) + if (response == command || response == "") response = this->serial.read_line(); this->command_logger->log("Received: '"+response+"'"); return response; diff --git a/serial/Serial.cc b/serial/Serial.cc index 4d6dc89..36e4e88 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -220,7 +220,7 @@ const string Serial::read_line(double timeout) const } } #endif - this->logger->log("Received: '"+logstr+"\\r\\n'"); + this->logger->log("Received: '"+logstr+"'"); return response; } From e33680e3fbdf61b66961d91f0c6be5cdd6ca5d51 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 20 Aug 2015 16:42:51 +0200 Subject: [PATCH 094/169] Better logger output on batteries --- openstratos.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 830ead9..d0091e4 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -133,8 +133,8 @@ int main(void) logger.log("Checking batteries..."); double main_battery, gsm_battery; GSM::get_instance().get_battery_status(main_battery, gsm_battery); - logger.log("Batteries checked => Main battery: "+ to_string(main_battery*100) + - "% - GSM battery: "+ to_string(gsm_battery*100) +"%"); + logger.log("Batteries checked => Main battery: "+ (main_battery > -1 ? to_string(main_battery*100)+"%" : "disconnected") + + " - GSM battery: "+ to_string(gsm_battery*100) +"%"); if ((main_battery < 0.95 && main_battery > -1) || gsm_battery < 0.95) { From 5c3ca3ed88fe45e7b1230ca08cbd53528f067317 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 22 Aug 2015 15:30:49 +0200 Subject: [PATCH 095/169] Refactorized serial threads. Now better lose coupling --- gps/GPS.cc | 93 +++++++++++++++++++++++---- gps/GPS.h | 8 ++- gsm/GSM.cc | 32 ++++++---- gsm/GSM.h | 2 +- serial/Serial.cc | 123 ++++++++---------------------------- serial/Serial.h | 13 ++-- testing/battery_test.cc | 19 ------ testing/temperature_test.cc | 30 --------- 8 files changed, 138 insertions(+), 182 deletions(-) delete mode 100644 testing/battery_test.cc delete mode 100644 testing/temperature_test.cc diff --git a/gps/GPS.cc b/gps/GPS.cc index 6e93e29..73de1ac 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -6,6 +6,9 @@ #include #include #include +#include + +#include #include @@ -27,14 +30,26 @@ GPS& GPS::get_instance() GPS::~GPS() { - if (this->serial.is_open()) + if ( ! this->stopped) + { + this->logger->log("Stopping GPS thread..."); + this->should_stop = true; + while ( ! this->stopped) this_thread::sleep_for(1ms); + this->logger->log("GPS thread stopped"); + } + + if (this->serial->is_open()) { this->logger->log("Closing serial interface..."); - this->serial.close(); + this->serial->close(); this->logger->log("Serial interface closed."); + this->logger->log("Deallocating serial..."); + delete this->serial; + this->logger->log("Serial deallocated"); this->logger->log("Deallocating frame logger..."); delete this->frame_logger; + this->logger->log("Frame logger deallocated"); } this->logger->log("Turning off GPS..."); this->turn_off(); @@ -52,28 +67,39 @@ bool GPS::initialize() to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPS"); - this->logger->log("Starting serial connection..."); - if ( ! this->serial.initialize_GPS()) { - this->logger->log("GPS serial error."); - return false; - } - - this->logger->log("Serial connection started."); this->frame_logger = new Logger("data/logs/GPS/GPSFrames."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "GPSFrame"); + this->should_stop = false; + this->stopped = true; + #ifndef OS_TESTING pinMode(GPS_ENABLE_GPIO, OUTPUT); this->logger->log("Turning GPS on..."); this->turn_on(); this->logger->log("GPS on."); + #endif + + this->logger->log("Starting serial connection..."); + this->serial = new Serial(GPS_UART, GPS_BAUDRATE, "GPS"); + if ( ! this->serial->is_open()) { + this->logger->log("GPS serial error."); + return false; + } + this->logger->log("Serial connection started."); + + this->logger->log("Starting GPS frame thread..."); + thread t(&GPS::gps_thread, this); + t.detach(); + this->logger->log("GPS frame thread running."); + #ifndef OS_TESTING this->logger->log("Sending configuration frames..."); - this->serial.println("$PMTK220,100*2F"); + this->serial->println("$PMTK220,100*2F"); this->frame_logger->log("Sent: $PMTK220,100*2F"); - this->serial.println("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); + this->serial->println("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); this->frame_logger->log("Sent: $PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"); this->logger->log("Configuration frames sent."); #endif @@ -107,6 +133,51 @@ bool GPS::turn_off() const } } +void GPS::gps_thread() +{ + this->stopped = false; + string response; + + while( ! this->should_stop) + { + #ifndef OS_TESTING + int available = this->serial->available(); + + if (available > 0) + { + for (int i = 0; i < available; i++) + { + char c = this->serial->read_char(); + response += c; + if (response[response.length()-1] == '\r' && c == '\n') + { + response = response.substr(0, response.length()-2); + + if (response.at(0) == '$') + { + this->parse(response); + } + response = ""; + this_thread::sleep_for(50ms); + } + } + } + else if (available == 0) + { + this_thread::sleep_for(50ms); + } + else if (available < 0) + { + this->logger->log("Error: Serial available < 0."); + } + #else + this_thread::sleep_for(50ms); + #endif + } + this->logger->log("Should-stop flag noticed."); + this->stopped = true; +} + bool GPS::is_valid(string frame) { regex frame_regex("\\$[A-Z][0-9A-Z\\.,-]*\\*[0-9A-F]{1,2}"); diff --git a/gps/GPS.h b/gps/GPS.h index 33fed27..72c364c 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -4,6 +4,7 @@ #include #include +#include #include "serial/Serial.h" #include "logger/Logger.h" @@ -21,10 +22,13 @@ namespace os { class GPS { private: - Serial serial; + Serial* serial; Logger* logger; Logger* frame_logger; + atomic_bool should_stop; + atomic_bool stopped; + tm time; bool active; uint_fast8_t satellites; @@ -38,6 +42,8 @@ namespace os { GPS() = default; + void gps_thread(); + void parse_GGA(const string& frame); void parse_GSA(const string& frame); void parse_RMC(const string& frame); diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 2ff4acf..d14f4a0 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -23,11 +23,14 @@ GSM& GSM::get_instance() GSM::~GSM() { this->turn_off(); - if (this->serial.is_open()) + if (this->serial->is_open()) { this->logger->log("Closing serial interface..."); - this->serial.close(); + this->serial->close(); this->logger->log("Serial interface closed."); + this->logger->log("Deallocating serial..."); + delete this->serial; + this->logger->log("Serial deallocated"); this->logger->log("Deallocating command logger..."); delete this->command_logger; @@ -76,7 +79,8 @@ bool GSM::initialize() } this->logger->log("Starting serial connection..."); - if ( ! this->serial.initialize(GSM_UART, GSM_BAUDRATE)) + this->serial = new Serial(GSM_UART, GSM_BAUDRATE, "GSM"); + if ( ! this->serial->is_open()) { this->logger->log("GSM serial error."); return false; @@ -84,7 +88,7 @@ bool GSM::initialize() this->logger->log("Serial connection started."); this->logger->log("Deleting possible serial characters..."); - this->serial.flush(); + this->serial->flush(); this->logger->log("Checking OK initialization (3 times)..."); if (this->send_command_read("AT") != "OK") @@ -137,19 +141,19 @@ bool GSM::send_SMS(const string& message, const string& number) const return false; } - this->serial.println(message); - this->serial.println(); - this->serial.write(to_string((char) 0x1A)); + this->serial->println(message); + this->serial->println(); + this->serial->write(to_string((char) 0x1A)); // Read line (timeout 10 seconds) - if (this->serial.read_line(10).find("+CMGS") == string::npos) + if (this->serial->read_line(10).find("+CMGS") == string::npos) { this->logger->log("Error sending SMS"); return false; } // Read line (timeout 10 seconds) - if (this->serial.read_line(10) != "OK") + if (this->serial->read_line(10) != "OK") { this->logger->log("Error sending SMS"); return false; @@ -189,7 +193,7 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen string gsm_response = this->send_command_read("AT+CBC"); string adc_response = this->send_command_read("AT+CADC?"); while (adc_response.substr(0, 6) != "+CADC:") - adc_response = this->serial.read_line(); + adc_response = this->serial->read_line(); if (gsm_response.substr(0, 5) == "+CBC:" && adc_response.substr(0, 6) == "+CADC:") { @@ -280,12 +284,12 @@ bool GSM::tear_down_GPRS() const const string GSM::send_command_read(const string& command) const { this->command_logger->log("Sent: '"+command+"'"); - this->serial.flush(); - this->serial.println(command); + this->serial->flush(); + this->serial->println(command); // Sent command - string response = this->serial.read_line(); + string response = this->serial->read_line(); if (response == command || response == "") - response = this->serial.read_line(); + response = this->serial->read_line(); this->command_logger->log("Received: '"+response+"'"); return response; } diff --git a/gsm/GSM.h b/gsm/GSM.h index b8d6fbc..e9b0e16 100644 --- a/gsm/GSM.h +++ b/gsm/GSM.h @@ -13,7 +13,7 @@ namespace os { class GSM { private: - Serial serial; + Serial* serial; Logger* logger; Logger* command_logger; diff --git a/serial/Serial.cc b/serial/Serial.cc index 36e4e88..cdfe1bf 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -16,62 +16,24 @@ using namespace std; using namespace os; -bool Serial::initialize_GPS() +Serial::Serial(const string& url, int baud_rate, const string& log_path) { - struct timeval timer; - gettimeofday(&timer, NULL); - struct tm * now = gmtime(&timer.tv_sec); - - this->logger = new Logger("data/logs/GPS/Serial."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "GPSSerial"); - - #ifndef OS_TESTING - this->fd = serialOpen(GPS_UART, GPS_BAUDRATE); - - if (this->fd == -1) { - this->open = false; - this->stopped = true; - - return false; - } - - this->open = true; - this->stopped = false; - this->flush(); - thread t(&Serial::gps_thread, this); - t.detach(); - #else - this->open = false; - this->stopped = true; - #endif + this->open = false; - return true; -} - -bool Serial::initialize(const string& url, int baud) -{ struct timeval timer; gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); - this->logger = new Logger("data/logs/GSM/Serial."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "GSMSerial"); + this->logger = new Logger("data/logs/"+log_path+"/Serial."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "Serial"); #ifndef OS_TESTING - this->fd = serialOpen(url.c_str(), baud); - #endif - - if (this->fd == -1) - { - return false; - } - - this->open = true; - this->stopped = true; + this->fd = serialOpen(url.c_str(), baud_rate); - return true; + if (this->fd == -1) this->logger->log("Error: connection fd is -1."); + else this->open = true; + #endif } Serial::~Serial() @@ -80,48 +42,6 @@ Serial::~Serial() delete this->logger; } -void Serial::gps_thread() -{ - string response; - - while(this->open) - { - #ifndef OS_TESTING - int available = serialDataAvail(this->fd); - - if (available > 0) - { - for (int i = 0; i < available; i++) - { - char c = serialGetchar(this->fd); - response += c; - if (response[response.length()-1] == '\r' && c == '\n') - { - response = response.substr(0, response.length()-2); - this->logger->log("Received: '"+response+"\\r\\n'"); - - if (response.at(0) == '$') - { - GPS::get_instance().parse(response); - } - response = ""; - this_thread::sleep_for(50ms); - } - } - } - else if (available == 0) - { - this_thread::sleep_for(25ms); - } - else if (available < 0) - { - this->logger->log("Error: Serial available < 0."); - } - #endif - } - this->stopped = true; -} - void Serial::println(const string& str) const { this->logger->log("Sent: '"+str+"\\r\\n'"); @@ -142,22 +62,29 @@ void Serial::write(const string& str) const void Serial::close() { - if (this->open) { - this->open = false; - while( ! this->stopped) - this_thread::sleep_for(1ms); - - #ifndef OS_TESTING + #ifndef OS_TESTING + if (this->open) { serialClose(this->fd); - #endif - } + this->open = false; + } + #endif } -bool Serial::is_open() +bool Serial::is_open() const { return this->open; } +int Serial::available() const +{ + return serialDataAvail(this->fd); +} + +char Serial::read_char() const +{ + return serialGetchar(this->fd); +} + const string Serial::read_line() const { return this->read_line(0.5); diff --git a/serial/Serial.h b/serial/Serial.h index 6187c25..9445a44 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -3,9 +3,7 @@ #include -#include #include -#include #include "logger/Logger.h" using namespace std; @@ -15,14 +13,13 @@ namespace os { { private: int fd; - atomic_bool open; - atomic_bool stopped; + bool open; Logger* logger; void gps_thread(); public: - Serial() = default; + Serial(const string& url, int baud_rate, const string& log_path); Serial(Serial& copy) = delete; ~Serial(); @@ -30,9 +27,9 @@ namespace os { void println() const; void write(const string& str) const; void close(); - bool is_open(); - bool initialize_GPS(); - bool initialize(const string& serial_URL, int baud); + bool is_open() const; + char read_char() const; + int available() const; const string read_line() const; const string read_line(double timeout) const; bool read_only(const string& only) const; diff --git a/testing/battery_test.cc b/testing/battery_test.cc deleted file mode 100644 index 8832aff..0000000 --- a/testing/battery_test.cc +++ /dev/null @@ -1,19 +0,0 @@ -describe("Battery", [](){ - - it("voltage to percentage calculator test", [&](){ - AssertThat(volt_to_percent(8.4), Is().EqualToWithDelta(100, 0.01)); - AssertThat(volt_to_percent(7.4), Is().EqualToWithDelta(0, 0.01)); - AssertThat(volt_to_percent(7.75), Is().EqualToWithDelta(35, 0.01)); - AssertThat(volt_to_percent(8), Is().EqualToWithDelta(60, 0.01)); - }); - - it("reading test", [&](){ - Battery bat(80); - - bat.start_reading(); - this_thread::sleep_for(75ms); - - AssertThat(bat.get_battery(), Is().EqualToWithDelta(50, 0.05)); - bat.stop_reading(); - }); -}); diff --git a/testing/temperature_test.cc b/testing/temperature_test.cc deleted file mode 100644 index 2a38a37..0000000 --- a/testing/temperature_test.cc +++ /dev/null @@ -1,30 +0,0 @@ -describe("Temperature", [&](){ - - it("read & stop test", [&]() { - Temperature temp(20); - temp.start_reading(); - AssertThat(temp.is_reading(), Equals(true)); - - this_thread::sleep_for(100ms); - - temp.stop_reading(); - AssertThat(temp.is_reading(), Equals(false)); - }); - - it("resistor to temperature conversion test", [&]() { - - AssertThat(r_to_c(1155.4), Is().EqualToWithDelta(40, 0.05)); - AssertThat(r_to_c(1116.9), Is().EqualToWithDelta(30, 0.05)); - AssertThat(r_to_c(1077.9), Is().EqualToWithDelta(20, 0.05)); - AssertThat(r_to_c(1039), Is().EqualToWithDelta(10, 0.05)); - AssertThat(r_to_c(1000), Is().EqualToWithDelta(0, 0.05)); - AssertThat(r_to_c(960.9), Is().EqualToWithDelta(-10, 0.05)); - AssertThat(r_to_c(921.6), Is().EqualToWithDelta(-20, 0.05)); - AssertThat(r_to_c(882.2), Is().EqualToWithDelta(-30, 0.05)); - AssertThat(r_to_c(842.7), Is().EqualToWithDelta(-40, 0.05)); - AssertThat(r_to_c(803.1), Is().EqualToWithDelta(-50, 0.05)); - AssertThat(r_to_c(763.3), Is().EqualToWithDelta(-60, 0.05)); - AssertThat(r_to_c(723.3), Is().EqualToWithDelta(-70, 0.05)); - AssertThat(r_to_c(683.3), Is().EqualToWithDelta(-80, 0.05)); - }); -}); From 0464de7bcdef1ad039b9f762eb193ef7c8ed9a80 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 14:35:36 +0200 Subject: [PATCH 096/169] Fixed GPS thread --- gps/GPS.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index 73de1ac..155bc0f 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -8,8 +8,6 @@ #include #include -#include - #include #include @@ -149,7 +147,7 @@ void GPS::gps_thread() { char c = this->serial->read_char(); response += c; - if (response[response.length()-1] == '\r' && c == '\n') + if (response[response.length()-2] == '\r' && c == '\n') { response = response.substr(0, response.length()-2); From bbb4cc8ee470fbc0fd05ad73128d1b1c6808adb8 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 14:51:04 +0200 Subject: [PATCH 097/169] More default serial timeout and added more tries on GSM initialization. --- gsm/GSM.cc | 9 ++++----- serial/Serial.cc | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index d14f4a0..89e0be5 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -100,15 +100,13 @@ bool GSM::initialize() if (this->send_command_read("AT") != "OK") { - this->logger->log("Error on initialization."); - return false; + this->logger->log("Not initialized."); } this_thread::sleep_for(100ms); if (this->send_command_read("AT") != "OK") { - this->logger->log("Error on initialization."); - return false; + this->logger->log("Not initialized."); } this_thread::sleep_for(100ms); this->logger->log("Initialization OK."); @@ -288,8 +286,9 @@ const string GSM::send_command_read(const string& command) const this->serial->println(command); // Sent command string response = this->serial->read_line(); - if (response == command || response == "") + if (response == command) response = this->serial->read_line(); + this->command_logger->log("Received: '"+response+"'"); return response; } diff --git a/serial/Serial.cc b/serial/Serial.cc index cdfe1bf..be8559e 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -87,7 +87,7 @@ char Serial::read_char() const const string Serial::read_line() const { - return this->read_line(0.5); + return this->read_line(1); } const string Serial::read_line(double timeout) const From f84832db386abb7fdd2d4f511cbd242fce273df4 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 14:56:50 +0200 Subject: [PATCH 098/169] Added echo to GSM --- gsm/GSM.cc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 89e0be5..2adba76 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -111,15 +111,6 @@ bool GSM::initialize() this_thread::sleep_for(100ms); this->logger->log("Initialization OK."); - this->logger->log("Turning echo off..."); - if (this->send_command_read("ATE0") != "OK") - { - this->logger->log("Error turning echo off."); - return false; - } - this_thread::sleep_for(100ms); - this->logger->log("Echo is off."); - return true; } From 505996adcdf4005b42039d02df1120e680f1e5a0 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 15:26:14 +0200 Subject: [PATCH 099/169] Fixed GSM initialization --- gsm/GSM.cc | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 2adba76..9426110 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -92,21 +92,17 @@ bool GSM::initialize() this->logger->log("Checking OK initialization (3 times)..."); if (this->send_command_read("AT") != "OK") - { - this->logger->log("Error on initialization."); - return false; - } + this->logger->log("Not initialized."); this_thread::sleep_for(100ms); if (this->send_command_read("AT") != "OK") - { this->logger->log("Not initialized."); - } this_thread::sleep_for(100ms); if (this->send_command_read("AT") != "OK") { - this->logger->log("Not initialized."); + this->logger->log("Error on initialization."); + return false; } this_thread::sleep_for(100ms); this->logger->log("Initialization OK."); From f0c0197183ff9ec2aee676d79d7049d7980e5214 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 16:00:34 +0200 Subject: [PATCH 100/169] Added debug information to SMS failure --- gsm/GSM.cc | 46 ++++++++++++++++++++++++++++++++++++---------- gsm/GSM.h | 1 + 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 9426110..8314594 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -43,6 +43,8 @@ GSM::~GSM() bool GSM::initialize() { + this->occupied = false; + struct timeval timer; gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); @@ -78,6 +80,7 @@ bool GSM::initialize() return false; } + this->occupied = true; this->logger->log("Starting serial connection..."); this->serial = new Serial(GSM_UART, GSM_BAUDRATE, "GSM"); if ( ! this->serial->is_open()) @@ -106,23 +109,26 @@ bool GSM::initialize() } this_thread::sleep_for(100ms); this->logger->log("Initialization OK."); + this->occupied = false; return true; } bool GSM::send_SMS(const string& message, const string& number) const { + while (this->occupied) this_thread::sleep_for(10ms); + this->occupied = true; + this->logger->log("Sending SMS: \""+message+"\" to number "+number+"."); if (this->send_command_read("AT+CMGF=1") != "OK") { - this->logger->log("Error sending SMS"); + this->logger->log("Error sending SMS on 'AT+CMGD=1' response."); return false; } - string send_command = "AT+CMGS=\""+number+"\""; - if (this->send_command_read(send_command) != "> ") + if (this->send_command_read("AT+CMGS=\""+number+"\"") != "> ") { - this->logger->log("Error sending SMS"); + this->logger->log("Error sending SMS on 'AT+CMGS' response."); return false; } @@ -133,16 +139,17 @@ bool GSM::send_SMS(const string& message, const string& number) const // Read line (timeout 10 seconds) if (this->serial->read_line(10).find("+CMGS") == string::npos) { - this->logger->log("Error sending SMS"); + this->logger->log("Error sending SMS. Could not read '+CMGS'."); return false; } // Read line (timeout 10 seconds) if (this->serial->read_line(10) != "OK") { - this->logger->log("Error sending SMS"); + this->logger->log("Error sending SMS. Could not read 'OK'."); return false; } + this->occupied = false; this->logger->log("SMS sent."); return true; @@ -172,6 +179,9 @@ bool GSM::get_status() const bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage) const { + while (this->occupied) this_thread::sleep_for(10ms); + this->occupied = true; + this->logger->log("Checking Battery status."); if (this->get_status()) { @@ -200,13 +210,18 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen { this->logger->log("Error: module is off."); } + this->occupied = false; return false; } bool GSM::has_connectivity() const { - string response = this->send_command_read("AT+CREG?"); - return response == "+CREG: 0,1" || response == "+CREG: 0,5"; + while (this->occupied) this_thread::sleep_for(10ms); + this->occupied = true; + string response = this->send_command_read("AT+CREG?"); + this->occupied = false; + + return response == "+CREG: 0,1" || response == "+CREG: 0,5"; } bool GSM::turn_on() const @@ -255,15 +270,26 @@ bool GSM::turn_off() const bool GSM::init_GPRS() const { - return !(this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") != "OK" || + while (this->occupied) this_thread::sleep_for(10ms); + this->occupied = true; + + bool result = !(this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") != "OK" || this->send_command_read("AT+SAPBR=3,1,\"APN\",\"" + string(GSM_LOC_SERV) + ";") != "OK" || this->send_command_read("AT+SAPBR=1,1") != "OK" || this->send_command_read("AT+SAPBR=2,1") != "OK"); + this->occupied = false; + + return result; } bool GSM::tear_down_GPRS() const { - return this->send_command_read("AT+SAPBR=0,1") == "OK"; + while (this->occupied) this_thread::sleep_for(10ms); + this->occupied = true; + bool result = this->send_command_read("AT+SAPBR=0,1") == "OK"; + this->occupied = false; + + return result; } const string GSM::send_command_read(const string& command) const diff --git a/gsm/GSM.h b/gsm/GSM.h index e9b0e16..49e8052 100644 --- a/gsm/GSM.h +++ b/gsm/GSM.h @@ -18,6 +18,7 @@ namespace os { Logger* command_logger; int fh; + atomic_bool occupied; GSM() = default; From 0d9240415595d12eab25fbfae0b7efa097171c47 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 16:10:39 +0200 Subject: [PATCH 101/169] Fixed build --- gsm/GSM.cc | 36 ++++++++++++++---------------------- gsm/GSM.h | 12 +++++------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 8314594..bba3dd8 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -114,7 +114,7 @@ bool GSM::initialize() return true; } -bool GSM::send_SMS(const string& message, const string& number) const +bool GSM::send_SMS(const string& message, const string& number) { while (this->occupied) this_thread::sleep_for(10ms); this->occupied = true; @@ -155,8 +155,11 @@ bool GSM::send_SMS(const string& message, const string& number) const return true; } -bool GSM::get_location(double& latitude, double& longitude) const +bool GSM::get_location(double& latitude, double& longitude) { + while (this->occupied) this_thread::sleep_for(10ms); + this->occupied = true; + if ( ! this->init_GPRS()) { return false; @@ -169,6 +172,7 @@ bool GSM::get_location(double& latitude, double& longitude) const { return false; } + this->occupied = false; return false; } @@ -177,7 +181,7 @@ bool GSM::get_status() const return digitalRead(GSM_STATUS_GPIO) == HIGH; } -bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage) const +bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage) { while (this->occupied) this_thread::sleep_for(10ms); this->occupied = true; @@ -214,7 +218,7 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen return false; } -bool GSM::has_connectivity() const +bool GSM::has_connectivity() { while (this->occupied) this_thread::sleep_for(10ms); this->occupied = true; @@ -270,26 +274,15 @@ bool GSM::turn_off() const bool GSM::init_GPRS() const { - while (this->occupied) this_thread::sleep_for(10ms); - this->occupied = true; - - bool result = !(this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") != "OK" || - this->send_command_read("AT+SAPBR=3,1,\"APN\",\"" + string(GSM_LOC_SERV) + ";") != "OK" || - this->send_command_read("AT+SAPBR=1,1") != "OK" || - this->send_command_read("AT+SAPBR=2,1") != "OK"); - this->occupied = false; - - return result; + return (this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") == "OK" && + this->send_command_read("AT+SAPBR=3,1,\"APN\",\"" + string(GSM_LOC_SERV) + ";") == "OK" && + this->send_command_read("AT+SAPBR=1,1") == "OK" & + this->send_command_read("AT+SAPBR=2,1") == "OK"); } bool GSM::tear_down_GPRS() const { - while (this->occupied) this_thread::sleep_for(10ms); - this->occupied = true; - bool result = this->send_command_read("AT+SAPBR=0,1") == "OK"; - this->occupied = false; - - return result; + return this->send_command_read("AT+SAPBR=0,1") == "OK"; } const string GSM::send_command_read(const string& command) const @@ -297,9 +290,8 @@ const string GSM::send_command_read(const string& command) const this->command_logger->log("Sent: '"+command+"'"); this->serial->flush(); this->serial->println(command); - // Sent command string response = this->serial->read_line(); - if (response == command) + if (response == command) // Sent command response = this->serial->read_line(); this->command_logger->log("Received: '"+response+"'"); diff --git a/gsm/GSM.h b/gsm/GSM.h index 49e8052..a489278 100644 --- a/gsm/GSM.h +++ b/gsm/GSM.h @@ -2,6 +2,7 @@ #define GSM_GSM_H_ #include +#include #include "serial/Serial.h" #include "logger/Logger.h" @@ -23,8 +24,6 @@ namespace os { GSM() = default; const string send_command_read(const string& command) const; - bool send_command_read_only(const string& command, const string& only) const; - void send_command(const string& command) const; bool init_GPRS() const; bool tear_down_GPRS() const; public: @@ -33,12 +32,11 @@ namespace os { static GSM& get_instance(); bool initialize(); - bool send_SMS(const string& message, const string& number) const; - bool get_location(double& latitude, double& longitude) const; + bool send_SMS(const string& message, const string& number); + bool get_location(double& latitude, double& longitude); bool get_status() const; - bool get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage) const; - bool is_up() const; - bool has_connectivity() const; + bool get_battery_status(double& main_bat_percentage, double& gsm_bat_percentage); + bool has_connectivity(); bool turn_on() const; bool turn_off() const; }; From 5759e65e870da40d7463fd372a179f350e6a60f3 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 16:20:37 +0200 Subject: [PATCH 102/169] Finished #33 --- gsm/GSM.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index bba3dd8..34e4f8c 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -86,6 +86,7 @@ bool GSM::initialize() if ( ! this->serial->is_open()) { this->logger->log("GSM serial error."); + this->occupied = false; return false; } this->logger->log("Serial connection started."); @@ -105,6 +106,7 @@ bool GSM::initialize() if (this->send_command_read("AT") != "OK") { this->logger->log("Error on initialization."); + this->occupied = false; return false; } this_thread::sleep_for(100ms); @@ -123,12 +125,14 @@ bool GSM::send_SMS(const string& message, const string& number) if (this->send_command_read("AT+CMGF=1") != "OK") { this->logger->log("Error sending SMS on 'AT+CMGD=1' response."); + this->occupied = false; return false; } if (this->send_command_read("AT+CMGS=\""+number+"\"") != "> ") { this->logger->log("Error sending SMS on 'AT+CMGS' response."); + this->occupied = false; return false; } @@ -140,6 +144,7 @@ bool GSM::send_SMS(const string& message, const string& number) if (this->serial->read_line(10).find("+CMGS") == string::npos) { this->logger->log("Error sending SMS. Could not read '+CMGS'."); + this->occupied = false; return false; } @@ -147,6 +152,7 @@ bool GSM::send_SMS(const string& message, const string& number) if (this->serial->read_line(10) != "OK") { this->logger->log("Error sending SMS. Could not read 'OK'."); + this->occupied = false; return false; } this->occupied = false; @@ -162,6 +168,7 @@ bool GSM::get_location(double& latitude, double& longitude) if ( ! this->init_GPRS()) { + this->occupied = false; return false; } // TODO @@ -170,6 +177,7 @@ bool GSM::get_location(double& latitude, double& longitude) // serialin[responseLength+1] = (char)0x0; if (this->tear_down_GPRS()) { + this->occupied = false; return false; } this->occupied = false; @@ -207,6 +215,7 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen gsm_bat_percentage = (gsm_bat_voltage/1000.0-BAT_GSM_MIN)/(BAT_GSM_MAX-BAT_GSM_MIN); main_bat_percentage = (main_bat_voltage/1000.0-BAT_MAIN_MIN)/(BAT_MAIN_MAX-BAT_MAIN_MIN); + this->occupied = false; return true; } } From 140955636cb068f561ad4b63152aade9950426f9 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 16:26:54 +0200 Subject: [PATCH 103/169] Eat message echo --- gsm/GSM.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 34e4f8c..dcae892 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -141,6 +141,7 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->write(to_string((char) 0x1A)); // Read line (timeout 10 seconds) + this->serial->read_line(); // Eat message echo if (this->serial->read_line(10).find("+CMGS") == string::npos) { this->logger->log("Error sending SMS. Could not read '+CMGS'."); From 1e385547279d42314919cf9bdb4f834014a5f28e Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 16:38:39 +0200 Subject: [PATCH 104/169] Trying to fix SMS sending (#20) --- gsm/GSM.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index dcae892..b5b7d2c 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -137,11 +137,12 @@ bool GSM::send_SMS(const string& message, const string& number) } this->serial->println(message); + this->serial->read_line(); // Eat message echo this->serial->println(); + this->serial->read_line(); // Eat prompt this->serial->write(to_string((char) 0x1A)); // Read line (timeout 10 seconds) - this->serial->read_line(); // Eat message echo if (this->serial->read_line(10).find("+CMGS") == string::npos) { this->logger->log("Error sending SMS. Could not read '+CMGS'."); From 91a0b4b9f2e40ff84ae53d9db07b46c2af591e89 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 16:48:39 +0200 Subject: [PATCH 105/169] Fixing SMS sending --- gsm/GSM.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index b5b7d2c..9d093ec 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -140,7 +140,8 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->read_line(); // Eat message echo this->serial->println(); this->serial->read_line(); // Eat prompt - this->serial->write(to_string((char) 0x1A)); + this->serial->write(to_string('\x1A')); + this->serial->read_line(); // Eat prompt // Read line (timeout 10 seconds) if (this->serial->read_line(10).find("+CMGS") == string::npos) From 46c97699fa5cb7791d6bcf2078b654c3d0941ed1 Mon Sep 17 00:00:00 2001 From: Razican Date: Mon, 24 Aug 2015 17:37:21 +0200 Subject: [PATCH 106/169] Trying to send Ctrl+Z properly --- gsm/GSM.cc | 2 +- serial/Serial.cc | 13 +++++++------ serial/Serial.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 9d093ec..a1d37e1 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -140,7 +140,7 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->read_line(); // Eat message echo this->serial->println(); this->serial->read_line(); // Eat prompt - this->serial->write(to_string('\x1A')); + this->serial->write('\x1A'); this->serial->read_line(); // Eat prompt // Read line (timeout 10 seconds) diff --git a/serial/Serial.cc b/serial/Serial.cc index be8559e..4e18f1c 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -38,26 +38,27 @@ Serial::Serial(const string& url, int baud_rate, const string& log_path) Serial::~Serial() { - this->close(); + if (this->open) + this->close(); delete this->logger; } void Serial::println(const string& str) const { - this->logger->log("Sent: '"+str+"\\r\\n'"); serialPuts(this->fd, (str+"\r\n").c_str()); + this->logger->log("Sent: '"+str+"\\r\\n'"); } void Serial::println() const { - this->logger->log("Sent: '\\r\\n'"); serialPuts(this->fd, "\r\n"); + this->logger->log("Sent: '\\r\\n'"); } -void Serial::write(const string& str) const +void Serial::write(unsigned char c) const { - this->logger->log("Sent: '"+str+"'"); - serialPuts(this->fd, str.c_str()); + serialPutchar(this->fd, c); + this->logger->log("Sent char: '"+string(1, c)+"'"); } void Serial::close() diff --git a/serial/Serial.h b/serial/Serial.h index 9445a44..8c97a18 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -25,7 +25,7 @@ namespace os { void println(const string& str) const; void println() const; - void write(const string& str) const; + void write(unsigned char c) const; void close(); bool is_open() const; char read_char() const; From 3556c6ae954235f2eff12cf9f7af0faac3b391d5 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 13:01:34 +0200 Subject: [PATCH 107/169] There was not enough timeout --- gsm/GSM.cc | 9 +++++---- openstratos.cc | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index a1d37e1..7a858ba 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -141,17 +141,18 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->println(); this->serial->read_line(); // Eat prompt this->serial->write('\x1A'); - this->serial->read_line(); // Eat prompt + this->serial->read_line(10); // Eat prompt (timeout 10 seconds) - // Read line (timeout 10 seconds) - if (this->serial->read_line(10).find("+CMGS") == string::npos) + // Read line + if (this->serial->read_line().find("+CMGS") == string::npos) { this->logger->log("Error sending SMS. Could not read '+CMGS'."); this->occupied = false; return false; } + this->serial->read_line(); // Eat new line - // Read line (timeout 10 seconds) + // Read OK (timeout 10 seconds) if (this->serial->read_line(10) != "OK") { this->logger->log("Error sending SMS. Could not read 'OK'."); diff --git a/openstratos.cc b/openstratos.cc index d0091e4..05b2803 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -128,7 +128,7 @@ int main(void) exit(1); } - logger.log("GSM initialized"); + logger.log("GSM initialized."); logger.log("Checking batteries..."); double main_battery, gsm_battery; From 1a02eedac26f1d91bd0fceb9fc23475a76f945df Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 15:28:32 +0200 Subject: [PATCH 108/169] More realistic descent times, trying to debug connectivity issues. --- openstratos.cc | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 05b2803..e821c91 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -156,12 +156,10 @@ int main(void) } logger.log("Waiting for GSM connectivity..."); - this_thread::sleep_for(25ms); while ( ! GSM::get_instance().has_connectivity()) { this_thread::sleep_for(1s); } - this_thread::sleep_for(25ms); logger.log("GSM connected."); logger.log("Starting battery thread..."); @@ -301,7 +299,7 @@ int main(void) { this_thread::sleep_for(1s); } - this_thread::sleep_for(1min); // TODO delete + this_thread::sleep_for(2min); // TODO: delete logger.log("Balloon launched."); state = set_state(GOING_UP); @@ -324,7 +322,7 @@ int main(void) // { this_thread::sleep_for(5s); // } - this_thread::sleep_for(3min); // TODO: delete + this_thread::sleep_for(270s); // TODO: delete logger.log("1.5 km mark."); logger.log("Trying to send \"going up\" SMS..."); if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ @@ -342,7 +340,7 @@ int main(void) GSM::get_instance().turn_off(); logger.log("GSM off."); - this_thread::sleep_for(15min); // TODO delete + this_thread::sleep_for(10min); // TODO: delete while ( ! has_bursted()); logger.log("Balloon burst."); @@ -365,13 +363,17 @@ int main(void) count = 0; while ( ! GSM::get_instance().has_connectivity()) { - if (count > 15) break; + if (count > 20) + { + logger.log("Timeout."); + break; + } this_thread::sleep_for(1s); ++count; } if ( ! GSM::get_instance().has_connectivity()) { - logger.log("No connectivity, waiting for 1.5 km mark."); + logger.log("No connectivity, waiting for 1.5 km mark or landing."); } else { @@ -393,6 +395,7 @@ int main(void) { this_thread::sleep_for(5s); } + this_thread::sleep_for(200s); // TODO: delete // if ( ! has_landed()) // { logger.log("1.5 km mark."); @@ -400,7 +403,11 @@ int main(void) count = 0; while ( ! GSM::get_instance().has_connectivity()) { - if (count > 15) break; + if (count > 20) + { + logger.log("Timeout."); + break; + } this_thread::sleep_for(1s); ++count; } @@ -462,6 +469,8 @@ int main(void) } } + this_thread::sleep_for(200s); // TODO: delete + while ( ! has_landed()) { this_thread::sleep_for(5s); From 688dbb31464adf8dd6c2f71e04f981b0ca84536d Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 15:36:19 +0200 Subject: [PATCH 109/169] Fixed connectivity issues (I hope) --- openstratos.cc | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index e821c91..93a4860 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -363,15 +363,11 @@ int main(void) count = 0; while ( ! GSM::get_instance().has_connectivity()) { - if (count > 20) - { - logger.log("Timeout."); - break; - } + if (count == 20) break; this_thread::sleep_for(1s); ++count; } - if ( ! GSM::get_instance().has_connectivity()) + if (count == 20) { logger.log("No connectivity, waiting for 1.5 km mark or landing."); } @@ -403,15 +399,11 @@ int main(void) count = 0; while ( ! GSM::get_instance().has_connectivity()) { - if (count > 20) - { - logger.log("Timeout."); - break; - } + if (count == 20) break; this_thread::sleep_for(1s); ++count; } - if ( ! GSM::get_instance().has_connectivity()) + if (count == 20) { logger.log("No connectivity, waiting for 500 m mark or landing."); } From 7658459677d2f947562e17f419f6d1627f2b027f Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 17:17:05 +0200 Subject: [PATCH 110/169] Fixing small issues and better point detection --- gsm/GSM.cc | 11 +++++++++++ openstratos.cc | 8 ++++---- serial/Serial.cc | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 7a858ba..9eb1fcf 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -236,6 +236,8 @@ bool GSM::has_connectivity() while (this->occupied) this_thread::sleep_for(10ms); this->occupied = true; string response = this->send_command_read("AT+CREG?"); + this->serial->read_line(); // Read new line + this->serial->read_line(); // Read OK this->occupied = false; return response == "+CREG: 0,1" || response == "+CREG: 0,5"; @@ -304,8 +306,17 @@ const string GSM::send_command_read(const string& command) const this->serial->flush(); this->serial->println(command); string response = this->serial->read_line(); + // Trimming + string ltrim = response.erase(0, response.find_first_not_of(" \r\n\t")); + response = ltrim.erase(ltrim.find_last_not_of(" \r\n\t")+1); + if (response == command) // Sent command + { response = this->serial->read_line(); + // Trimming + string ltrim = response.erase(0, response.find_first_not_of(" \r\n\t")); + response = ltrim.erase(ltrim.find_last_not_of(" \r\n\t")+1); + } this->command_logger->log("Received: '"+response+"'"); return response; diff --git a/openstratos.cc b/openstratos.cc index 93a4860..def52a7 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -727,7 +727,7 @@ const string os::state_to_string(State state) bool os::has_launched() { double first_altitude = GPS::get_instance().get_altitude(); - this_thread::sleep_for(3s); + this_thread::sleep_for(5s); double second_altitude = GPS::get_instance().get_altitude(); return true; @@ -737,11 +737,11 @@ bool os::has_launched() bool os::has_bursted() { double first_altitude = GPS::get_instance().get_altitude(); - this_thread::sleep_for(3s); + this_thread::sleep_for(6s); double second_altitude = GPS::get_instance().get_altitude(); return true; - // return second_altitude < first_altitude - 15; + // return second_altitude < first_altitude - 10; } bool os::has_landed() @@ -751,7 +751,7 @@ bool os::has_landed() double second_altitude = GPS::get_instance().get_altitude(); return true; - // return first_altitude-second_altitude < 5; + // return abs(first_altitude-second_altitude) < 5; } const string os::generate_exif_data() diff --git a/serial/Serial.cc b/serial/Serial.cc index 4e18f1c..849e01a 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -146,6 +146,7 @@ const string Serial::read_line(double timeout) const this->logger->log("Error: Serial available < 0."); break; } + this_thread::sleep_for(1ms); } #endif this->logger->log("Received: '"+logstr+"'"); From 808a90a565391b69fc0b98429b77386055e9b6e6 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 17:40:24 +0200 Subject: [PATCH 111/169] No more space trimming --- gsm/GSM.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 9eb1fcf..1ef86ed 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -307,15 +307,15 @@ const string GSM::send_command_read(const string& command) const this->serial->println(command); string response = this->serial->read_line(); // Trimming - string ltrim = response.erase(0, response.find_first_not_of(" \r\n\t")); - response = ltrim.erase(ltrim.find_last_not_of(" \r\n\t")+1); + string ltrim = response.erase(0, response.find_first_not_of("\r\n\t")); + response = ltrim.erase(ltrim.find_last_not_of("\r\n\t")+1); if (response == command) // Sent command { response = this->serial->read_line(); // Trimming - string ltrim = response.erase(0, response.find_first_not_of(" \r\n\t")); - response = ltrim.erase(ltrim.find_last_not_of(" \r\n\t")+1); + string ltrim = response.erase(0, response.find_first_not_of("\r\n\t")); + response = ltrim.erase(ltrim.find_last_not_of("\r\n\t")+1); } this->command_logger->log("Received: '"+response+"'"); From 44048bbc11f98c6c0440fbe2f235c66fff1f0398 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 18:50:01 +0200 Subject: [PATCH 112/169] Fixed infinite loop --- gsm/GSM.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 1ef86ed..fbc0d48 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -203,7 +203,7 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen { string gsm_response = this->send_command_read("AT+CBC"); string adc_response = this->send_command_read("AT+CADC?"); - while (adc_response.substr(0, 6) != "+CADC:") + while (adc_response != '' && adc_response.substr(0, 6) != "+CADC:") adc_response = this->serial->read_line(); if (gsm_response.substr(0, 5) == "+CBC:" && adc_response.substr(0, 6) == "+CADC:") From 23b9ee2929ab5b990886c88edecac28bd8b5cea9 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 18:51:26 +0200 Subject: [PATCH 113/169] Fixed comparison --- gsm/GSM.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index fbc0d48..27b6a61 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -203,7 +203,7 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen { string gsm_response = this->send_command_read("AT+CBC"); string adc_response = this->send_command_read("AT+CADC?"); - while (adc_response != '' && adc_response.substr(0, 6) != "+CADC:") + while (adc_response != "" && adc_response.substr(0, 6) != "+CADC:") adc_response = this->serial->read_line(); if (gsm_response.substr(0, 5) == "+CBC:" && adc_response.substr(0, 6) == "+CADC:") From 9287cc47c164d6e22c2d651732a25434eea51561 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 25 Aug 2015 19:07:55 +0200 Subject: [PATCH 114/169] Fixing battery check --- gsm/GSM.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 27b6a61..69495c9 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -202,7 +202,11 @@ bool GSM::get_battery_status(double& main_bat_percentage, double& gsm_bat_percen if (this->get_status()) { string gsm_response = this->send_command_read("AT+CBC"); + this->serial->read_line(); // Eat new line + this->serial->read_line(); // Eat OK string adc_response = this->send_command_read("AT+CADC?"); + this->serial->read_line(); // Eat new line + this->serial->read_line(); // Eat OK while (adc_response != "" && adc_response.substr(0, 6) != "+CADC:") adc_response = this->serial->read_line(); @@ -236,8 +240,8 @@ bool GSM::has_connectivity() while (this->occupied) this_thread::sleep_for(10ms); this->occupied = true; string response = this->send_command_read("AT+CREG?"); - this->serial->read_line(); // Read new line - this->serial->read_line(); // Read OK + this->serial->read_line(); // Eat new line + this->serial->read_line(); // Eat OK this->occupied = false; return response == "+CREG: 0,1" || response == "+CREG: 0,5"; From 8be73280c0395f3fb599c0574c55ff0a272eda44 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 01:30:13 +0200 Subject: [PATCH 115/169] Starting with #32 --- constants.h | 2 ++ openstratos.cc | 35 +++++++++++++++++++++++++++-------- openstratos.h | 9 ++++++++- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/constants.h b/constants.h index 85e19aa..7d1c770 100644 --- a/constants.h +++ b/constants.h @@ -1,6 +1,8 @@ #ifndef CONSTANTS_H_ #define CONSTANTS_H_ + #define DEBUG true + #define FLIGHT_LENGTH 4.8 // Hours #define BAT_GSM_MAX 4.2 diff --git a/openstratos.cc b/openstratos.cc index def52a7..68b368c 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -2,14 +2,30 @@ int main(void) { - cout << "[OpenStratos] Starting..." << endl; // Only if verbose + #if DEBUG + cout << "[OpenStratos] Starting..." << endl; + #endif - State last_state; - if (file_exists(STATE_FILE)) - last_state = get_state(); + if ( ! file_exists(STATE_FILE)) + { + #if DEBUG + cout << "[OpenStratos] No state file. Starting main logic..." << endl; + #endif + main_logic(); + } else - last_state = SHUT_DOWN; + { + #if DEBUG + cout << "[OpenStratos] State file found. Starting safe mode..." << endl; + #endif + safe_mode(); + } + + return 0; +} +void os::main_logic() +{ State state = set_state(INITIALIZING); struct timeval timer; @@ -547,7 +563,11 @@ int main(void) logger.log("Powering off..."); sync(); // reboot(RB_POWER_OFF); - return 0; +} + +void os::safe_mode() +{ + // TODO } inline bool os::file_exists(const string& name) @@ -750,8 +770,7 @@ bool os::has_landed() this_thread::sleep_for(5s); double second_altitude = GPS::get_instance().get_altitude(); - return true; - // return abs(first_altitude-second_altitude) < 5; + return abs(first_altitude-second_altitude) < 5; } const string os::generate_exif_data() diff --git a/openstratos.h b/openstratos.h index a5884b1..29d137f 100644 --- a/openstratos.h +++ b/openstratos.h @@ -2,8 +2,8 @@ #define OPENSTRATOS_H_ #include +#include -#include #include #include #include @@ -25,6 +25,10 @@ #include "camera/Camera.h" #include "gsm/GSM.h" +#if DEBUG + #include +#endif + namespace os { enum State { @@ -39,6 +43,9 @@ namespace os RECOVERY, }; + void main_logic(); + void safe_mode(); + inline bool file_exists(const string& name); inline float get_available_disk_space(); void gps_thread_fn(State& state); From fb781187233005ad8fc27027bb450ba341e37d2a Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 14:06:36 +0200 Subject: [PATCH 116/169] Major logic refactoring Closes #32, starts #41 and prepares the script for #22 and #40. --- openstratos.cc | 978 +++++++++++++++++++++++++------------------------ openstratos.h | 30 +- 2 files changed, 513 insertions(+), 495 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 68b368c..e40536d 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -26,212 +26,258 @@ int main(void) void os::main_logic() { - State state = set_state(INITIALIZING); - struct timeval timer; gettimeofday(&timer, NULL); - struct tm * now = gmtime(&timer.tv_sec); + struct tm* now = gmtime(&timer.tv_sec); - cout << "[OpenStratos] Current time: " << setfill('0') << setw(2) << now->tm_hour << ":" << - setfill('0') << setw(2) << now->tm_min << ":" << setfill('0') << setw(2) << now->tm_sec << - " UTC of " << setfill('0') << setw(2) << now->tm_mon << "/" << - setfill('0') << setw(2) << now->tm_mday << "/" << (now->tm_year+1900) << endl; // Only if verbose + #if DEBUG + cout << "[OpenStratos] Current time: " << setfill('0') << setw(2) << now->tm_hour << ":" << + setfill('0') << setw(2) << now->tm_min << ":" << setfill('0') << setw(2) << now->tm_sec << + " UTC of " << setfill('0') << setw(2) << now->tm_mon << "/" << + setfill('0') << setw(2) << now->tm_mday << "/" << (now->tm_year+1900) << endl; + #endif - if ( ! file_exists("data")) - { - cout << "[OpenStratos] No data directory, creating..." << endl; - if (mkdir("data", 0755) == 0) - { - cout << "[OpenStratos] Data directory created." << endl; - } - else - { - cout << "[OpenStratos] Error creating data directory." << endl; - exit(1); - } - } + check_or_create("data"); + State state = set_state(INITIALIZING); + + check_or_create("data/logs"); + check_or_create("data/logs/main"); + check_or_create("data/logs/camera"); + check_or_create("data/logs/GPS"); + check_or_create("data/logs/GSM"); + + #if DEBUG + cout << "[OpenStratos] Starting logger..." << endl; + #endif + + Logger logger("data/logs/main/OpenStratos."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "OpenStratos"); + + #if DEBUG + cout << "[OpenStratos] Logger started." << endl; + #endif + + initialize(&logger, now); - if ( ! file_exists("data/logs")) + logger.log("Starting battery thread..."); + thread battery_thread(&battery_thread_fn, ref(state)); + logger.log("Battery thread started."); + + logger.log("Starting picture thread..."); + thread picture_thread(&picture_thread_fn, ref(state)); + logger.log("Picture thread started."); + + state = set_state(ACQUIRING_FIX); + logger.log("State changed to "+ state_to_string(state) +"."); + + while (state != SHUT_DOWN) { - cout << "[OpenStratos] No log directory, creating..." << endl; - if (mkdir("data/logs", 0755) == 0 && mkdir("data/logs/main", 0755) == 0 && - mkdir("data/logs/camera", 0755) == 0 && mkdir("data/logs/GPS", 0755) == 0 - && mkdir("data/logs/GSM", 0755) == 0) + if (state == ACQUIRING_FIX) { - cout << "[OpenStratos] Log directory created." << endl; + aquire_fix(&logger); + state = set_state(FIX_ACQUIRED); + logger.log("State changed to "+ state_to_string(state) +"."); } - else + else if (state == FIX_ACQUIRED) { - cout << "[OpenStratos] Error creating log directory." << endl; - exit(1); + start_recording(&logger); + send_init_sms(&logger); + state = set_state(WAITING_LAUNCH); + logger.log("State changed to "+ state_to_string(state) +"."); } - } - - cout << "[OpenStratos] Starting logger..." << endl; // Only if verbose - - Logger logger("data/logs/main/OpenStratos."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "OpenStratos"); - cout << "[OpenStratos] Logger started." << endl; // Only if verbose - - if (file_exists("data/video")) - { - logger.log("Video directory exists."); - } - else - { - logger.log("No video directory, creating..."); - if (mkdir("data/video", 0755) == 0) + else if (state == WAITING_LAUNCH) { - logger.log("Video directory created."); + wait_launch(&logger); + state = set_state(GOING_UP); + logger.log("State changed to "+ state_to_string(state) +"."); } - else + else if (state == GOING_UP) { - logger.log("Error creating video directory."); - exit(1); + go_up(&logger); + state = set_state(GOING_DOWN); + logger.log("State changed to "+ state_to_string(state) +"."); } - } - - if (file_exists("data/img")) - { - logger.log("Image directory exists."); - } - else - { - logger.log("No image directory, creating..."); - if (mkdir("data/img", 0755) == 0) + else if (state == GOING_DOWN) { - logger.log("Image directory created."); + go_down(&logger); + state = set_state(LANDED); + logger.log("State changed to "+ state_to_string(state) +"."); } - else + else if (state == LANDED) { - logger.log("Error creating image directory."); - exit(1); + land(&logger); + state = set_state(SHUT_DOWN); + logger.log("State changed to "+ state_to_string(state) +"."); } + // else + // TODO reboot } - logger.log("Available disk space: " + to_string(get_available_disk_space()/1073741824) + " GiB"); - if (get_available_disk_space() < FLIGHT_LENGTH*9437184000) // 1.25 times the flight length + logger.log("Joining threads..."); + picture_thread.join(); + battery_thread.join(); + logger.log("Threads joined."); + + shut_down(&logger); +} + +void os::safe_mode() +{ + // TODO +} + +inline bool os::has_launched() +{ + double first_altitude = GPS::get_instance().get_altitude(); + this_thread::sleep_for(5s); + double second_altitude = GPS::get_instance().get_altitude(); + + return true; + // return second_altitude > first_altitude + 10; +} + +inline bool os::has_bursted() +{ + double first_altitude = GPS::get_instance().get_altitude(); + this_thread::sleep_for(6s); + double second_altitude = GPS::get_instance().get_altitude(); + + return true; + // return second_altitude < first_altitude - 10; +} + +inline bool os::has_landed() +{ + double first_altitude = GPS::get_instance().get_altitude(); + this_thread::sleep_for(5s); + double second_altitude = GPS::get_instance().get_altitude(); + + return abs(first_altitude-second_altitude) < 5; +} + +void os::initialize(Logger* logger, tm* now) +{ + check_or_create("data/video", logger); + check_or_create("data/img", logger); + + float available_disk_space = get_available_disk_space(); + + logger->log("Available disk space: " + to_string(available_disk_space/1073741824) + " GiB"); + if (available_disk_space < FLIGHT_LENGTH*9437184000) // 1.25 times the flight length { - logger.log("Error: Not enough disk space."); + logger->log("Error: Not enough disk space."); exit(1); } - logger.log("Disk space enough for about " + to_string(get_available_disk_space()/7549747200) + + logger->log("Disk space enough for about " + to_string(available_disk_space/7549747200) + " hours of fullHD video."); - logger.log("Initializing WiringPi..."); + logger->log("Initializing WiringPi..."); wiringPiSetup(); - logger.log("WiringPi initialized."); + logger->log("WiringPi initialized."); - logger.log("Initializing GPS..."); + logger->log("Initializing GPS..."); if ( ! GPS::get_instance().initialize()) { - logger.log("GPS initialization error."); + logger->log("GPS initialization error."); exit(1); } - logger.log("GPS initialized."); + logger->log("GPS initialized."); - logger.log("Initializing GSM..."); + logger->log("Initializing GSM..."); if ( ! GSM::get_instance().initialize()) { - logger.log("GSM initialization error."); - logger.log("Turning GPS off..."); + logger->log("GSM initialization error."); + logger->log("Turning GPS off..."); if (GPS::get_instance().turn_off()) - logger.log("GPS off."); + logger->log("GPS off."); else - logger.log("Error turning GPS off."); + logger->log("Error turning GPS off."); exit(1); } - logger.log("GSM initialized."); + logger->log("GSM initialized."); - logger.log("Checking batteries..."); + logger->log("Checking batteries..."); double main_battery, gsm_battery; GSM::get_instance().get_battery_status(main_battery, gsm_battery); - logger.log("Batteries checked => Main battery: "+ (main_battery > -1 ? to_string(main_battery*100)+"%" : "disconnected") + + logger->log("Batteries checked => Main battery: "+ (main_battery > -1 ? to_string(main_battery*100)+"%" : "disconnected") + " - GSM battery: "+ to_string(gsm_battery*100) +"%"); if ((main_battery < 0.95 && main_battery > -1) || gsm_battery < 0.95) { - logger.log("Error: Not enough battery."); + logger->log("Error: Not enough battery."); - logger.log("Turning GSM off..."); + logger->log("Turning GSM off..."); if (GSM::get_instance().turn_off()) - logger.log("GSM off."); + logger->log("GSM off."); else - logger.log("Error turning GSM off."); + logger->log("Error turning GSM off."); - logger.log("Turning GPS off..."); + logger->log("Turning GPS off..."); if (GPS::get_instance().turn_off()) - logger.log("GPS off."); + logger->log("GPS off."); else - logger.log("Error turning GPS off."); + logger->log("Error turning GPS off."); exit(1); } - logger.log("Waiting for GSM connectivity..."); + logger->log("Waiting for GSM connectivity..."); while ( ! GSM::get_instance().has_connectivity()) { this_thread::sleep_for(1s); } - logger.log("GSM connected."); - - logger.log("Starting battery thread..."); - thread battery_thread(&battery_thread_fn, ref(state)); - logger.log("Battery thread started."); + logger->log("GSM connected."); - logger.log("Testing camera recording..."); + logger->log("Testing camera recording..."); #ifndef RASPICAM - logger.log("Error: No raspivid found. Is this a Raspberry?"); + logger->log("Error: No raspivid found. Is this a Raspberry?"); exit(1); #endif - logger.log("Recording 10 seconds as test..."); + logger->log("Recording 10 seconds as test..."); if ( ! Camera::get_instance().record(10000)) { - logger.log("Error starting recording"); + logger->log("Error starting recording"); exit(1); } this_thread::sleep_for(11s); if (file_exists("data/video/test.h264")) { - logger.log("Camera test OK."); - logger.log("Removing test file..."); + logger->log("Camera test OK."); + + logger->log("Removing test file..."); if (remove("data/video/test.h264")) - { - logger.log("Error removing test file."); - } + logger->log("Error removing test file."); else - { - logger.log("Test file removed."); - } + logger->log("Test file removed."); } else { - logger.log("Test recording error."); - logger.log("Turning GSM off..."); + logger->log("Test recording error."); + logger->log("Turning GSM off..."); if (GSM::get_instance().turn_off()) - logger.log("GSM off."); + logger->log("GSM off."); else - logger.log("Error turning GSM off."); + logger->log("Error turning GSM off."); - logger.log("Turning GPS off..."); + logger->log("Turning GPS off..."); if (GPS::get_instance().turn_off()) - logger.log("GPS off."); + logger->log("GPS off."); else - logger.log("Error turning GPS off."); + logger->log("Error turning GPS off."); exit(1); } +} - state = set_state(ACQUIRING_FIX); - logger.log("State changed to "+ state_to_string(state) +"."); +void os::aquire_fix(Logger* logger) +{ while ( ! GPS::get_instance().is_active()) - { this_thread::sleep_for(1s); - } - logger.log("GPS fix acquired, waiting for date change."); + + logger->log("GPS fix acquired, waiting for date change."); this_thread::sleep_for(2s); struct timezone tz = {0, 0}; @@ -239,372 +285,308 @@ void os::main_logic() struct timeval tv = {timegm(&gps_time), 0}; settimeofday(&tv, &tz); - logger.log("System date change."); + logger->log("System date change."); +} - logger.log("Starting video recording..."); +void os::start_recording(Logger* logger) +{ + logger->log("Starting video recording..."); if ( ! Camera::get_instance().record()) { - logger.log("Error starting recording"); - logger.log("Turning GSM off..."); + logger->log("Error starting recording"); + logger->log("Turning GSM off..."); if (GSM::get_instance().turn_off()) - logger.log("GSM off."); + logger->log("GSM off."); else - logger.log("Error turning GSM off."); + logger->log("Error turning GSM off."); - logger.log("Turning GPS off..."); + logger->log("Turning GPS off..."); if (GPS::get_instance().turn_off()) - logger.log("GPS off."); + logger->log("GPS off."); else - logger.log("Error turning GPS off."); + logger->log("Error turning GPS off."); exit(1); } - logger.log("Recording started."); - - logger.log("Starting picture thread..."); - thread picture_thread(&picture_thread_fn, ref(state)); - logger.log("Picture thread started."); - - logger.log("Starting GPS Thread..."); - thread gps_thread(&gps_thread_fn, ref(state)); - logger.log("GPS thread started."); + logger->log("Recording started."); +} - logger.log("Sending initialization SMS..."); +void send_init_sms(Logger* logger) +{ + logger->log("Sending initialization SMS..."); if ( ! GSM::get_instance().send_SMS("Initialization finished OK. Recording. Waiting for launch.", SMS_PHONE)) { - logger.log("Error sending initialization SMS."); + logger->log("Error sending initialization SMS."); - logger.log("Stoping video recording."); + logger->log("Stoping video recording."); if (Camera::get_instance().stop()) { - logger.log("Recording stopped."); + logger->log("Recording stopped."); } else { - logger.log("Error stopping recording."); + logger->log("Error stopping recording."); } - logger.log("Turning GSM off..."); + logger->log("Turning GSM off..."); if (GSM::get_instance().turn_off()) - logger.log("GSM off."); + logger->log("GSM off."); else - logger.log("Error turning GSM off."); + logger->log("Error turning GSM off."); - logger.log("Turning GPS off..."); + logger->log("Turning GPS off..."); if (GPS::get_instance().turn_off()) - logger.log("GPS off."); + logger->log("GPS off."); else - logger.log("Error turning GPS off."); + logger->log("Error turning GPS off."); exit(1); } - logger.log("Initialization SMS sent."); + logger->log("Initialization SMS sent."); +} - state = set_state(WAITING_LAUNCH); - logger.log("State changed to "+ state_to_string(state) +"."); - logger.log("Waiting for launch..."); +void wait_launch(Logger* logger) +{ + logger->log("Waiting for launch..."); + while ( ! has_launched()) + this_thread::sleep_for(1s); + + this_thread::sleep_for(2min); // TODO: delete + logger->log("Balloon launched."); +} + +void go_up(Logger* logger) +{ + logger->log("Trying to send launch confirmation SMS..."); + if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ + to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ + to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger->log("Error sending launch confirmation SMS."); + } + else + { + logger->log("Launch confirmation SMS sent."); + } + + // while (GPS::get_instance().get_altitude() < 1500) + // { + this_thread::sleep_for(5s); + // } + this_thread::sleep_for(270s); // TODO: delete + logger->log("1.5 km mark."); + logger->log("Trying to send \"going up\" SMS..."); + if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ + to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ + to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger->log("Error sending \"going up\" SMS."); + } + else + { + logger->log("\"Going up\" SMS sent."); + } + + logger->log("Turning off GSM..."); + GSM::get_instance().turn_off(); + logger->log("GSM off."); + + this_thread::sleep_for(10min); // TODO: delete - // Main logic + while ( ! has_bursted()); + logger->log("Balloon burst."); +} + +void go_down(Logger* logger) +{ + while (GPS::get_instance().get_altitude() > 2500) + { + this_thread::sleep_for(5s); + } + this_thread::sleep_for(5min); // TODO: delete + logger->log("2.5 km mark."); + + logger->log("Turning on GSM..."); + GSM::get_instance().turn_on(); + + logger->log("Waiting for GSM connectivity..."); int count = 0; - while (state != SHUT_DOWN) + while ( ! GSM::get_instance().has_connectivity()) + { + if (count == 20) break; + this_thread::sleep_for(1s); + ++count; + } + if (count == 20) + { + logger->log("No connectivity, waiting for 1.5 km mark or landing."); + } + else { - switch (state) + logger->log("GSM connected."); + + logger->log("Trying to send first SMS..."); + if ( ! GSM::get_instance().send_SMS("2.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) { - case WAITING_LAUNCH: - while ( ! has_launched()) - { - this_thread::sleep_for(1s); - } - this_thread::sleep_for(2min); // TODO: delete - logger.log("Balloon launched."); - - state = set_state(GOING_UP); - logger.log("State changed to "+ state_to_string(state) +"."); - break; - case GOING_UP: - logger.log("Trying to send launch confirmation SMS..."); - if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ - to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ - to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - { - logger.log("Error sending launch confirmation SMS."); - } - else - { - logger.log("Launch confirmation SMS sent."); - } - - // while (GPS::get_instance().get_altitude() < 1500) - // { - this_thread::sleep_for(5s); - // } - this_thread::sleep_for(270s); // TODO: delete - logger.log("1.5 km mark."); - logger.log("Trying to send \"going up\" SMS..."); - if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ - to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ - to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - { - logger.log("Error sending \"going up\" SMS."); - } - else - { - logger.log("\"Going up\" SMS sent."); - } - - logger.log("Turning off GSM..."); - GSM::get_instance().turn_off(); - logger.log("GSM off."); - - this_thread::sleep_for(10min); // TODO: delete - - while ( ! has_bursted()); - logger.log("Balloon burst."); - state = set_state(GOING_DOWN); - logger.log("State changed to "+ state_to_string(state) +"."); - break; - case GOING_DOWN: - while (GPS::get_instance().get_altitude() > 2500) - { - this_thread::sleep_for(5s); - } - this_thread::sleep_for(5min); // TODO: delete - logger.log("2.5 km mark."); - - logger.log("Turning on GSM..."); - GSM::get_instance().turn_on(); - count = 0; - - logger.log("Waiting for GSM connectivity..."); - count = 0; - while ( ! GSM::get_instance().has_connectivity()) - { - if (count == 20) break; - this_thread::sleep_for(1s); - ++count; - } - if (count == 20) - { - logger.log("No connectivity, waiting for 1.5 km mark or landing."); - } - else - { - logger.log("GSM connected."); - - logger.log("Trying to send first SMS..."); - if ( ! GSM::get_instance().send_SMS("2.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - { - logger.log("Error sending first SMS."); - } - else - { - logger.log("First SMS sent."); - } - } - - while (GPS::get_instance().get_altitude() > 1500)// && ! has_landed()) - { - this_thread::sleep_for(5s); - } - this_thread::sleep_for(200s); // TODO: delete - // if ( ! has_landed()) - // { - logger.log("1.5 km mark."); - - count = 0; - while ( ! GSM::get_instance().has_connectivity()) - { - if (count == 20) break; - this_thread::sleep_for(1s); - ++count; - } - if (count == 20) - { - logger.log("No connectivity, waiting for 500 m mark or landing."); - } - else - { - logger.log("GSM connected."); - - logger.log("Trying to send second SMS..."); - if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - { - logger.log("Error sending second SMS."); - } - else - { - logger.log("Second SMS sent."); - } - } - // } - - while ( ! has_landed() && GPS::get_instance().get_altitude() > 500) - { - this_thread::sleep_for(5s); - } - - if ( ! has_landed()) - { - logger.log("500 m mark."); - - count = 0; - while ( ! GSM::get_instance().has_connectivity()) - { - if (count > 15) break; - this_thread::sleep_for(1s); - ++count; - } - if ( ! GSM::get_instance().has_connectivity()) - { - logger.log("No connectivity, waiting for landing."); - } - else - { - logger.log("GSM connected."); - - logger.log("Trying to send third SMS..."); - if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - { - logger.log("Error sending third SMS."); - } - else - { - logger.log("Third SMS sent."); - } - } - } - - this_thread::sleep_for(200s); // TODO: delete - - while ( ! has_landed()) - { - this_thread::sleep_for(5s); - } - logger.log("Landed."); - state = set_state(LANDED); - logger.log("State changed to "+ state_to_string(state) +"."); - break; - case LANDED: - logger.log("Stopping video..."); - if ( ! Camera::get_instance().stop()) - { - logger.log("Error stopping video."); - // TODO try again? - } - else - { - logger.log("Video stopped."); - } - - logger.log("Waiting 1 minute before sending landed SMS..."); - this_thread::sleep_for(1min); - - logger.log("Sending landed SMS..."); - if ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) - { - logger.log("Error sending landed SMS. Trying again in 10 minutes..."); - } - else - { - logger.log("Landed SMS sent. Sending backup SMS in 10 minutes..."); - } - - this_thread::sleep_for(10min); - - logger.log("Sending second landed SMS..."); - - while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE) && - (main_battery >= 0.05 || main_battery < -1) && gsm_battery >= 0.05) - { - logger.log("Error sending second SMS, trying again in 5 minutes."); - this_thread::sleep_for(5min); - GSM::get_instance().get_battery_status(main_battery, gsm_battery); - } - - if ((main_battery < 0.05 && main_battery > -1) || gsm_battery < 0.05) - { - logger.log("Not enough battery."); - logger.log("Main battery: "+ to_string(main_battery) + - "% - GSM battery: "+ to_string(gsm_battery) +"%"); - } - else - { - logger.log("Second SMS sent."); - } + logger->log("Error sending first SMS."); + } + else + { + logger->log("First SMS sent."); + } + } - logger.log("Shutting down..."); - state = set_state(SHUT_DOWN); - logger.log("State changed to "+ state_to_string(state) +"."); + while (GPS::get_instance().get_altitude() > 1500)// && ! has_landed()) + { + this_thread::sleep_for(5s); + } + this_thread::sleep_for(200s); // TODO: delete + // if ( ! has_landed()) + // { + logger->log("1.5 km mark."); + + count = 0; + while ( ! GSM::get_instance().has_connectivity()) + { + if (count == 20) break; + this_thread::sleep_for(1s); + ++count; + } + if (count == 20) + { + logger->log("No connectivity, waiting for 500 m mark or landing."); } + else + { + logger->log("GSM connected."); + + logger->log("Trying to send second SMS..."); + if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger->log("Error sending second SMS."); + } + else + { + logger->log("Second SMS sent."); + } + } + // } + + while ( ! has_landed() && GPS::get_instance().get_altitude() > 500) + { + this_thread::sleep_for(5s); } - logger.log("Turning GSM off..."); - if (GSM::get_instance().turn_off()) - logger.log("GSM off."); - else - logger.log("Error turning GSM off."); + if ( ! has_landed()) + { + logger->log("500 m mark."); - logger.log("Turning GPS off..."); - if (GPS::get_instance().turn_off()) - logger.log("GPS off."); - else - logger.log("Error turning GPS off."); + count = 0; + while ( ! GSM::get_instance().has_connectivity()) + { + if (count > 15) break; + this_thread::sleep_for(1s); + ++count; + } + if ( ! GSM::get_instance().has_connectivity()) + { + logger->log("No connectivity, waiting for landing."); + } + else + { + logger->log("GSM connected."); + + logger->log("Trying to send third SMS..."); + if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger->log("Error sending third SMS."); + } + else + { + logger->log("Third SMS sent."); + } + } + } - logger.log("Joining threads..."); - picture_thread.join(); - gps_thread.join(); - battery_thread.join(); - logger.log("Threads joined."); - logger.log("Powering off..."); - sync(); - // reboot(RB_POWER_OFF); -} + this_thread::sleep_for(200s); // TODO: delete -void os::safe_mode() -{ - // TODO + while ( ! has_landed()) + { + this_thread::sleep_for(5s); + } + logger->log("Landed."); } -inline bool os::file_exists(const string& name) +void os::land(Logger* logger) { - struct stat buffer; - return stat(name.c_str(), &buffer) == 0; -} + logger->log("Stopping video..."); + if ( ! Camera::get_instance().stop()) + logger->log("Error stopping video."); + else + logger->log("Video stopped."); -inline float os::get_available_disk_space() -{ - struct statvfs fs; - statvfs("data", &fs); + logger->log("Waiting 1 minute before sending landed SMS..."); + this_thread::sleep_for(1min); - return ((float) fs.f_bsize)*fs.f_bavail; + logger->log("Sending landed SMS..."); + if ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + { + logger->log("Error sending landed SMS. Trying again in 10 minutes..."); + } + else + { + logger->log("Landed SMS sent. Sending backup SMS in 10 minutes..."); + } + + this_thread::sleep_for(10min); + + logger->log("Sending second landed SMS..."); + + double main_battery = 1, gsm_battery = 1; + while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) + +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE) && + (main_battery >= 0.05 || main_battery < -1) && gsm_battery >= 0.05) + { + logger->log("Error sending second SMS, trying again in 5 minutes."); + this_thread::sleep_for(5min); + GSM::get_instance().get_battery_status(main_battery, gsm_battery); + } + + if ((main_battery < 0.05 && main_battery > -1) || gsm_battery < 0.05) + { + logger->log("Not enough battery."); + logger->log("Main battery: "+ to_string(main_battery) + + "% - GSM battery: "+ to_string(gsm_battery) +"%"); + } + else + { + logger->log("Second SMS sent."); + } } -void os::gps_thread_fn(State& state) +void os::shut_down(Logger* logger) { - struct timeval timer; - gettimeofday(&timer, NULL); - struct tm * now = gmtime(&timer.tv_sec); + logger->log("Shutting down..."); - Logger logger("data/logs/GPS/Position."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "GPSPosition"); + logger->log("Turning GSM off..."); + if (GSM::get_instance().turn_off()) + logger->log("GSM off."); + else + logger->log("Error turning GSM off."); - while (state != SHUT_DOWN) { - logger.log("Lat: "+ to_string(GPS::get_instance().get_latitude()) +", Lon: "+ - to_string(GPS::get_instance().get_longitude()) +", Alt: "+ - to_string(GPS::get_instance().get_altitude()) +", Speed: "+ - to_string(GPS::get_instance().get_velocity().speed) +", Course: "+ - to_string(GPS::get_instance().get_velocity().course) +", Sat: "+ - to_string(GPS::get_instance().get_satellites()) +", PDOP: "+ - to_string(GPS::get_instance().get_PDOP())); + logger->log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger->log("GPS off."); + else + logger->log("Error turning GPS off."); - this_thread::sleep_for(250ms); - } + logger->log("Powering off..."); + sync(); + // reboot(RB_POWER_OFF); } void os::picture_thread_fn(State& state) @@ -683,6 +665,79 @@ void os::battery_thread_fn(State& state) } } +void os::check_or_create(const string& path, Logger* logger) +{ + if ( ! file_exists(path)) + { + if (logger != NULL) + logger->log("[OpenStratos] No '"+path+"' directory, creating..."); + #if DEBUG + else + cout << "[OpenStratos] No '"+path+"' directory, creating..." << endl; + #endif + if (mkdir(path.c_str(), 0755) != 0) + { + if (logger != NULL) + logger->log("[OpenStratos] Error creating '"+path+"' directory."); + #if DEBUG + else + cout << "[OpenStratos] Error creating '"+path+"' directory." << endl; + #endif + exit(1); + + } + else + { + if (logger != NULL) + logger->log("[OpenStratos] '"+path+"' directory created."); + #if DEBUG + else + cout << "[OpenStratos] '"+path+"' directory created." << endl; + #endif + } + } +} + +inline bool os::file_exists(const string& name) +{ + struct stat buffer; + return stat(name.c_str(), &buffer) == 0; +} + +inline float os::get_available_disk_space() +{ + struct statvfs fs; + statvfs("data", &fs); + + return ((float) fs.f_bsize)*fs.f_bavail; +} + +const string os::generate_exif_data() +{ + string exif; + while (GPS::get_instance().get_PDOP() > 5) + { + this_thread::sleep_for(1s); + } + double gps_lat = GPS::get_instance().get_latitude(); + double gps_lon = GPS::get_instance().get_longitude(); + double gps_alt = GPS::get_instance().get_altitude(); + uint_fast8_t gps_sat = GPS::get_instance().get_satellites(); + float gps_pdop = GPS::get_instance().get_PDOP(); + euc_vec gps_velocity = GPS::get_instance().get_velocity(); + + exif += "GPSLatitudeRef="+to_string(gps_lat > 0 ? 'N' : 'S'); + exif += " GPSLatitude="+to_string(abs((int) gps_lat*1000000))+"/1000000,0/1,0/1"; + exif += " GPSLongitudeRef="+to_string(gps_lon > 0 ? 'E' : 'W'); + exif += " GPSLongitude="+to_string(abs((int) gps_lon*1000000))+"/1000000,0/1,0/1"; + exif += " GPSAltitudeRef=0 GPSAltitude="+to_string(gps_alt); + exif += " GPSSatellites="+to_string(gps_sat); + exif += " GPSDOP="+to_string(gps_pdop); + exif += " GPSSpeedRef=K GPSSpeed="+to_string(gps_velocity.speed*3.6); + exif += " GPSTrackRef=T GPSTrack="+to_string(gps_velocity.course); + exif += " GPSDifferential=0"; +} + State os::set_state(State new_state) { ofstream state_file(STATE_FILE); @@ -692,7 +747,7 @@ State os::set_state(State new_state) return new_state; } -State os::get_state() +State os::get_last_state() { ifstream state_file(STATE_FILE); string str_state((istreambuf_iterator(state_file)), @@ -701,6 +756,7 @@ State os::get_state() if (str_state == "INITIALIZING") return INITIALIZING; if (str_state == "ACQUIRING_FIX") return ACQUIRING_FIX; + if (str_state == "FIX_ACQUIRED") return FIX_ACQUIRED; if (str_state == "WAITING_LAUNCH") return WAITING_LAUNCH; if (str_state == "GOING_UP") return GOING_UP; if (str_state == "GOING_DOWN") return GOING_DOWN; @@ -721,6 +777,9 @@ const string os::state_to_string(State state) case ACQUIRING_FIX: return "ACQUIRING_FIX"; break; + case FIX_ACQUIRED: + return "FIX_ACQUIRED"; + break; case WAITING_LAUNCH: return "WAITING_LAUNCH"; break; @@ -743,58 +802,3 @@ const string os::state_to_string(State state) return "RECOVERY"; } } - -bool os::has_launched() -{ - double first_altitude = GPS::get_instance().get_altitude(); - this_thread::sleep_for(5s); - double second_altitude = GPS::get_instance().get_altitude(); - - return true; - // return second_altitude > first_altitude + 10; -} - -bool os::has_bursted() -{ - double first_altitude = GPS::get_instance().get_altitude(); - this_thread::sleep_for(6s); - double second_altitude = GPS::get_instance().get_altitude(); - - return true; - // return second_altitude < first_altitude - 10; -} - -bool os::has_landed() -{ - double first_altitude = GPS::get_instance().get_altitude(); - this_thread::sleep_for(5s); - double second_altitude = GPS::get_instance().get_altitude(); - - return abs(first_altitude-second_altitude) < 5; -} - -const string os::generate_exif_data() -{ - string exif; - while (GPS::get_instance().get_PDOP() > 5) - { - this_thread::sleep_for(1s); - } - double gps_lat = GPS::get_instance().get_latitude(); - double gps_lon = GPS::get_instance().get_longitude(); - double gps_alt = GPS::get_instance().get_altitude(); - uint_fast8_t gps_sat = GPS::get_instance().get_satellites(); - float gps_pdop = GPS::get_instance().get_PDOP(); - euc_vec gps_velocity = GPS::get_instance().get_velocity(); - - exif += "GPSLatitudeRef="+to_string(gps_lat > 0 ? 'N' : 'S'); - exif += " GPSLatitude="+to_string(abs((int) gps_lat*1000000))+"/1000000,0/1,0/1"; - exif += " GPSLongitudeRef="+to_string(gps_lon > 0 ? 'E' : 'W'); - exif += " GPSLongitude="+to_string(abs((int) gps_lon*1000000))+"/1000000,0/1,0/1"; - exif += " GPSAltitudeRef=0 GPSAltitude="+to_string(gps_alt); - exif += " GPSSatellites="+to_string(gps_sat); - exif += " GPSDOP="+to_string(gps_pdop); - exif += " GPSSpeedRef=K GPSSpeed="+to_string(gps_velocity.speed*3.6); - exif += " GPSTrackRef=T GPSTrack="+to_string(gps_velocity.course); - exif += " GPSDifferential=0"; -} diff --git a/openstratos.h b/openstratos.h index 29d137f..d1744c9 100644 --- a/openstratos.h +++ b/openstratos.h @@ -34,6 +34,7 @@ namespace os enum State { INITIALIZING, ACQUIRING_FIX, + FIX_ACQUIRED, WAITING_LAUNCH, GOING_UP, GOING_DOWN, @@ -46,18 +47,31 @@ namespace os void main_logic(); void safe_mode(); - inline bool file_exists(const string& name); - inline float get_available_disk_space(); - void gps_thread_fn(State& state); + void initialize(Logger* logger, tm* now); + void aquire_fix(Logger* logger); + void start_recording(Logger* logger); + void send_init_sms(Logger* logger); + void wait_launch(Logger* logger); + void go_up(Logger* logger); + void go_down(Logger* logger); + void land(Logger* logger); + void shut_down(Logger* logger); + + inline bool has_launched(); + inline bool has_bursted(); + inline bool has_landed(); + void picture_thread_fn(State& state); void battery_thread_fn(State& state); + + void check_or_create(const string& path, Logger* logger = NULL); + inline bool file_exists(const string& name); + inline float get_available_disk_space(); + const string generate_exif_data(); + State set_state(State new_state); - State get_state(); + State get_last_state(); const string state_to_string(State state); - bool has_launched(); - bool has_bursted(); - bool has_landed(); - const string generate_exif_data(); } using namespace std; From e2c68b7bad927380d17fa68185e864b5cfb6c815 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 18:06:42 +0200 Subject: [PATCH 117/169] Close #41 --- serial/Serial.cc | 55 +++++++++++++++++++++++++++++++++++++----------- serial/Serial.h | 9 ++++++-- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/serial/Serial.cc b/serial/Serial.cc index 849e01a..84986bb 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -12,6 +12,9 @@ #include "constants.h" #include "gps/GPS.h" +#if DEBUG + #include "logger/Logger.h" +#endif using namespace std; using namespace os; @@ -24,15 +27,21 @@ Serial::Serial(const string& url, int baud_rate, const string& log_path) gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); - this->logger = new Logger("data/logs/"+log_path+"/Serial."+ to_string(now->tm_year+1900) +"-"+ - to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ - to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "Serial"); + #if DEBUG + this->logger = new Logger("data/logs/"+log_path+"/Serial."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "Serial"); + #endif #ifndef OS_TESTING this->fd = serialOpen(url.c_str(), baud_rate); - if (this->fd == -1) this->logger->log("Error: connection fd is -1."); - else this->open = true; + #if DEBUG + if (this->fd == -1) this->logger->log("Error: connection fd is -1."); + else this->open = true; + #else + if (this->fd != -1) this->open = true; + #endif #endif } @@ -40,25 +49,37 @@ Serial::~Serial() { if (this->open) this->close(); - delete this->logger; + + #if DEBUG + delete this->logger; + #endif } void Serial::println(const string& str) const { serialPuts(this->fd, (str+"\r\n").c_str()); - this->logger->log("Sent: '"+str+"\\r\\n'"); + + #if DEBUG + this->logger->log("Sent: '"+str+"\\r\\n'"); + #endif } void Serial::println() const { serialPuts(this->fd, "\r\n"); - this->logger->log("Sent: '\\r\\n'"); + + #if DEBUG + this->logger->log("Sent: '\\r\\n'"); + #endif } void Serial::write(unsigned char c) const { serialPutchar(this->fd, c); - this->logger->log("Sent char: '"+string(1, c)+"'"); + + #if DEBUG + this->logger->log("Sent char: '"+string(1, c)+"'"); + #endif } void Serial::close() @@ -111,7 +132,10 @@ const string Serial::read_line(double timeout) const if (elapsed_time > timeout) { - this->logger->log("Error: Serial timeout. ("+to_string(timeout)+" s)"); + #if DEBUG + this->logger->log("Error: Serial timeout. ("+to_string(timeout)+" s)"); + #endif + break; } @@ -143,13 +167,20 @@ const string Serial::read_line(double timeout) const if (available < 0) { - this->logger->log("Error: Serial available < 0."); + #if DEBUG + this->logger->log("Error: Serial available < 0."); + #endif + break; } this_thread::sleep_for(1ms); } #endif - this->logger->log("Received: '"+logstr+"'"); + + #if DEBUG + this->logger->log("Received: '"+logstr+"'"); + #endif + return response; } diff --git a/serial/Serial.h b/serial/Serial.h index 8c97a18..796e8f7 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -5,7 +5,10 @@ #include -#include "logger/Logger.h" +#include "constants.h" +#if DEBUG + #include "logger/Logger.h" +#endif using namespace std; namespace os { @@ -15,7 +18,9 @@ namespace os { int fd; bool open; - Logger* logger; + #if DEBUG + Logger* logger; + #endif void gps_thread(); public: From 5062bc8dda71e64e874ec484f59e5e96baefb627 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 18:29:34 +0200 Subject: [PATCH 118/169] Close #42. For no SMS mode: first ./configure CPPFLAGS=-DNO_SMS and then make clean && make. --- gsm/GSM.cc | 70 +++++++++++++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 69495c9..1a3ef3b 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -122,43 +122,47 @@ bool GSM::send_SMS(const string& message, const string& number) this->occupied = true; this->logger->log("Sending SMS: \""+message+"\" to number "+number+"."); - if (this->send_command_read("AT+CMGF=1") != "OK") - { - this->logger->log("Error sending SMS on 'AT+CMGD=1' response."); - this->occupied = false; - return false; - } + #ifndef NO_SMS + if (this->send_command_read("AT+CMGF=1") != "OK") + { + this->logger->log("Error sending SMS on 'AT+CMGD=1' response."); + this->occupied = false; + return false; + } - if (this->send_command_read("AT+CMGS=\""+number+"\"") != "> ") - { - this->logger->log("Error sending SMS on 'AT+CMGS' response."); - this->occupied = false; - return false; - } + if (this->send_command_read("AT+CMGS=\""+number+"\"") != "> ") + { + this->logger->log("Error sending SMS on 'AT+CMGS' response."); + this->occupied = false; + return false; + } - this->serial->println(message); - this->serial->read_line(); // Eat message echo - this->serial->println(); - this->serial->read_line(); // Eat prompt - this->serial->write('\x1A'); - this->serial->read_line(10); // Eat prompt (timeout 10 seconds) + this->serial->println(message); + this->serial->read_line(); // Eat message echo + this->serial->println(); + this->serial->read_line(); // Eat prompt + this->serial->write('\x1A'); + this->serial->read_line(10); // Eat prompt (timeout 10 seconds) - // Read line - if (this->serial->read_line().find("+CMGS") == string::npos) - { - this->logger->log("Error sending SMS. Could not read '+CMGS'."); - this->occupied = false; - return false; - } - this->serial->read_line(); // Eat new line + // Read line + if (this->serial->read_line().find("+CMGS") == string::npos) + { + this->logger->log("Error sending SMS. Could not read '+CMGS'."); + this->occupied = false; + return false; + } + this->serial->read_line(); // Eat new line - // Read OK (timeout 10 seconds) - if (this->serial->read_line(10) != "OK") - { - this->logger->log("Error sending SMS. Could not read 'OK'."); - this->occupied = false; - return false; - } + // Read OK (timeout 10 seconds) + if (this->serial->read_line(10) != "OK") + { + this->logger->log("Error sending SMS. Could not read 'OK'."); + this->occupied = false; + return false; + } + #else + this_thread::sleep_for(5s); + #endif this->occupied = false; this->logger->log("SMS sent."); From 2a543a7fed15112aa436497870c4fe36da294750 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 19:15:30 +0200 Subject: [PATCH 119/169] Fixed some compiling issues --- openstratos.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index e40536d..da0be10 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -311,7 +311,7 @@ void os::start_recording(Logger* logger) logger->log("Recording started."); } -void send_init_sms(Logger* logger) +void os::send_init_sms(Logger* logger) { logger->log("Sending initialization SMS..."); if ( ! GSM::get_instance().send_SMS("Initialization finished OK. Recording. Waiting for launch.", SMS_PHONE)) @@ -345,7 +345,7 @@ void send_init_sms(Logger* logger) logger->log("Initialization SMS sent."); } -void wait_launch(Logger* logger) +void os::wait_launch(Logger* logger) { logger->log("Waiting for launch..."); while ( ! has_launched()) @@ -355,7 +355,7 @@ void wait_launch(Logger* logger) logger->log("Balloon launched."); } -void go_up(Logger* logger) +void os::go_up(Logger* logger) { logger->log("Trying to send launch confirmation SMS..."); if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ @@ -397,7 +397,7 @@ void go_up(Logger* logger) logger->log("Balloon burst."); } -void go_down(Logger* logger) +void os::go_down(Logger* logger) { while (GPS::get_instance().get_altitude() > 2500) { From 3bd49e105371451fed67deefe56e24bb001415fc Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 19:30:50 +0200 Subject: [PATCH 120/169] Better logger messages in directory creation --- openstratos.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index da0be10..cb0a786 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -670,7 +670,7 @@ void os::check_or_create(const string& path, Logger* logger) if ( ! file_exists(path)) { if (logger != NULL) - logger->log("[OpenStratos] No '"+path+"' directory, creating..."); + logger->log("No '"+path+"' directory, creating..."); #if DEBUG else cout << "[OpenStratos] No '"+path+"' directory, creating..." << endl; @@ -678,7 +678,7 @@ void os::check_or_create(const string& path, Logger* logger) if (mkdir(path.c_str(), 0755) != 0) { if (logger != NULL) - logger->log("[OpenStratos] Error creating '"+path+"' directory."); + logger->log("Error creating '"+path+"' directory."); #if DEBUG else cout << "[OpenStratos] Error creating '"+path+"' directory." << endl; @@ -689,7 +689,7 @@ void os::check_or_create(const string& path, Logger* logger) else { if (logger != NULL) - logger->log("[OpenStratos] '"+path+"' directory created."); + logger->log("'"+path+"' directory created."); #if DEBUG else cout << "[OpenStratos] '"+path+"' directory created." << endl; From 54ea7b6ca334bce6984f8f5a415e240b0370655f Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 22:38:02 +0200 Subject: [PATCH 121/169] Closed #38 and #43. To activate simulation mode, pass CPPFLAGS=-DSIM to ./configure script. To activate real simulation mode, pass CPPFLAGS=-DREAL_SIM to ./configure script. If no flag is passed it assumes real launch. If both flags are passed, the behaviour could be unexpected. They can be combined with the NO_SMS flag using CPPFLAGS="-DNO_SMS -DSIM" for normal simulation or CPPFLAGS="-DNO_SMS -DREAL_SIM". --- openstratos.cc | 228 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 190 insertions(+), 38 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index cb0a786..58dc558 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -95,6 +95,8 @@ void os::main_logic() else if (state == GOING_UP) { go_up(&logger); + logger.log("Balloon burst."); + state = set_state(GOING_DOWN); logger.log("State changed to "+ state_to_string(state) +"."); } @@ -133,8 +135,11 @@ inline bool os::has_launched() this_thread::sleep_for(5s); double second_altitude = GPS::get_instance().get_altitude(); - return true; - // return second_altitude > first_altitude + 10; + #if defined SIM || defined REAL_SIM + return true; + #else + return second_altitude > first_altitude + 10; + #endif } inline bool os::has_bursted() @@ -143,8 +148,11 @@ inline bool os::has_bursted() this_thread::sleep_for(6s); double second_altitude = GPS::get_instance().get_altitude(); - return true; - // return second_altitude < first_altitude - 10; + #if defined SIM || defined REAL_SIM + return true; + #else + return second_altitude < first_altitude - 10; + #endif } inline bool os::has_landed() @@ -348,10 +356,16 @@ void os::send_init_sms(Logger* logger) void os::wait_launch(Logger* logger) { logger->log("Waiting for launch..."); + #ifdef SIM + this_thread::sleep_for(2min); + #endif + #ifdef REAL_SIM + this_thread::sleep_for(20min); + #endif + while ( ! has_launched()) this_thread::sleep_for(1s); - this_thread::sleep_for(2min); // TODO: delete logger->log("Balloon launched."); } @@ -369,11 +383,14 @@ void os::go_up(Logger* logger) logger->log("Launch confirmation SMS sent."); } - // while (GPS::get_instance().get_altitude() < 1500) - // { - this_thread::sleep_for(5s); - // } - this_thread::sleep_for(270s); // TODO: delete + #if !defined SIM && !defined REAL_SIM + while (GPS::get_instance().get_altitude() < 1500) + { + this_thread::sleep_for(2s); + } + #else + this_thread::sleep_for(275s); + #endif logger->log("1.5 km mark."); logger->log("Trying to send \"going up\" SMS..."); if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ @@ -391,20 +408,148 @@ void os::go_up(Logger* logger) GSM::get_instance().turn_off(); logger->log("GSM off."); - this_thread::sleep_for(10min); // TODO: delete + bool bursted = false; + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("5 km mark passed going up."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(1435s); + logger->log("5 km mark passed going up."); + #else + while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 5000); + if ( ! bursted) logger->log("5 km mark passed going up."); + else return; + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("10 km mark passed going up."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(2000s); + logger->log("10 km mark passed going up."); + #else + while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 10000); + if ( ! bursted) logger->log("10 km mark passed going up."); + else return; + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("15 km mark passed going up."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(2000s); + logger->log("15 km mark passed going up."); + #else + while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 15000); + if ( ! bursted) logger->log("15 km mark passed going up."); + else return; + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("20 km mark passed going up."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(2000s); + logger->log("20 km mark passed going up."); + #else + while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 20000); + if ( ! bursted) logger->log("20 km mark passed going up."); + else return; + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("25 km mark passed going up."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(2000s); + logger->log("25 km mark passed going up."); + #else + while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 25000); + if ( ! bursted) logger->log("25 km mark passed going up."); + else return; + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("30 km mark passed going up."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(2000s); + logger->log("30 km mark passed going up."); + #else + while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 30000); + if ( ! bursted) logger->log("30 km mark passed going up."); + else return; + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("35 km mark passed going up."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(2000s); + logger->log("35 km mark passed going up."); + #else + while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 35000); + if ( ! bursted) logger->log("35 km mark passed going up."); + else return; + #endif while ( ! has_bursted()); - logger->log("Balloon burst."); } void os::go_down(Logger* logger) { - while (GPS::get_instance().get_altitude() > 2500) - { - this_thread::sleep_for(5s); - } - this_thread::sleep_for(5min); // TODO: delete - logger->log("2.5 km mark."); + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(1min); + logger->log("25 km mark passed going down."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(5min); + logger->log("25 km mark passed going down."); + #else + while (GPS::get_instance().get_altitude() > 25000) + this_thread::sleep_for(5s); + + logger->log("25 km mark passed going down."); + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(1min); + logger->log("15 km mark passed going down."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(650s); + logger->log("15 km mark passed going down."); + #else + while (GPS::get_instance().get_altitude() > 15000) + this_thread::sleep_for(5s); + + logger->log("15 km mark passed going down."); + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(2min); + logger->log("5 km mark passed going down."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(1400s); + logger->log("5 km mark passed going down."); + #else + while (GPS::get_instance().get_altitude() > 5000) + this_thread::sleep_for(5s); + + logger->log("5 km mark passed going down."); + #endif + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(1min); + logger->log("2.5 km mark passed going down."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(500s); + logger->log("2.5 km mark passed going down."); + #else + while (GPS::get_instance().get_altitude() > 2500) + this_thread::sleep_for(5s); + + logger->log("2.5 km mark passed going down."); + #endif logger->log("Turning on GSM..."); GSM::get_instance().turn_on(); @@ -437,15 +582,21 @@ void os::go_down(Logger* logger) } } - while (GPS::get_instance().get_altitude() > 1500)// && ! has_landed()) - { - this_thread::sleep_for(5s); - } - this_thread::sleep_for(200s); // TODO: delete - // if ( ! has_landed()) - // { - logger->log("1.5 km mark."); + bool landed = false; + + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(1min); + logger->log("1.5 km mark passed going down."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(175s); + logger->log("1.5 km mark passed going down."); + #else + while (GPS::get_instance().get_altitude() > 1500 && ! (landed = has_landed())); + if ( ! landed) logger->log("1.5 km mark passed going down."); + #endif + if ( ! landed) + { count = 0; while ( ! GSM::get_instance().has_connectivity()) { @@ -472,14 +623,20 @@ void os::go_down(Logger* logger) logger->log("Second SMS sent."); } } - // } - - while ( ! has_landed() && GPS::get_instance().get_altitude() > 500) - { - this_thread::sleep_for(5s); } - if ( ! has_landed()) + #if defined SIM && !defined REAL_SIM + this_thread::sleep_for(1min); + logger->log("500 m mark passed going down."); + #elif defined REAL_SIM && !defined SIM + this_thread::sleep_for(225s); + logger->log("500 m mark passed going down."); + #else + while (GPS::get_instance().get_altitude() > 500 && ! (landed = has_landed())); + if ( ! landed) logger->log("500 m mark passed going down."); + #endif + + if ( ! landed) { logger->log("500 m mark."); @@ -511,12 +668,7 @@ void os::go_down(Logger* logger) } } - this_thread::sleep_for(200s); // TODO: delete - - while ( ! has_landed()) - { - this_thread::sleep_for(5s); - } + while ( ! has_landed()); logger->log("Landed."); } From 6e489da00740a1ac3a8a0c111c56abba1c238cc1 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 23:11:49 +0200 Subject: [PATCH 122/169] Fixed GPS setting month incorrectly --- gps/GPS.cc | 2 +- testing/gps_test.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index 155bc0f..f9dc7b3 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -293,7 +293,7 @@ void GPS::parse_RMC(const string& frame) this->time.tm_sec = stoi(s_data[1].substr(4, 2)); this->time.tm_mday = stoi(s_data[9].substr(0, 2)); - this->time.tm_mon = stoi(s_data[9].substr(2, 2)); + this->time.tm_mon = stoi(s_data[9].substr(2, 2))-1; this->time.tm_year = stoi(s_data[9].substr(4, 2))+100; // Update latitude diff --git a/testing/gps_test.cc b/testing/gps_test.cc index 25457a4..a1d3c1e 100644 --- a/testing/gps_test.cc +++ b/testing/gps_test.cc @@ -92,7 +92,7 @@ describe("GPS", [](){ tm gps_time = GPS::get_instance().get_time(); AssertThat(gps_time.tm_mday, Equals(19)); - AssertThat(gps_time.tm_mon, Equals(11)); + AssertThat(gps_time.tm_mon, Equals(10)); AssertThat(gps_time.tm_year, Equals(194)); AssertThat(gps_time.tm_hour, Equals(22)); AssertThat(gps_time.tm_min, Equals(54)); From 7e9346832c27a5d13fafff44359db1e2a70c5ceb Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 26 Aug 2015 23:47:20 +0200 Subject: [PATCH 123/169] Added small debug message for simulations --- openstratos.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/openstratos.cc b/openstratos.cc index 58dc558..5aeaab6 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -3,6 +3,14 @@ int main(void) { #if DEBUG + #ifdef SIM + cout << "[OpenStratos] Simulation." << endl; + #endif + + #ifdef REAL_SIM + cout << "[OpenStratos] Realistic simulation." << endl; + #endif + cout << "[OpenStratos] Starting..." << endl; #endif From 67056eff3af96d59a6df555250f6275a9bc79d31 Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 28 Aug 2015 16:49:25 +0200 Subject: [PATCH 124/169] Updated script to real weight --- constants.h | 2 +- openstratos.cc | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/constants.h b/constants.h index 7d1c770..201ebee 100644 --- a/constants.h +++ b/constants.h @@ -3,7 +3,7 @@ #define DEBUG true - #define FLIGHT_LENGTH 4.8 // Hours + #define FLIGHT_LENGTH 4.55 // Hours #define BAT_GSM_MAX 4.2 #define BAT_GSM_MIN 3.7 diff --git a/openstratos.cc b/openstratos.cc index 5aeaab6..0247242 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -397,7 +397,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2s); } #else - this_thread::sleep_for(275s); + this_thread::sleep_for(260s); #endif logger->log("1.5 km mark."); logger->log("Trying to send \"going up\" SMS..."); @@ -422,7 +422,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("5 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1435s); + this_thread::sleep_for(1400s); logger->log("5 km mark passed going up."); #else while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 5000); @@ -434,7 +434,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("10 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2000s); + this_thread::sleep_for(2008s); logger->log("10 km mark passed going up."); #else while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 10000); @@ -446,7 +446,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("15 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2000s); + this_thread::sleep_for(2008s); logger->log("15 km mark passed going up."); #else while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 15000); @@ -458,7 +458,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("20 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2000s); + this_thread::sleep_for(2008s); logger->log("20 km mark passed going up."); #else while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 20000); @@ -470,7 +470,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("25 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2000s); + this_thread::sleep_for(2008s); logger->log("25 km mark passed going up."); #else while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 25000); @@ -482,7 +482,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("30 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2000s); + this_thread::sleep_for(2008s); logger->log("30 km mark passed going up."); #else while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 30000); @@ -494,7 +494,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("35 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2000s); + this_thread::sleep_for(2008s); logger->log("35 km mark passed going up."); #else while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 35000); From 97988c515b03e601665b57022d541927b93888e6 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 29 Aug 2015 13:14:33 +0200 Subject: [PATCH 125/169] Added startup script. Closes #21 and #23. --- startup.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100755 startup.sh diff --git a/startup.sh b/startup.sh new file mode 100755 index 0000000..26fa1c2 --- /dev/null +++ b/startup.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +echo "[`date`] Starting OpenStratos..." >> /root/control.log +/root/openstratos >> /root/control.log 2>&1 & +sleep 5 + +while true; do + (pgrep procname && sleep 60) || + (echo "[`date`] Process not running, restarting..." >> /root/control.log; shutdown -r now) +done From b443f3062e91d5724b670501c842ee5d74be1929 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 29 Aug 2015 20:11:48 +0200 Subject: [PATCH 126/169] Fixed #39 --- camera/Camera.cc | 18 ++++++++++++++++++ camera/Camera.h | 1 + 2 files changed, 19 insertions(+) diff --git a/camera/Camera.cc b/camera/Camera.cc index 495c1e2..06ce96c 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -167,6 +167,13 @@ bool Camera::stop() return true; } this->logger->log("Error stopping video recording."); + + if ( ! this->is_really_recording()) + { + this->logger->log("Warning: error was already stopped."); + this->recording = false; + return true; + } return false; #else this->logger->log("Test mode. Video recording stop simulated."); @@ -175,6 +182,17 @@ bool Camera::stop() #endif } +bool Camera::is_really_recording() const +{ + FILE* process = popen("pgrep raspivid", "r"); + char response[5]; + fgets(response, 5, process); + pclose(process); + + if (process == NULL) this->logger->log("Error checking if raspivid is really recording"); + return (process != NULL && response != NULL); +} + int os::get_file_count(const string& path) { DIR *dp; diff --git a/camera/Camera.h b/camera/Camera.h index bbd1fca..e2c00c2 100644 --- a/camera/Camera.h +++ b/camera/Camera.h @@ -17,6 +17,7 @@ namespace os { bool recording = false; Camera(); void record_thread(int time); + bool is_really_recording() const; public: Camera(Camera& copy) = delete; ~Camera(); From 2ca23ac08b4df19b9105ede1e7f18113997e8c55 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 29 Aug 2015 22:12:10 +0200 Subject: [PATCH 127/169] Started with #40. Still many cases to to. Also fixed two small errors in GSM destructor. They were not causing any issue apart from log warnings. --- gsm/GSM.cc | 11 ++- openstratos.cc | 210 ++++++++++++++++++++++++++++++++++++------------- openstratos.h | 2 +- 3 files changed, 162 insertions(+), 61 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 1a3ef3b..23f066e 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -22,7 +22,6 @@ GSM& GSM::get_instance() GSM::~GSM() { - this->turn_off(); if (this->serial->is_open()) { this->logger->log("Closing serial interface..."); @@ -35,9 +34,13 @@ GSM::~GSM() this->logger->log("Deallocating command logger..."); delete this->command_logger; } - this->logger->log("Shutting down..."); - this->turn_off(); - this->logger->log("Shut down finished."); + + if (this->get_status()) + { + this->logger->log("Shutting down..."); + this->turn_off(); + this->logger->log("Shut down finished."); + } delete this->logger; } diff --git a/openstratos.cc b/openstratos.cc index 0247242..316a2f8 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -79,62 +79,155 @@ void os::main_logic() state = set_state(ACQUIRING_FIX); logger.log("State changed to "+ state_to_string(state) +"."); - while (state != SHUT_DOWN) + main_while(&logger, &state); + + logger.log("Joining threads..."); + picture_thread.join(); + battery_thread.join(); + logger.log("Threads joined."); + + shut_down(&logger); +} + +void os::safe_mode() +{ + State last_state = get_last_state(); + State state = set_state(SAFE_MODE); + Logger* logger; + int count = 0; + + if (last_state > INITIALIZING) + { + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm* now = gmtime(&timer.tv_sec); + + logger = new Logger("data/logs/main/OpenStratos."+ to_string(now->tm_year+1900) +"-"+ + to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ + to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "OpenStratos"); + } + + switch (last_state) { - if (state == ACQUIRING_FIX) + case INITIALIZING: + case ACQUIRING_FIX: + remove("data"); + reboot(RB_AUTOBOOT); + break; + case FIX_ACQUIRED: // It could be that the SMS was sent but the state didn't change + case WAITING_LAUNCH: + logger->log("Initializing WiringPi..."); + wiringPiSetup(); + logger->log("WiringPi initialized."); + + logger->log("Initializing GPS..."); + + while ( ! GPS::get_instance().initialize() && ++count < 5) + logger->log("GPS initialization error."); + + if (count < 5) + { + logger->log("GPS initialized."); + count = 0; + while ( ! GPS::get_instance().is_active() && ++count < 10) + this_thread::sleep_for(10s); + this_thread::sleep_for(10s); + if (count == 10) + { + logger->log("Not getting fix. Going to recovery mode."); + reboot(RB_AUTOBOOT); + } + + double start_alt = GPS::get_instance().get_altitude(); + this_thread::sleep_for(5s); + double end_alt = GPS::get_instance().get_altitude(); + + if (end_alt - start_alt < -10) state = set_state(GOING_DOWN); + else if (end_alt - start_alt > 10) state = set_state(GOING_UP); + else if (end_alt > 5000) state = set_state(GOING_DOWN); + else state = set_state(LANDED); + + logger->log("Initializing GSM..."); + if ( ! GSM::get_instance().initialize()) + { + logger->log("GSM initialization error. Going to recovery mode."); + reboot(RB_AUTOBOOT); + } + logger->log("GSM initialized."); + + main_while(logger, &state); + shut_down(logger); + } + else + { + logger->log("Error initializing GPS. Going to recovery mode."); + reboot(RB_AUTOBOOT); + } + break; + case GOING_UP: + break; + case GOING_DOWN: + break; + case LANDED: + break; + case SHUT_DOWN: + break; + case SAFE_MODE: + logger->log("Recovery mode"); + // TODO recovery mode + } + + if (logger) delete logger; +} + +void os::main_while(Logger* logger, State* state) +{ + while (*state != SHUT_DOWN) + { + if (*state == ACQUIRING_FIX) { - aquire_fix(&logger); - state = set_state(FIX_ACQUIRED); - logger.log("State changed to "+ state_to_string(state) +"."); + aquire_fix(logger); + *state = set_state(FIX_ACQUIRED); + logger->log("State changed to "+ state_to_string(*state) +"."); } - else if (state == FIX_ACQUIRED) + else if (*state == FIX_ACQUIRED) { - start_recording(&logger); - send_init_sms(&logger); - state = set_state(WAITING_LAUNCH); - logger.log("State changed to "+ state_to_string(state) +"."); + start_recording(logger); + send_init_sms(logger); + *state = set_state(WAITING_LAUNCH); + logger->log("State changed to "+ state_to_string(*state) +"."); } - else if (state == WAITING_LAUNCH) + else if (*state == WAITING_LAUNCH) { - wait_launch(&logger); - state = set_state(GOING_UP); - logger.log("State changed to "+ state_to_string(state) +"."); + wait_launch(logger); + *state = set_state(GOING_UP); + logger->log("State changed to "+ state_to_string(*state) +"."); } - else if (state == GOING_UP) + else if (*state == GOING_UP) { - go_up(&logger); - logger.log("Balloon burst."); + go_up(logger); + logger->log("Balloon burst."); - state = set_state(GOING_DOWN); - logger.log("State changed to "+ state_to_string(state) +"."); + *state = set_state(GOING_DOWN); + logger->log("State changed to "+ state_to_string(*state) +"."); + } + else if (*state == GOING_DOWN) + { + go_down(logger); + *state = set_state(LANDED); + logger->log("State changed to "+ state_to_string(*state) +"."); } - else if (state == GOING_DOWN) + else if (*state == LANDED) { - go_down(&logger); - state = set_state(LANDED); - logger.log("State changed to "+ state_to_string(state) +"."); + land(logger); + *state = set_state(SHUT_DOWN); + logger->log("State changed to "+ state_to_string(*state) +"."); } - else if (state == LANDED) + else { - land(&logger); - state = set_state(SHUT_DOWN); - logger.log("State changed to "+ state_to_string(state) +"."); + reboot(RB_AUTOBOOT); } - // else - // TODO reboot } - - logger.log("Joining threads..."); - picture_thread.join(); - battery_thread.join(); - logger.log("Threads joined."); - - shut_down(&logger); -} - -void os::safe_mode() -{ - // TODO } inline bool os::has_launched() @@ -183,7 +276,8 @@ void os::initialize(Logger* logger, tm* now) if (available_disk_space < FLIGHT_LENGTH*9437184000) // 1.25 times the flight length { logger->log("Error: Not enough disk space."); - exit(1); + sync(); + reboot(RB_POWER_OFF); } logger->log("Disk space enough for about " + to_string(available_disk_space/7549747200) + @@ -197,7 +291,8 @@ void os::initialize(Logger* logger, tm* now) if ( ! GPS::get_instance().initialize()) { logger->log("GPS initialization error."); - exit(1); + sync(); + reboot(RB_POWER_OFF); } logger->log("GPS initialized."); @@ -211,7 +306,8 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - exit(1); + sync(); + reboot(RB_POWER_OFF); } logger->log("GSM initialized."); @@ -237,7 +333,8 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - exit(1); + sync(); + reboot(RB_POWER_OFF); } logger->log("Waiting for GSM connectivity..."); @@ -256,7 +353,8 @@ void os::initialize(Logger* logger, tm* now) if ( ! Camera::get_instance().record(10000)) { logger->log("Error starting recording"); - exit(1); + sync(); + reboot(RB_POWER_OFF); } this_thread::sleep_for(11s); if (file_exists("data/video/test.h264")) @@ -284,7 +382,8 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - exit(1); + sync(); + reboot(RB_POWER_OFF); } } @@ -322,7 +421,8 @@ void os::start_recording(Logger* logger) else logger->log("Error turning GPS off."); - exit(1); + sync(); + reboot(RB_POWER_OFF); } logger->log("Recording started."); } @@ -356,7 +456,8 @@ void os::send_init_sms(Logger* logger) else logger->log("Error turning GPS off."); - exit(1); + sync(); + reboot(RB_POWER_OFF); } logger->log("Initialization SMS sent."); } @@ -746,7 +847,7 @@ void os::shut_down(Logger* logger) logger->log("Powering off..."); sync(); - // reboot(RB_POWER_OFF); + reboot(RB_POWER_OFF); } void os::picture_thread_fn(State& state) @@ -843,8 +944,9 @@ void os::check_or_create(const string& path, Logger* logger) else cout << "[OpenStratos] Error creating '"+path+"' directory." << endl; #endif - exit(1); + sync(); + reboot(RB_POWER_OFF); } else { @@ -922,9 +1024,8 @@ State os::get_last_state() if (str_state == "GOING_DOWN") return GOING_DOWN; if (str_state == "LANDED") return LANDED; if (str_state == "SHUT_DOWN") return SHUT_DOWN; - if (str_state == "SAFE_MODE") return SAFE_MODE; - return RECOVERY; + return SAFE_MODE; } const string os::state_to_string(State state) @@ -957,8 +1058,5 @@ const string os::state_to_string(State state) break; case SAFE_MODE: return "SAFE_MODE"; - break; - case RECOVERY: - return "RECOVERY"; } } diff --git a/openstratos.h b/openstratos.h index d1744c9..0b2ab69 100644 --- a/openstratos.h +++ b/openstratos.h @@ -41,11 +41,11 @@ namespace os LANDED, SHUT_DOWN, SAFE_MODE, - RECOVERY, }; void main_logic(); void safe_mode(); + void main_while(Logger* logger, State* state); void initialize(Logger* logger, tm* now); void aquire_fix(Logger* logger); From 915476313e077d1b0473252ea24d5aab21406742 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 2 Sep 2015 18:24:17 +0200 Subject: [PATCH 128/169] Fixed #36 --- openstratos.cc | 63 ++++++++++++++++++++++++++++++++++++++++---------- openstratos.h | 4 ++-- 2 files changed, 53 insertions(+), 14 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 316a2f8..4a1ef02 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -230,9 +230,11 @@ void os::main_while(Logger* logger, State* state) } } -inline bool os::has_launched() +inline bool os::has_launched(double launch_altitude) { double first_altitude = GPS::get_instance().get_altitude(); + if (first_altitude > launch_altitude + 100) return true; + this_thread::sleep_for(5s); double second_altitude = GPS::get_instance().get_altitude(); @@ -243,9 +245,11 @@ inline bool os::has_launched() #endif } -inline bool os::has_bursted() +inline bool os::has_bursted(double maximum_altitude) { double first_altitude = GPS::get_instance().get_altitude(); + if (first_altitude < maximum_altitude - 1000) return true; + this_thread::sleep_for(6s); double second_altitude = GPS::get_instance().get_altitude(); @@ -465,6 +469,7 @@ void os::send_init_sms(Logger* logger) void os::wait_launch(Logger* logger) { logger->log("Waiting for launch..."); + double launch_altitude = GPS::get_instance().get_altitude(); #ifdef SIM this_thread::sleep_for(2min); #endif @@ -472,7 +477,7 @@ void os::wait_launch(Logger* logger) this_thread::sleep_for(20min); #endif - while ( ! has_launched()) + while ( ! has_launched(launch_altitude)) this_thread::sleep_for(1s); logger->log("Balloon launched."); @@ -492,9 +497,13 @@ void os::go_up(Logger* logger) logger->log("Launch confirmation SMS sent."); } + double maximum_altitude = 0; + double current_altitude = GPS::get_instance().get_altitude(); + #if !defined SIM && !defined REAL_SIM - while (GPS::get_instance().get_altitude() < 1500) + while (current_altitude = GPS::get_instance().get_altitude() < 1500) { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; this_thread::sleep_for(2s); } #else @@ -526,7 +535,11 @@ void os::go_up(Logger* logger) this_thread::sleep_for(1400s); logger->log("5 km mark passed going up."); #else - while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 5000); + while ( ! (bursted = has_bursted(maximum_altitude)) && + (current_altitude = GPS::get_instance().get_altitude()) < 5000) + { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; + } if ( ! bursted) logger->log("5 km mark passed going up."); else return; #endif @@ -538,7 +551,11 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2008s); logger->log("10 km mark passed going up."); #else - while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 10000); + while ( ! (bursted = has_bursted(maximum_altitude)) && + (current_altitude = GPS::get_instance().get_altitude()) < 10000) + { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; + } if ( ! bursted) logger->log("10 km mark passed going up."); else return; #endif @@ -550,7 +567,11 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2008s); logger->log("15 km mark passed going up."); #else - while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 15000); + while ( ! (bursted = has_bursted(maximum_altitude)) && + (current_altitude = GPS::get_instance().get_altitude()) < 15000) + { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; + } if ( ! bursted) logger->log("15 km mark passed going up."); else return; #endif @@ -562,7 +583,11 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2008s); logger->log("20 km mark passed going up."); #else - while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 20000); + while ( ! (bursted = has_bursted(maximum_altitude)) && + (current_altitude = GPS::get_instance().get_altitude()) < 20000) + { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; + } if ( ! bursted) logger->log("20 km mark passed going up."); else return; #endif @@ -574,7 +599,11 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2008s); logger->log("25 km mark passed going up."); #else - while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 25000); + while ( ! (bursted = has_bursted(maximum_altitude)) && + (current_altitude = GPS::get_instance().get_altitude()) < 25000) + { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; + } if ( ! bursted) logger->log("25 km mark passed going up."); else return; #endif @@ -586,7 +615,11 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2008s); logger->log("30 km mark passed going up."); #else - while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 30000); + while ( ! (bursted = has_bursted(maximum_altitude)) && + (current_altitude = GPS::get_instance().get_altitude()) < 30000) + { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; + } if ( ! bursted) logger->log("30 km mark passed going up."); else return; #endif @@ -598,12 +631,18 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2008s); logger->log("35 km mark passed going up."); #else - while ( ! (bursted = has_bursted()) && GPS::get_instance().get_altitude() < 35000); + while ( ! (bursted = has_bursted(maximum_altitude)) && + (current_altitude = GPS::get_instance().get_altitude()) < 35000) + { + if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; + } if ( ! bursted) logger->log("35 km mark passed going up."); else return; #endif - while ( ! has_bursted()); + while ( ! has_bursted(maximum_altitude)) + if ((current_altitude = GPS::get_instance().get_altitude()) > maximum_altitude) + maximum_altitude = current_altitude; } void os::go_down(Logger* logger) diff --git a/openstratos.h b/openstratos.h index 0b2ab69..5a292b4 100644 --- a/openstratos.h +++ b/openstratos.h @@ -57,8 +57,8 @@ namespace os void land(Logger* logger); void shut_down(Logger* logger); - inline bool has_launched(); - inline bool has_bursted(); + inline bool has_launched(double launch_altitude); + inline bool has_bursted(double maximum_altitude); inline bool has_landed(); void picture_thread_fn(State& state); From 2c5f326e68740c72901a6e9f7d5a2c4301d4736a Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 2 Sep 2015 19:16:01 +0200 Subject: [PATCH 129/169] Implemented #28. Still testing needed --- gps/GPS.cc | 2 ++ gsm/GSM.cc | 84 +++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 79 insertions(+), 7 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index f9dc7b3..4737f2c 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -114,6 +114,7 @@ bool GPS::turn_on() const } else { + this->logger->log("Error: Turning on GPS but GPS already on."); return false; } } @@ -127,6 +128,7 @@ bool GPS::turn_off() const } else { + this->logger->log("Error: Turning off GPS but GPS already off."); return false; } } diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 23f066e..f079e6d 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -177,22 +177,92 @@ bool GSM::get_location(double& latitude, double& longitude) while (this->occupied) this_thread::sleep_for(10ms); this->occupied = true; - if ( ! this->init_GPRS()) + if (this->send_command_read("AT+CMGF=1") != "OK") { + this->logger->log("Error getting location on 'AT+CMGD=1' response."); this->occupied = false; return false; } - // TODO - // OLD: - // uint16_t responseLength = SerialSendRead("AT+CIPGSMLOC=1,1"); - // serialin[responseLength+1] = (char)0x0; - if (this->tear_down_GPRS()) + + if (this->send_command_read("AT+CGATT=1") != "OK") + { + this->logger->log("Error getting location on 'AT+CGATT=1' response."); + if (this->send_command_read("AT+SAPBR=0,1") != "OK") + this->logger->log("Error turning GPRS down."); + else + this->logger->log("GPRS off."); + + this->occupied = false; + return false; + } + + if (this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") != "OK") + { + this->logger->log("Error getting location on 'AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"' response."); + if (this->send_command_read("AT+SAPBR=0,1") != "OK") + this->logger->log("Error turning GPRS down."); + else + this->logger->log("GPRS off."); + + this->occupied = false; + return false; + } + + if (this->send_command_read("AT+SAPBR=3,1,\"APN\",\""+string(GSM_LOC_SERV)+"\"") != "OK") { + this->logger->log("Error getting location on 'AT+SAPBR=3,1,\"APN\",\""+string(GSM_LOC_SERV)+"\"' response."); + if (this->send_command_read("AT+SAPBR=0,1") != "OK") + this->logger->log("Error turning GPRS down."); + else + this->logger->log("GPRS off."); + this->occupied = false; return false; } + + if (this->send_command_read("AT+SAPBR=1,1") != "OK") + { + this->logger->log("Error getting location on 'AT+SAPBR=1,1' response."); + if (this->send_command_read("AT+SAPBR=0,1") != "OK") + this->logger->log("Error turning GPRS down."); + else + this->logger->log("GPRS off."); + + this->occupied = false; + return false; + } + + string response = this->send_command_read("AT+CIPGSMLOC=1,1"); + if (response == "ERROR" || this->serial->read_line() != "OK") + { + this->logger->log("Error getting location on 'AT+CIPGSMLOC=1,1' response."); + if (this->send_command_read("AT+SAPBR=0,1") != "OK") + this->logger->log("Error turning GPRS down."); + else + this->logger->log("GPRS off."); + + this->occupied = false; + return false; + } + + if (this->send_command_read("AT+SAPBR=0,1") != "OK") + this->logger->log("Error turning GPRS down."); + else + this->logger->log("GPRS off."); + this->occupied = false; - return false; + + stringstream ss(response); + string data; + vector s_data; + + // We put all fields in a vector + while(getline(ss, data, ',')) s_data.push_back(data); + + latitude = stod(s_data[2]); + longitude = stod(s_data[1]); + + return true; } bool GSM::get_status() const From 5c65ba7910434f31bc5ddb56923c67946107d31b Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 2 Sep 2015 23:59:53 +0200 Subject: [PATCH 130/169] Better README. Fixes #46 --- README | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 1 deletion(-) diff --git a/README b/README index 4b2ff08..5cc970d 100644 --- a/README +++ b/README @@ -2,4 +2,84 @@ [![Build Status](https://travis-ci.org/OpenStratos/server.svg?branch=develop)](https://travis-ci.org/OpenStratos/server) -Server implemented in C++14. It will be in charge of the management of the balloon. +Server implemented in C++14. It will be in charge of the management of the balloon. It will +communicate via SMS to the provided phone. It will initialize all needed components, track and log +position and software messages, detect launch, burst and landing and send the landing position via +SMS. + +## Requirements ## + +The software needs a working instalation of WiringPi and a RaspiCam for the tests. It will perform +some basic tests if no Raspberry Pi is being used. It works with Adafruit Fona module, even though +it should work with other GSM modules. It also uses the Adafruit Ultimate GPS module. The following +software is needed to compile OpenStratos (apart from the WiringPi library): + +* build-essential +* g++ +* m4 +* automake +* autoconf + +## Compiling ## + +For compilation, a *build.sh* script is provided, that should be run as is. It will compile the +tests of OpenStratos and run them. After that, the main program can be compiled using ```make```. +Optional configuration arguments can be passed. The first optional configuration argument is the +*NO_SMS* flag. This prevents actual SMSs being sent, even if they are simulated. This way no charges +will be applied. For using this argument the directory should be cleaned with ```make clean``` and +then pass the *NO_SMS* flag to the configure script: + +``` +./configure CPPFLAGS="-DNO_SMS" +``` + +After that the usual ```make``` will compile the software. Note that the test do not send SMSs. The software itself comes with two built-in simulation modes: + +### Normal Simulation ### + +In this mode, a simple simulation is made, with a length of about 45 minutes. It will run through +all the main stages of the program. For using this mode the directory should be cleaned with +```make clean``` and then pass the *SIM* flag to the configure script: + +``` +./configure CPPFLAGS="-DSIM" +``` + +It can be combined with the *NO_SMS* flag: + +``` +./configure CPPFLAGS="-DSIM -DNO_SMS" +``` + +After that, the software can be compiled using ```make```. + +### Realistic Simulation ### + +In this mode, a complete realistic simulation is made, that will last for about 5 hours. It will +realistically simulate the times in a 35 km height balloon. It will be similar to the normal +simulation, the only change will be in the timing. For using this mode the directory should be +cleaned with ```make clean``` and then pass the *REAL_SIM* flag to the configure script: + +``` +./configure CPPFLAGS="-DREAL_SIM" +``` + +It can be combined with the *NO_SMS* flag: + +``` +./configure CPPFLAGS="-DREAL_SIM -DNO_SMS" +``` + +After that, the software can be compiled using ```make```. The result of combining the two +simulation flags is undetermined. They should not be combined. + +## License ## + +This software is licensed under the GNU General Public License version 3. You can use, copy, modify +the software as long as all the derivative work is published under the same license. A copy of the license can be found in the *[COPYING](COPYING)* file of the repository where a detailed explanation of the +copying rights can be found. + +## Contributing guidelines ## + +The guidelines to contribute to this repository can be found in the +[contribution guidelines](contributing.md) file of the repository. From 5109d546efb313003cc51f017913e9b875c9e85f Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 4 Sep 2015 19:04:59 +0200 Subject: [PATCH 131/169] New system thread. Closes #35 and #48. --- constants.h | 2 +- openstratos.cc | 116 ++++++++++++++++++++++++++++++++++++++----------- openstratos.h | 4 ++ 3 files changed, 95 insertions(+), 27 deletions(-) diff --git a/constants.h b/constants.h index 201ebee..1a7315e 100644 --- a/constants.h +++ b/constants.h @@ -3,7 +3,7 @@ #define DEBUG true - #define FLIGHT_LENGTH 4.55 // Hours + #define FLIGHT_LENGTH 4.222 // Hours #define BAT_GSM_MAX 4.2 #define BAT_GSM_MIN 3.7 diff --git a/openstratos.cc b/openstratos.cc index 4a1ef02..8077dc9 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -50,6 +50,7 @@ void os::main_logic() check_or_create("data/logs"); check_or_create("data/logs/main"); + check_or_create("data/logs/system"); check_or_create("data/logs/camera"); check_or_create("data/logs/GPS"); check_or_create("data/logs/GSM"); @@ -66,6 +67,10 @@ void os::main_logic() cout << "[OpenStratos] Logger started." << endl; #endif + logger.log("Starting system thread..."); + thread system_thread(&system_thread_fn, ref(state)); + logger.log("System thread started."); + initialize(&logger, now); logger.log("Starting battery thread..."); @@ -84,6 +89,7 @@ void os::main_logic() logger.log("Joining threads..."); picture_thread.join(); battery_thread.join(); + system_thread.join(); logger.log("Threads joined."); shut_down(&logger); @@ -507,7 +513,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2s); } #else - this_thread::sleep_for(260s); + this_thread::sleep_for(225s); #endif logger->log("1.5 km mark."); logger->log("Trying to send \"going up\" SMS..."); @@ -532,7 +538,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("5 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1400s); + this_thread::sleep_for(1225s); logger->log("5 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -548,7 +554,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("10 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2008s); + this_thread::sleep_for(1750s); logger->log("10 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -564,7 +570,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("15 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2008s); + this_thread::sleep_for(1725s); logger->log("15 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -580,7 +586,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("20 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2008s); + this_thread::sleep_for(1750s); logger->log("20 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -596,7 +602,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("25 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2008s); + this_thread::sleep_for(1750s); logger->log("25 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -612,7 +618,7 @@ void os::go_up(Logger* logger) this_thread::sleep_for(2min); logger->log("30 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2008s); + this_thread::sleep_for(1725s); logger->log("30 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -626,10 +632,8 @@ void os::go_up(Logger* logger) #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); - logger->log("35 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(2008s); - logger->log("35 km mark passed going up."); + this_thread::sleep_for(1650s); #else while ( ! (bursted = has_bursted(maximum_altitude)) && (current_altitude = GPS::get_instance().get_altitude()) < 35000) @@ -651,7 +655,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("25 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(5min); + this_thread::sleep_for(325s); logger->log("25 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 25000) @@ -664,7 +668,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("15 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(650s); + this_thread::sleep_for(700s); logger->log("15 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 15000) @@ -677,7 +681,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(2min); logger->log("5 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1400s); + this_thread::sleep_for(1450s); logger->log("5 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 5000) @@ -690,7 +694,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("2.5 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(500s); + this_thread::sleep_for(525s); logger->log("2.5 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 2500) @@ -736,7 +740,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("1.5 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(175s); + this_thread::sleep_for(225s); logger->log("1.5 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 1500 && ! (landed = has_landed())); @@ -777,7 +781,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("500 m mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(225s); + this_thread::sleep_for(175s); logger->log("500 m mark passed going down."); #else while (GPS::get_instance().get_altitude() > 500 && ! (landed = has_landed())); @@ -889,6 +893,66 @@ void os::shut_down(Logger* logger) reboot(RB_POWER_OFF); } +void os::system_thread_fn(State& state) +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + Logger cpu_logger("data/logs/system/CPU."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "CPU"); + + Logger ram_logger("data/logs/system/RAM."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "RAM"); + + Logger temp_logger("data/logs/system/Temp."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "Temp"); + + FILE *gpu_temp_process, *cpu_command_process; + char gpu_response[11]; + char cpu_command[100]; + struct sysinfo* info; + + while (state != SHUT_DOWN) + { + ifstream cpu_temp_file("/sys/class/thermal/thermal_zone0/temp"); + string cpu_temp_str((istreambuf_iterator(cpu_temp_file)), + istreambuf_iterator()); + cpu_temp_file.close(); + + gpu_temp_process = popen("/opt/vc/bin/vcgencmd measure_temp", "r"); + fgets(gpu_response, 11, gpu_temp_process); + pclose(gpu_temp_process); + + temp_logger.log("CPU: "+to_string(stoi(cpu_temp_str)/1000.0)+" GPU: "+ + string(gpu_response).substr(5, 4)); + + cpu_command_process = popen("grep 'cpu ' /proc/stat", "r"); + fgets(cpu_command, 100, cpu_command_process); + pclose(cpu_command_process); + + const string cpu_command_str = string(cpu_command); + stringstream ss(cpu_command_str); + string data; + vector s_data; + + // We put all fields in a vector + while(getline(ss, data, ' ')) s_data.push_back(data); + + // Note that s_data[1] is "" + cpu_logger.log(to_string((stof(s_data[2])+stof(s_data[4]))/ + (stof(s_data[2])+stof(s_data[4])+stof(s_data[5])))); + + sysinfo(info); + ram_logger.log(to_string(info->freeram/info->totalram)); + + this_thread::sleep_for(30s); + } +} + void os::picture_thread_fn(State& state) { struct timeval timer; @@ -1051,18 +1115,18 @@ State os::set_state(State new_state) State os::get_last_state() { ifstream state_file(STATE_FILE); - string str_state((istreambuf_iterator(state_file)), - istreambuf_iterator()); + string state_str((istreambuf_iterator(state_file)), + istreambuf_iterator()); state_file.close(); - if (str_state == "INITIALIZING") return INITIALIZING; - if (str_state == "ACQUIRING_FIX") return ACQUIRING_FIX; - if (str_state == "FIX_ACQUIRED") return FIX_ACQUIRED; - if (str_state == "WAITING_LAUNCH") return WAITING_LAUNCH; - if (str_state == "GOING_UP") return GOING_UP; - if (str_state == "GOING_DOWN") return GOING_DOWN; - if (str_state == "LANDED") return LANDED; - if (str_state == "SHUT_DOWN") return SHUT_DOWN; + if (state_str == "INITIALIZING") return INITIALIZING; + if (state_str == "ACQUIRING_FIX") return ACQUIRING_FIX; + if (state_str == "FIX_ACQUIRED") return FIX_ACQUIRED; + if (state_str == "WAITING_LAUNCH") return WAITING_LAUNCH; + if (state_str == "GOING_UP") return GOING_UP; + if (state_str == "GOING_DOWN") return GOING_DOWN; + if (state_str == "LANDED") return LANDED; + if (state_str == "SHUT_DOWN") return SHUT_DOWN; return SAFE_MODE; } diff --git a/openstratos.h b/openstratos.h index 5a292b4..7b73fe2 100644 --- a/openstratos.h +++ b/openstratos.h @@ -6,6 +6,8 @@ #include #include +#include +#include #include #include #include @@ -15,6 +17,7 @@ #include #include #include +#include #include @@ -61,6 +64,7 @@ namespace os inline bool has_bursted(double maximum_altitude); inline bool has_landed(); + void system_thread_fn(State& state); void picture_thread_fn(State& state); void battery_thread_fn(State& state); From b9c3ded267d651b12017d1359179994f95843899 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 14:54:10 +0200 Subject: [PATCH 132/169] Should implement #49. Nevertheless, I'm still getting some weird warnings on compilation :| --- Makefile.am | 3 +- camera/Camera.cc | 27 +++++ camera/Camera.h | 1 + openstratos.cc | 271 ----------------------------------------------- openstratos.h | 36 +------ 5 files changed, 31 insertions(+), 307 deletions(-) diff --git a/Makefile.am b/Makefile.am index eda7769..3be2e86 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,6 +1,5 @@ bin_PROGRAMS = openstratos -openstratos_SOURCES = openstratos.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc gsm/GSM.cc -openstratos_LDADD = -lwiringPi +openstratos_SOURCES = openstratos.cc utils.cc threads.cc camera/Camera.cc gps/GPS.cc serial/Serial.cc logger/Logger.cc gsm/GSM.cc openstratos_CPPFLAGS = -std=c++14 EXTRA_PROGRAMS = utesting diff --git a/camera/Camera.cc b/camera/Camera.cc index 06ce96c..ca6e85d 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -13,6 +13,7 @@ #include "config.h" #include "constants.h" +#include "gps/GPS.h" using namespace os; using namespace std; @@ -208,3 +209,29 @@ int os::get_file_count(const string& path) return i-2; } + +const string os::generate_exif_data() +{ + string exif; + while (GPS::get_instance().get_PDOP() > 5) + { + this_thread::sleep_for(1s); + } + double gps_lat = GPS::get_instance().get_latitude(); + double gps_lon = GPS::get_instance().get_longitude(); + double gps_alt = GPS::get_instance().get_altitude(); + uint_fast8_t gps_sat = GPS::get_instance().get_satellites(); + float gps_pdop = GPS::get_instance().get_PDOP(); + euc_vec gps_velocity = GPS::get_instance().get_velocity(); + + exif += "GPSLatitudeRef="+to_string(gps_lat > 0 ? 'N' : 'S'); + exif += " GPSLatitude="+to_string(abs((int) gps_lat*1000000))+"/1000000,0/1,0/1"; + exif += " GPSLongitudeRef="+to_string(gps_lon > 0 ? 'E' : 'W'); + exif += " GPSLongitude="+to_string(abs((int) gps_lon*1000000))+"/1000000,0/1,0/1"; + exif += " GPSAltitudeRef=0 GPSAltitude="+to_string(gps_alt); + exif += " GPSSatellites="+to_string(gps_sat); + exif += " GPSDOP="+to_string(gps_pdop); + exif += " GPSSpeedRef=K GPSSpeed="+to_string(gps_velocity.speed*3.6); + exif += " GPSTrackRef=T GPSTrack="+to_string(gps_velocity.course); + exif += " GPSDifferential=0"; +} diff --git a/camera/Camera.h b/camera/Camera.h index e2c00c2..b4cdb29 100644 --- a/camera/Camera.h +++ b/camera/Camera.h @@ -32,6 +32,7 @@ namespace os { }; int get_file_count(const string& path); + const string generate_exif_data(); } #endif // CAMERA_CAMERA_H_ diff --git a/openstratos.cc b/openstratos.cc index 8077dc9..829c626 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -892,274 +892,3 @@ void os::shut_down(Logger* logger) sync(); reboot(RB_POWER_OFF); } - -void os::system_thread_fn(State& state) -{ - struct timeval timer; - gettimeofday(&timer, NULL); - struct tm * now = gmtime(&timer.tv_sec); - - Logger cpu_logger("data/logs/system/CPU."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "CPU"); - - Logger ram_logger("data/logs/system/RAM."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "RAM"); - - Logger temp_logger("data/logs/system/Temp."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "Temp"); - - FILE *gpu_temp_process, *cpu_command_process; - char gpu_response[11]; - char cpu_command[100]; - struct sysinfo* info; - - while (state != SHUT_DOWN) - { - ifstream cpu_temp_file("/sys/class/thermal/thermal_zone0/temp"); - string cpu_temp_str((istreambuf_iterator(cpu_temp_file)), - istreambuf_iterator()); - cpu_temp_file.close(); - - gpu_temp_process = popen("/opt/vc/bin/vcgencmd measure_temp", "r"); - fgets(gpu_response, 11, gpu_temp_process); - pclose(gpu_temp_process); - - temp_logger.log("CPU: "+to_string(stoi(cpu_temp_str)/1000.0)+" GPU: "+ - string(gpu_response).substr(5, 4)); - - cpu_command_process = popen("grep 'cpu ' /proc/stat", "r"); - fgets(cpu_command, 100, cpu_command_process); - pclose(cpu_command_process); - - const string cpu_command_str = string(cpu_command); - stringstream ss(cpu_command_str); - string data; - vector s_data; - - // We put all fields in a vector - while(getline(ss, data, ' ')) s_data.push_back(data); - - // Note that s_data[1] is "" - cpu_logger.log(to_string((stof(s_data[2])+stof(s_data[4]))/ - (stof(s_data[2])+stof(s_data[4])+stof(s_data[5])))); - - sysinfo(info); - ram_logger.log(to_string(info->freeram/info->totalram)); - - this_thread::sleep_for(30s); - } -} - -void os::picture_thread_fn(State& state) -{ - struct timeval timer; - gettimeofday(&timer, NULL); - struct tm * now = gmtime(&timer.tv_sec); - - Logger logger("data/logs/camera/Pictures."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "Pictures"); - - logger.log("Waiting for launch..."); - - while (state != GOING_UP) - { - this_thread::sleep_for(10s); - } - - logger.log("Launched, waiting 2 minutes for first picture..."); - this_thread::sleep_for(2min); - - while (state == GOING_UP) - { - logger.log("Taking picture..."); - - if ( ! Camera::get_instance().take_picture(generate_exif_data())) - { - logger.log("Error taking picture. Trying again in 30 seconds..."); - } - else - { - logger.log("Picture taken correctly. Next picture in 30 seconds..."); - } - - this_thread::sleep_for(30s); - logger.log("Taking picture..."); - - if ( ! Camera::get_instance().take_picture(generate_exif_data())) - { - logger.log("Error taking picture. Next picture in 4 minutes..."); - } - else - { - logger.log("Picture taken correctly. Next picture in 4 minutes..."); - } - - this_thread::sleep_for(4min); - } - - logger.log("Going down, no more pictures are being taken, picture thread is closing."); -} - -void os::battery_thread_fn(State& state) -{ - struct timeval timer; - gettimeofday(&timer, NULL); - struct tm * now = gmtime(&timer.tv_sec); - - Logger logger("data/logs/GSM/Battery."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ - to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ - to_string(now->tm_sec) +".log", "Battery"); - - double main_battery, gsm_battery; - - while (state != SHUT_DOWN) - { - if (GSM::get_instance().get_status()) - { - GSM::get_instance().get_battery_status(main_battery, gsm_battery); - logger.log("Main: "+ to_string(main_battery)); - logger.log("GSM: "+ to_string(gsm_battery)); - } - - this_thread::sleep_for(3min); - } -} - -void os::check_or_create(const string& path, Logger* logger) -{ - if ( ! file_exists(path)) - { - if (logger != NULL) - logger->log("No '"+path+"' directory, creating..."); - #if DEBUG - else - cout << "[OpenStratos] No '"+path+"' directory, creating..." << endl; - #endif - if (mkdir(path.c_str(), 0755) != 0) - { - if (logger != NULL) - logger->log("Error creating '"+path+"' directory."); - #if DEBUG - else - cout << "[OpenStratos] Error creating '"+path+"' directory." << endl; - #endif - - sync(); - reboot(RB_POWER_OFF); - } - else - { - if (logger != NULL) - logger->log("'"+path+"' directory created."); - #if DEBUG - else - cout << "[OpenStratos] '"+path+"' directory created." << endl; - #endif - } - } -} - -inline bool os::file_exists(const string& name) -{ - struct stat buffer; - return stat(name.c_str(), &buffer) == 0; -} - -inline float os::get_available_disk_space() -{ - struct statvfs fs; - statvfs("data", &fs); - - return ((float) fs.f_bsize)*fs.f_bavail; -} - -const string os::generate_exif_data() -{ - string exif; - while (GPS::get_instance().get_PDOP() > 5) - { - this_thread::sleep_for(1s); - } - double gps_lat = GPS::get_instance().get_latitude(); - double gps_lon = GPS::get_instance().get_longitude(); - double gps_alt = GPS::get_instance().get_altitude(); - uint_fast8_t gps_sat = GPS::get_instance().get_satellites(); - float gps_pdop = GPS::get_instance().get_PDOP(); - euc_vec gps_velocity = GPS::get_instance().get_velocity(); - - exif += "GPSLatitudeRef="+to_string(gps_lat > 0 ? 'N' : 'S'); - exif += " GPSLatitude="+to_string(abs((int) gps_lat*1000000))+"/1000000,0/1,0/1"; - exif += " GPSLongitudeRef="+to_string(gps_lon > 0 ? 'E' : 'W'); - exif += " GPSLongitude="+to_string(abs((int) gps_lon*1000000))+"/1000000,0/1,0/1"; - exif += " GPSAltitudeRef=0 GPSAltitude="+to_string(gps_alt); - exif += " GPSSatellites="+to_string(gps_sat); - exif += " GPSDOP="+to_string(gps_pdop); - exif += " GPSSpeedRef=K GPSSpeed="+to_string(gps_velocity.speed*3.6); - exif += " GPSTrackRef=T GPSTrack="+to_string(gps_velocity.course); - exif += " GPSDifferential=0"; -} - -State os::set_state(State new_state) -{ - ofstream state_file(STATE_FILE); - state_file << state_to_string(new_state); - state_file.close(); - - return new_state; -} - -State os::get_last_state() -{ - ifstream state_file(STATE_FILE); - string state_str((istreambuf_iterator(state_file)), - istreambuf_iterator()); - state_file.close(); - - if (state_str == "INITIALIZING") return INITIALIZING; - if (state_str == "ACQUIRING_FIX") return ACQUIRING_FIX; - if (state_str == "FIX_ACQUIRED") return FIX_ACQUIRED; - if (state_str == "WAITING_LAUNCH") return WAITING_LAUNCH; - if (state_str == "GOING_UP") return GOING_UP; - if (state_str == "GOING_DOWN") return GOING_DOWN; - if (state_str == "LANDED") return LANDED; - if (state_str == "SHUT_DOWN") return SHUT_DOWN; - - return SAFE_MODE; -} - -const string os::state_to_string(State state) -{ - switch (state) - { - case INITIALIZING: - return "INITIALIZING"; - break; - case ACQUIRING_FIX: - return "ACQUIRING_FIX"; - break; - case FIX_ACQUIRED: - return "FIX_ACQUIRED"; - break; - case WAITING_LAUNCH: - return "WAITING_LAUNCH"; - break; - case GOING_UP: - return "GOING_UP"; - break; - case GOING_DOWN: - return "GOING_DOWN"; - break; - case LANDED: - return "LANDED"; - break; - case SHUT_DOWN: - return "SHUT_DOWN"; - break; - case SAFE_MODE: - return "SAFE_MODE"; - } -} diff --git a/openstratos.h b/openstratos.h index 7b73fe2..186aeb8 100644 --- a/openstratos.h +++ b/openstratos.h @@ -1,28 +1,21 @@ #ifndef OPENSTRATOS_H_ #define OPENSTRATOS_H_ -#include #include #include -#include -#include -#include -#include #include -#include -#include -#include #include #include #include -#include #include #include "config.h" #include "constants.h" +#include "utils.h" +#include "threads.h" #include "logger/Logger.h" #include "gps/GPS.h" #include "camera/Camera.h" @@ -34,18 +27,6 @@ namespace os { - enum State { - INITIALIZING, - ACQUIRING_FIX, - FIX_ACQUIRED, - WAITING_LAUNCH, - GOING_UP, - GOING_DOWN, - LANDED, - SHUT_DOWN, - SAFE_MODE, - }; - void main_logic(); void safe_mode(); void main_while(Logger* logger, State* state); @@ -63,19 +44,6 @@ namespace os inline bool has_launched(double launch_altitude); inline bool has_bursted(double maximum_altitude); inline bool has_landed(); - - void system_thread_fn(State& state); - void picture_thread_fn(State& state); - void battery_thread_fn(State& state); - - void check_or_create(const string& path, Logger* logger = NULL); - inline bool file_exists(const string& name); - inline float get_available_disk_space(); - const string generate_exif_data(); - - State set_state(State new_state); - State get_last_state(); - const string state_to_string(State state); } using namespace std; From 6ea3ab20716182d29bc83cee1ccec0e289c00f53 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 14:55:42 +0200 Subject: [PATCH 133/169] Some files wew missing --- threads.cc | 154 +++++++++++++++++++++++++++++++++++++++++++++++++++++ threads.h | 12 +++++ utils.cc | 126 +++++++++++++++++++++++++++++++++++++++++++ utils.h | 30 +++++++++++ 4 files changed, 322 insertions(+) create mode 100644 threads.cc create mode 100644 threads.h create mode 100644 utils.cc create mode 100644 utils.h diff --git a/threads.cc b/threads.cc new file mode 100644 index 0000000..873c017 --- /dev/null +++ b/threads.cc @@ -0,0 +1,154 @@ +#include "threads.h" + +#include + +#include +#include +#include +#include + +#include +#include + +#include "logger/Logger.h" +#include "camera/Camera.h" +#include "gsm/GSM.h" + +using namespace std; +using namespace os; + +void os::system_thread_fn(State& state) +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + Logger cpu_logger("data/logs/system/CPU."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "CPU"); + + Logger ram_logger("data/logs/system/RAM."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "RAM"); + + Logger temp_logger("data/logs/system/Temp."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "Temp"); + + FILE *gpu_temp_process, *cpu_command_process; + char gpu_response[11]; + char cpu_command[100]; + struct sysinfo* info; + + while (state != SHUT_DOWN) + { + ifstream cpu_temp_file("/sys/class/thermal/thermal_zone0/temp"); + string cpu_temp_str((istreambuf_iterator(cpu_temp_file)), + istreambuf_iterator()); + cpu_temp_file.close(); + + gpu_temp_process = popen("/opt/vc/bin/vcgencmd measure_temp", "r"); + fgets(gpu_response, 11, gpu_temp_process); + pclose(gpu_temp_process); + + temp_logger.log("CPU: "+to_string(stoi(cpu_temp_str)/1000.0)+" GPU: "+ + string(gpu_response).substr(5, 4)); + + cpu_command_process = popen("grep 'cpu ' /proc/stat", "r"); + fgets(cpu_command, 100, cpu_command_process); + pclose(cpu_command_process); + + const string cpu_command_str = string(cpu_command); + stringstream ss(cpu_command_str); + string data; + vector s_data; + + // We put all fields in a vector + while(getline(ss, data, ' ')) s_data.push_back(data); + + // Note that s_data[1] is "" + cpu_logger.log(to_string((stof(s_data[2])+stof(s_data[4]))/ + (stof(s_data[2])+stof(s_data[4])+stof(s_data[5])))); + + sysinfo(info); + ram_logger.log(to_string(info->freeram/info->totalram)); + + this_thread::sleep_for(30s); + } +} + +void os::picture_thread_fn(State& state) +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + Logger logger("data/logs/camera/Pictures."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "Pictures"); + + logger.log("Waiting for launch..."); + + while (state != GOING_UP) + { + this_thread::sleep_for(10s); + } + + logger.log("Launched, waiting 2 minutes for first picture..."); + this_thread::sleep_for(2min); + + while (state == GOING_UP) + { + logger.log("Taking picture..."); + + if ( ! Camera::get_instance().take_picture(generate_exif_data())) + { + logger.log("Error taking picture. Trying again in 30 seconds..."); + } + else + { + logger.log("Picture taken correctly. Next picture in 30 seconds..."); + } + + this_thread::sleep_for(30s); + logger.log("Taking picture..."); + + if ( ! Camera::get_instance().take_picture(generate_exif_data())) + { + logger.log("Error taking picture. Next picture in 4 minutes..."); + } + else + { + logger.log("Picture taken correctly. Next picture in 4 minutes..."); + } + + this_thread::sleep_for(4min); + } + + logger.log("Going down, no more pictures are being taken, picture thread is closing."); +} + +void os::battery_thread_fn(State& state) +{ + struct timeval timer; + gettimeofday(&timer, NULL); + struct tm * now = gmtime(&timer.tv_sec); + + Logger logger("data/logs/GSM/Battery."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ + to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ + to_string(now->tm_sec) +".log", "Battery"); + + double main_battery, gsm_battery; + + while (state != SHUT_DOWN) + { + if (GSM::get_instance().get_status()) + { + GSM::get_instance().get_battery_status(main_battery, gsm_battery); + logger.log("Main: "+ to_string(main_battery)); + logger.log("GSM: "+ to_string(gsm_battery)); + } + + this_thread::sleep_for(3min); + } +} diff --git a/threads.h b/threads.h new file mode 100644 index 0000000..b1136ba --- /dev/null +++ b/threads.h @@ -0,0 +1,12 @@ +#ifndef THREADS_H_ +#define THREADS_H_ + +#include "utils.h" + +namespace os { + void system_thread_fn(State& state); + void picture_thread_fn(State& state); + void battery_thread_fn(State& state); +} + +#endif // THREADS_H_ diff --git a/utils.cc b/utils.cc new file mode 100644 index 0000000..f667364 --- /dev/null +++ b/utils.cc @@ -0,0 +1,126 @@ +#include "utils.h" + +#include + +#include +#include +#include +#include + +#include "constants.h" + +#ifdef DEBUG + #include +#endif + +using namespace std; +using namespace os; + +void os::check_or_create(const string& path, Logger* logger) +{ + if ( ! file_exists(path)) + { + if (logger != NULL) + logger->log("No '"+path+"' directory, creating..."); + #if DEBUG + else + cout << "[OpenStratos] No '"+path+"' directory, creating..." << endl; + #endif + if (mkdir(path.c_str(), 0755) != 0) + { + if (logger != NULL) + logger->log("Error creating '"+path+"' directory."); + #ifdef DEBUG + else + cout << "[OpenStratos] Error creating '"+path+"' directory." << endl; + #endif + + sync(); + reboot(RB_POWER_OFF); + } + else + { + if (logger != NULL) + logger->log("'"+path+"' directory created."); + #if DEBUG + else + cout << "[OpenStratos] '"+path+"' directory created." << endl; + #endif + } + } +} + +inline bool os::file_exists(const string& name) +{ + struct stat buffer; + return stat(name.c_str(), &buffer) == 0; +} + +inline float os::get_available_disk_space() +{ + struct statvfs fs; + statvfs("data", &fs); + + return ((float) fs.f_bsize)*fs.f_bavail; +} + +State os::set_state(State new_state) +{ + ofstream state_file(STATE_FILE); + state_file << state_to_string(new_state); + state_file.close(); + + return new_state; +} + +State os::get_last_state() +{ + ifstream state_file(STATE_FILE); + string state_str((istreambuf_iterator(state_file)), + istreambuf_iterator()); + state_file.close(); + + if (state_str == "INITIALIZING") return INITIALIZING; + if (state_str == "ACQUIRING_FIX") return ACQUIRING_FIX; + if (state_str == "FIX_ACQUIRED") return FIX_ACQUIRED; + if (state_str == "WAITING_LAUNCH") return WAITING_LAUNCH; + if (state_str == "GOING_UP") return GOING_UP; + if (state_str == "GOING_DOWN") return GOING_DOWN; + if (state_str == "LANDED") return LANDED; + if (state_str == "SHUT_DOWN") return SHUT_DOWN; + + return SAFE_MODE; +} + +const string os::state_to_string(State state) +{ + switch (state) + { + case INITIALIZING: + return "INITIALIZING"; + break; + case ACQUIRING_FIX: + return "ACQUIRING_FIX"; + break; + case FIX_ACQUIRED: + return "FIX_ACQUIRED"; + break; + case WAITING_LAUNCH: + return "WAITING_LAUNCH"; + break; + case GOING_UP: + return "GOING_UP"; + break; + case GOING_DOWN: + return "GOING_DOWN"; + break; + case LANDED: + return "LANDED"; + break; + case SHUT_DOWN: + return "SHUT_DOWN"; + break; + case SAFE_MODE: + return "SAFE_MODE"; + } +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..71b6f3c --- /dev/null +++ b/utils.h @@ -0,0 +1,30 @@ +#ifndef UTILS_H_ +#define UTILS_H_ + +#include + +#include "logger/Logger.h" + +namespace os { + enum State { + INITIALIZING, + ACQUIRING_FIX, + FIX_ACQUIRED, + WAITING_LAUNCH, + GOING_UP, + GOING_DOWN, + LANDED, + SHUT_DOWN, + SAFE_MODE, + }; + + void check_or_create(const string& path, Logger* logger = NULL); + inline bool file_exists(const string& name); + inline float get_available_disk_space(); + + State set_state(State new_state); + State get_last_state(); + const string state_to_string(State state); +} + +#endif // UTILS_H_ From 6d47a36b32917242b14599f1a821c3809b206c46 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 15:10:42 +0200 Subject: [PATCH 134/169] Fixed small compiling warning --- utils.cc | 16 ---------------- utils.h | 19 +++++++++++++++++-- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/utils.cc b/utils.cc index f667364..585a690 100644 --- a/utils.cc +++ b/utils.cc @@ -4,8 +4,6 @@ #include #include -#include -#include #include "constants.h" @@ -50,20 +48,6 @@ void os::check_or_create(const string& path, Logger* logger) } } -inline bool os::file_exists(const string& name) -{ - struct stat buffer; - return stat(name.c_str(), &buffer) == 0; -} - -inline float os::get_available_disk_space() -{ - struct statvfs fs; - statvfs("data", &fs); - - return ((float) fs.f_bsize)*fs.f_bavail; -} - State os::set_state(State new_state) { ofstream state_file(STATE_FILE); diff --git a/utils.h b/utils.h index 71b6f3c..ced1217 100644 --- a/utils.h +++ b/utils.h @@ -3,6 +3,9 @@ #include +#include +#include + #include "logger/Logger.h" namespace os { @@ -19,8 +22,20 @@ namespace os { }; void check_or_create(const string& path, Logger* logger = NULL); - inline bool file_exists(const string& name); - inline float get_available_disk_space(); + + inline bool file_exists(const string& name) + { + struct stat buffer; + return stat(name.c_str(), &buffer) == 0; + } + + inline float get_available_disk_space() + { + struct statvfs fs; + statvfs("data", &fs); + + return ((float) fs.f_bsize)*fs.f_bavail; + } State set_state(State new_state); State get_last_state(); From 66234ba0d570a0c2a00bd8b085047e65613f64c9 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 15:59:52 +0200 Subject: [PATCH 135/169] Safe mode finished. This finally implements #40. It also has a better debug mode support, explained in the readme. --- README | 20 +++++++++++ constants.h | 2 -- openstratos.cc | 93 ++++++++++++++++++++++++++++++++++-------------- openstratos.h | 2 +- serial/Serial.cc | 20 +++++------ serial/Serial.h | 4 +-- utils.cc | 11 +++--- utils.h | 15 ++++++++ 8 files changed, 120 insertions(+), 47 deletions(-) diff --git a/README b/README index 5cc970d..5b02f53 100644 --- a/README +++ b/README @@ -73,6 +73,26 @@ It can be combined with the *NO_SMS* flag: After that, the software can be compiled using ```make```. The result of combining the two simulation flags is undetermined. They should not be combined. +### Debug Mode ### + +The software has a small debug mode, that prints from *stdio* some logs that occur before the log +file is created. It also enables serial logging, that will log everything that happens in the +serial. This has a moderate overhead and should not be used in production. GSM and GPS loggers log everythong they send and receive. This is only needed to debug if something goes wrong with the +serial. For using this mode the directory should be cleaned with ```make clean``` and then pass the +*DEBUG* flag to the configure script: + +``` +./configure CPPFLAGS="-DDEBUG" +``` + +It can be combined with the *NO_SMS* flag or/and one of the simulation flags: + +``` +./configure CPPFLAGS="-DREAL_SIM -DNO_SMS -DDEBUG" +./configure CPPFLAGS="-DSIM -DDEBUG" +./configure CPPFLAGS="-DNO_SMS -DDEBUG" +``` + ## License ## This software is licensed under the GNU General Public License version 3. You can use, copy, modify diff --git a/constants.h b/constants.h index 1a7315e..df052e2 100644 --- a/constants.h +++ b/constants.h @@ -1,8 +1,6 @@ #ifndef CONSTANTS_H_ #define CONSTANTS_H_ - #define DEBUG true - #define FLIGHT_LENGTH 4.222 // Hours #define BAT_GSM_MAX 4.2 diff --git a/openstratos.cc b/openstratos.cc index 829c626..24689f1 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -2,7 +2,7 @@ int main(void) { - #if DEBUG + #ifdef DEBUG #ifdef SIM cout << "[OpenStratos] Simulation." << endl; #endif @@ -16,14 +16,14 @@ int main(void) if ( ! file_exists(STATE_FILE)) { - #if DEBUG + #ifdef DEBUG cout << "[OpenStratos] No state file. Starting main logic..." << endl; #endif main_logic(); } else { - #if DEBUG + #ifdef DEBUG cout << "[OpenStratos] State file found. Starting safe mode..." << endl; #endif safe_mode(); @@ -38,7 +38,7 @@ void os::main_logic() gettimeofday(&timer, NULL); struct tm* now = gmtime(&timer.tv_sec); - #if DEBUG + #ifdef DEBUG cout << "[OpenStratos] Current time: " << setfill('0') << setw(2) << now->tm_hour << ":" << setfill('0') << setw(2) << now->tm_min << ":" << setfill('0') << setw(2) << now->tm_sec << " UTC of " << setfill('0') << setw(2) << now->tm_mon << "/" << @@ -55,7 +55,7 @@ void os::main_logic() check_or_create("data/logs/GPS"); check_or_create("data/logs/GSM"); - #if DEBUG + #ifdef DEBUG cout << "[OpenStratos] Starting logger..." << endl; #endif @@ -63,7 +63,7 @@ void os::main_logic() to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "OpenStratos"); - #if DEBUG + #ifdef DEBUG cout << "[OpenStratos] Logger started." << endl; #endif @@ -101,6 +101,7 @@ void os::safe_mode() State state = set_state(SAFE_MODE); Logger* logger; int count = 0; + double latitude = 0, longitude = 0; if (last_state > INITIALIZING) { @@ -117,17 +118,19 @@ void os::safe_mode() { case INITIALIZING: case ACQUIRING_FIX: - remove("data"); + remove(STATE_FILE); reboot(RB_AUTOBOOT); break; case FIX_ACQUIRED: // It could be that the SMS was sent but the state didn't change case WAITING_LAUNCH: + case GOING_UP: + case GOING_DOWN: + case LANDED: logger->log("Initializing WiringPi..."); wiringPiSetup(); logger->log("WiringPi initialized."); logger->log("Initializing GPS..."); - while ( ! GPS::get_instance().initialize() && ++count < 5) logger->log("GPS initialization error."); @@ -135,23 +138,19 @@ void os::safe_mode() { logger->log("GPS initialized."); count = 0; - while ( ! GPS::get_instance().is_active() && ++count < 10) + logger->log("Waiting for GPS fix..."); + while ( ! GPS::get_instance().is_active() && ++count < 100) this_thread::sleep_for(10s); - this_thread::sleep_for(10s); - if (count == 10) + + if (count == 100) { logger->log("Not getting fix. Going to recovery mode."); reboot(RB_AUTOBOOT); } - double start_alt = GPS::get_instance().get_altitude(); - this_thread::sleep_for(5s); - double end_alt = GPS::get_instance().get_altitude(); - - if (end_alt - start_alt < -10) state = set_state(GOING_DOWN); - else if (end_alt - start_alt > 10) state = set_state(GOING_UP); - else if (end_alt > 5000) state = set_state(GOING_DOWN); - else state = set_state(LANDED); + logger->log("GPS fix acquired."); + this_thread::sleep_for(10s); + state = (state == LANDED) ? LANDED : get_real_state(); logger->log("Initializing GSM..."); if ( ! GSM::get_instance().initialize()) @@ -170,17 +169,59 @@ void os::safe_mode() reboot(RB_AUTOBOOT); } break; - case GOING_UP: - break; - case GOING_DOWN: - break; - case LANDED: - break; case SHUT_DOWN: + shut_down(logger); break; case SAFE_MODE: logger->log("Recovery mode"); - // TODO recovery mode + + logger->log("Initializing GSM..."); + while ( ! GSM::get_instance().initialize()) GSM::get_instance().turn_off(); + logger->log("GSM initialized"); + logger->log("Waiting for GSM connectivity..."); + while ( ! GSM::get_instance().has_connectivity()) this_thread::sleep_for(5s); + logger->log("GSM connected."); + + count = 0; + logger->log("Sending mayday messages..."); + while (count < 10) + { + this_thread::sleep_for(20s); + + GSM::get_instance().get_location(latitude, longitude); + GSM::get_instance().send_SMS("MAYDAY - Lat: "+ + to_string(latitude) +" and Lon: "+ + to_string(longitude), SMS_PHONE) && ++count; + } + logger->log("Mayday messages sent."); + + logger->log("Initializing GPS..."); + while ( ! GPS::get_instance().initialize() && ++count < 5) + logger->log("GPS initialization error."); + shut_down(logger); + + if (count < 5) + { + logger->log("GPS initialized."); + count = 0; + logger->log("Waiting for GPS fix..."); + while ( ! GPS::get_instance().is_active() && ++count < 100) + this_thread::sleep_for(10s); + + if (count == 100) + { + logger->log("Not getting fix."); + shut_down(logger); + } + + logger->log("GPS fix acquired."); + this_thread::sleep_for(10s); + state = (state == LANDED) ? LANDED : get_real_state(); + + main_while(logger, &state); + shut_down(logger); + } + } if (logger) delete logger; diff --git a/openstratos.h b/openstratos.h index 186aeb8..3ab7e71 100644 --- a/openstratos.h +++ b/openstratos.h @@ -21,7 +21,7 @@ #include "camera/Camera.h" #include "gsm/GSM.h" -#if DEBUG +#ifdef DEBUG #include #endif diff --git a/serial/Serial.cc b/serial/Serial.cc index 84986bb..146012e 100644 --- a/serial/Serial.cc +++ b/serial/Serial.cc @@ -12,7 +12,7 @@ #include "constants.h" #include "gps/GPS.h" -#if DEBUG +#ifdef DEBUG #include "logger/Logger.h" #endif @@ -27,7 +27,7 @@ Serial::Serial(const string& url, int baud_rate, const string& log_path) gettimeofday(&timer, NULL); struct tm * now = gmtime(&timer.tv_sec); - #if DEBUG + #ifdef DEBUG this->logger = new Logger("data/logs/"+log_path+"/Serial."+ to_string(now->tm_year+1900) +"-"+ to_string(now->tm_mon) +"-"+ to_string(now->tm_mday) +"."+ to_string(now->tm_hour) +"-"+ to_string(now->tm_min) +"-"+ to_string(now->tm_sec) +".log", "Serial"); @@ -36,7 +36,7 @@ Serial::Serial(const string& url, int baud_rate, const string& log_path) #ifndef OS_TESTING this->fd = serialOpen(url.c_str(), baud_rate); - #if DEBUG + #ifdef DEBUG if (this->fd == -1) this->logger->log("Error: connection fd is -1."); else this->open = true; #else @@ -50,7 +50,7 @@ Serial::~Serial() if (this->open) this->close(); - #if DEBUG + #ifdef DEBUG delete this->logger; #endif } @@ -59,7 +59,7 @@ void Serial::println(const string& str) const { serialPuts(this->fd, (str+"\r\n").c_str()); - #if DEBUG + #ifdef DEBUG this->logger->log("Sent: '"+str+"\\r\\n'"); #endif } @@ -68,7 +68,7 @@ void Serial::println() const { serialPuts(this->fd, "\r\n"); - #if DEBUG + #ifdef DEBUG this->logger->log("Sent: '\\r\\n'"); #endif } @@ -77,7 +77,7 @@ void Serial::write(unsigned char c) const { serialPutchar(this->fd, c); - #if DEBUG + #ifdef DEBUG this->logger->log("Sent char: '"+string(1, c)+"'"); #endif } @@ -132,7 +132,7 @@ const string Serial::read_line(double timeout) const if (elapsed_time > timeout) { - #if DEBUG + #ifdef DEBUG this->logger->log("Error: Serial timeout. ("+to_string(timeout)+" s)"); #endif @@ -167,7 +167,7 @@ const string Serial::read_line(double timeout) const if (available < 0) { - #if DEBUG + #ifdef DEBUG this->logger->log("Error: Serial available < 0."); #endif @@ -177,7 +177,7 @@ const string Serial::read_line(double timeout) const } #endif - #if DEBUG + #ifdef DEBUG this->logger->log("Received: '"+logstr+"'"); #endif diff --git a/serial/Serial.h b/serial/Serial.h index 796e8f7..0323a31 100644 --- a/serial/Serial.h +++ b/serial/Serial.h @@ -6,7 +6,7 @@ #include #include "constants.h" -#if DEBUG +#ifdef DEBUG #include "logger/Logger.h" #endif using namespace std; @@ -18,7 +18,7 @@ namespace os { int fd; bool open; - #if DEBUG + #ifdef DEBUG Logger* logger; #endif diff --git a/utils.cc b/utils.cc index 585a690..8491e07 100644 --- a/utils.cc +++ b/utils.cc @@ -1,16 +1,15 @@ #include "utils.h" #include +#ifdef DEBUG + #include +#endif #include #include #include "constants.h" -#ifdef DEBUG - #include -#endif - using namespace std; using namespace os; @@ -20,7 +19,7 @@ void os::check_or_create(const string& path, Logger* logger) { if (logger != NULL) logger->log("No '"+path+"' directory, creating..."); - #if DEBUG + #ifdef DEBUG else cout << "[OpenStratos] No '"+path+"' directory, creating..." << endl; #endif @@ -40,7 +39,7 @@ void os::check_or_create(const string& path, Logger* logger) { if (logger != NULL) logger->log("'"+path+"' directory created."); - #if DEBUG + #ifdef DEBUG else cout << "[OpenStratos] '"+path+"' directory created." << endl; #endif diff --git a/utils.h b/utils.h index ced1217..40040ea 100644 --- a/utils.h +++ b/utils.h @@ -2,11 +2,14 @@ #define UTILS_H_ #include +#include #include #include +#include "constants.h" #include "logger/Logger.h" +#include "gps/GPS.h" namespace os { enum State { @@ -40,6 +43,18 @@ namespace os { State set_state(State new_state); State get_last_state(); const string state_to_string(State state); + + inline State get_real_state() + { + double start_alt = 0;//GPS::get_instance().get_altitude(); + this_thread::sleep_for(5s); + double end_alt = 0;//GPS::get_instance().get_altitude(); + + if (end_alt - start_alt < -10) return set_state(GOING_DOWN); + else if (end_alt - start_alt > 5) return set_state(GOING_UP); + else if (end_alt > 8000) return set_state(GOING_DOWN); + else return set_state(LANDED); + } } #endif // UTILS_H_ From 8cdbdf02d8ab2dfc1e91f23959d4a7ee91c829f2 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 16:09:03 +0200 Subject: [PATCH 136/169] Enabled camera recording in safe mode --- openstratos.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/openstratos.cc b/openstratos.cc index 24689f1..5868baa 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -160,6 +160,15 @@ void os::safe_mode() } logger->log("GSM initialized."); + if (state != LANDED) + { + logger->log("Trying to start recording...") + if (Camera::get_instance().record()) + logger->log("Recording."); + else + logger->log("Error starting recording"); + } + main_while(logger, &state); shut_down(logger); } From 5293362f69eb1f4002811aa3be886efb2182cbad Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 17:20:57 +0200 Subject: [PATCH 137/169] That's all folks! Feature freeze finished. I will try to polish the script a bit, but everything is finished. Now comes the 1.5 week long bug fixing. This implements #37 and #44. It also adds a <160 characters check in the SMS sending so that we can debug that better. --- gps/GPS.h | 2 +- gsm/GSM.cc | 7 ++ openstratos.cc | 201 ++++++++++++++++++++++++++++---------------- openstratos.h | 10 +-- testing/gps_test.cc | 12 +-- utils.h | 50 +++++++++++ 6 files changed, 193 insertions(+), 89 deletions(-) diff --git a/gps/GPS.h b/gps/GPS.h index 72c364c..3dac520 100644 --- a/gps/GPS.h +++ b/gps/GPS.h @@ -55,7 +55,7 @@ namespace os { static bool is_valid(string frame); tm get_time() const {return this->time;} - bool is_active() const {return this->active;} + bool is_fixed() const {return this->active;} uint_fast8_t get_satellites() const {return this->satellites;} double get_latitude() const {return this->latitude;} double get_longitude() const {return this->longitude;} diff --git a/gsm/GSM.cc b/gsm/GSM.cc index f079e6d..5e15457 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -125,6 +125,12 @@ bool GSM::send_SMS(const string& message, const string& number) this->occupied = true; this->logger->log("Sending SMS: \""+message+"\" to number "+number+"."); + if (message.length() > 160) + { + this->logger->log("Error: SMS has more than 10 characters"); + } + else + { #ifndef NO_SMS if (this->send_command_read("AT+CMGF=1") != "OK") { @@ -166,6 +172,7 @@ bool GSM::send_SMS(const string& message, const string& number) #else this_thread::sleep_for(5s); #endif + } this->occupied = false; this->logger->log("SMS sent."); diff --git a/openstratos.cc b/openstratos.cc index 5868baa..5aeb0ab 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -139,7 +139,7 @@ void os::safe_mode() logger->log("GPS initialized."); count = 0; logger->log("Waiting for GPS fix..."); - while ( ! GPS::get_instance().is_active() && ++count < 100) + while ( ! GPS::get_instance().is_fixed() && ++count < 100) this_thread::sleep_for(10s); if (count == 100) @@ -162,7 +162,7 @@ void os::safe_mode() if (state != LANDED) { - logger->log("Trying to start recording...") + logger->log("Trying to start recording..."); if (Camera::get_instance().record()) logger->log("Recording."); else @@ -191,16 +191,14 @@ void os::safe_mode() while ( ! GSM::get_instance().has_connectivity()) this_thread::sleep_for(5s); logger->log("GSM connected."); - count = 0; logger->log("Sending mayday messages..."); - while (count < 10) + for (count = 0; count < 10;) { this_thread::sleep_for(20s); GSM::get_instance().get_location(latitude, longitude); - GSM::get_instance().send_SMS("MAYDAY - Lat: "+ - to_string(latitude) +" and Lon: "+ - to_string(longitude), SMS_PHONE) && ++count; + GSM::get_instance().send_SMS("MAYDAY\r\nLat: "+ to_string(latitude) +"\r\n"+ + "Lon: "+ to_string(longitude), SMS_PHONE) && ++count; } logger->log("Mayday messages sent."); @@ -214,7 +212,7 @@ void os::safe_mode() logger->log("GPS initialized."); count = 0; logger->log("Waiting for GPS fix..."); - while ( ! GPS::get_instance().is_active() && ++count < 100) + while ( ! GPS::get_instance().is_fixed() && ++count < 100) this_thread::sleep_for(10s); if (count == 100) @@ -238,6 +236,8 @@ void os::safe_mode() void os::main_while(Logger* logger, State* state) { + double launch_altitude; + while (*state != SHUT_DOWN) { if (*state == ACQUIRING_FIX) @@ -255,13 +255,13 @@ void os::main_while(Logger* logger, State* state) } else if (*state == WAITING_LAUNCH) { - wait_launch(logger); + wait_launch(logger, launch_altitude); *state = set_state(GOING_UP); logger->log("State changed to "+ state_to_string(*state) +"."); } else if (*state == GOING_UP) { - go_up(logger); + go_up(logger, launch_altitude); logger->log("Balloon burst."); *state = set_state(GOING_DOWN); @@ -286,45 +286,6 @@ void os::main_while(Logger* logger, State* state) } } -inline bool os::has_launched(double launch_altitude) -{ - double first_altitude = GPS::get_instance().get_altitude(); - if (first_altitude > launch_altitude + 100) return true; - - this_thread::sleep_for(5s); - double second_altitude = GPS::get_instance().get_altitude(); - - #if defined SIM || defined REAL_SIM - return true; - #else - return second_altitude > first_altitude + 10; - #endif -} - -inline bool os::has_bursted(double maximum_altitude) -{ - double first_altitude = GPS::get_instance().get_altitude(); - if (first_altitude < maximum_altitude - 1000) return true; - - this_thread::sleep_for(6s); - double second_altitude = GPS::get_instance().get_altitude(); - - #if defined SIM || defined REAL_SIM - return true; - #else - return second_altitude < first_altitude - 10; - #endif -} - -inline bool os::has_landed() -{ - double first_altitude = GPS::get_instance().get_altitude(); - this_thread::sleep_for(5s); - double second_altitude = GPS::get_instance().get_altitude(); - - return abs(first_altitude-second_altitude) < 5; -} - void os::initialize(Logger* logger, tm* now) { check_or_create("data/video", logger); @@ -449,7 +410,7 @@ void os::initialize(Logger* logger, tm* now) void os::aquire_fix(Logger* logger) { - while ( ! GPS::get_instance().is_active()) + while ( ! GPS::get_instance().is_fixed()) this_thread::sleep_for(1s); logger->log("GPS fix acquired, waiting for date change."); @@ -489,8 +450,23 @@ void os::start_recording(Logger* logger) void os::send_init_sms(Logger* logger) { + double main_battery = 0, gsm_battery = 0; + bool bat_status = false; + + logger->log("Getting battery values..."); + if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + logger->log("Sending initialization SMS..."); - if ( ! GSM::get_instance().send_SMS("Initialization finished OK. Recording. Waiting for launch.", SMS_PHONE)) + if ( ! GSM::get_instance().send_SMS("Init: OK\r\n"+ + (bat_status ? "Main bat: "+to_string(main_battery*100)+"%\r\n"+ + "GSM bat: "+to_string(gsm_battery*100)+"%\r\n" : "Bat: ERR\r\n")+ + "Lat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +"\r\n"+ + "Waiting Launch", SMS_PHONE)) { logger->log("Error sending initialization SMS."); @@ -522,10 +498,10 @@ void os::send_init_sms(Logger* logger) logger->log("Initialization SMS sent."); } -void os::wait_launch(Logger* logger) +void os::wait_launch(Logger* logger, double& launch_altitude) { logger->log("Waiting for launch..."); - double launch_altitude = GPS::get_instance().get_altitude(); + launch_altitude = GPS::get_instance().get_altitude(); #ifdef SIM this_thread::sleep_for(2min); #endif @@ -539,12 +515,25 @@ void os::wait_launch(Logger* logger) logger->log("Balloon launched."); } -void os::go_up(Logger* logger) +void os::go_up(Logger* logger, double launch_altitude) { + double main_battery = 0, gsm_battery = 0; + bool bat_status = false; + + logger->log("Getting battery values..."); + if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + logger->log("Trying to send launch confirmation SMS..."); - if ( ! GSM::get_instance().send_SMS("Launched in Lat: "+ - to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ - to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + if ( ! GSM::get_instance().send_SMS( + "Launched.\r\nAlt: "+ to_string(launch_altitude) + + "m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) { logger->log("Error sending launch confirmation SMS."); } @@ -566,10 +555,20 @@ void os::go_up(Logger* logger) this_thread::sleep_for(225s); #endif logger->log("1.5 km mark."); + + logger->log("Getting battery values..."); + if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + logger->log("Trying to send \"going up\" SMS..."); - if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going up in Lat: "+ - to_string(GPS::get_instance().get_latitude()) +" and Lon: "+ - to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + if ( ! GSM::get_instance().send_SMS( + "Alt: > 1.5km\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) { logger->log("Error sending \"going up\" SMS."); } @@ -701,6 +700,9 @@ void os::go_up(Logger* logger) void os::go_down(Logger* logger) { + double main_battery = 0, gsm_battery = 0; + bool bat_status = false; + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); logger->log("25 km mark passed going down."); @@ -772,9 +774,19 @@ void os::go_down(Logger* logger) { logger->log("GSM connected."); + logger->log("Getting battery values..."); + if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + logger->log("Trying to send first SMS..."); - if ( ! GSM::get_instance().send_SMS("2.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + if ( ! GSM::get_instance().send_SMS( + "Alt: < 2.5km\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) { logger->log("Error sending first SMS."); } @@ -782,6 +794,8 @@ void os::go_down(Logger* logger) { logger->log("First SMS sent."); } + + bat_status = false; } bool landed = false; @@ -814,9 +828,19 @@ void os::go_down(Logger* logger) { logger->log("GSM connected."); + logger->log("Getting battery values..."); + if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + logger->log("Trying to send second SMS..."); - if ( ! GSM::get_instance().send_SMS("1.5 km mark passed going down in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + if ( ! GSM::get_instance().send_SMS( + "Alt: < 1.5km\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) { logger->log("Error sending second SMS."); } @@ -824,6 +848,8 @@ void os::go_down(Logger* logger) { logger->log("Second SMS sent."); } + + bat_status = false; } } @@ -857,9 +883,20 @@ void os::go_down(Logger* logger) { logger->log("GSM connected."); + logger->log("Getting battery values..."); + if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + + logger->log("Trying to send third SMS..."); - if ( ! GSM::get_instance().send_SMS("500 m mark passed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + if ( ! GSM::get_instance().send_SMS( + "Alt: < 500m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) { logger->log("Error sending third SMS."); } @@ -885,9 +922,22 @@ void os::land(Logger* logger) logger->log("Waiting 1 minute before sending landed SMS..."); this_thread::sleep_for(1min); + double main_battery = 0, gsm_battery = 0; + bool bat_status = false; + + logger->log("Getting battery values..."); + if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + logger->log("Sending landed SMS..."); - if ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE)) + if ( ! GSM::get_instance().send_SMS( + "Landed.\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) { logger->log("Error sending landed SMS. Trying again in 10 minutes..."); } @@ -899,13 +949,16 @@ void os::land(Logger* logger) this_thread::sleep_for(10min); logger->log("Sending second landed SMS..."); - - double main_battery = 1, gsm_battery = 1; - while ( ! GSM::get_instance().send_SMS("Landed in Lat: "+ to_string(GPS::get_instance().get_latitude()) - +" and Lon: "+ to_string(GPS::get_instance().get_longitude()) +".", SMS_PHONE) && - (main_battery >= 0.05 || main_battery < -1) && gsm_battery >= 0.05) + while ( ! GSM::get_instance().send_SMS( + "Landed.\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE) || + ! GPS::get_instance().is_fixed() && + (main_battery >= 0 || main_battery < -1) && gsm_battery >= 0) { - logger->log("Error sending second SMS, trying again in 5 minutes."); + logger->log("Error sending second SMS or GPS without fix, trying again in 5 minutes."); this_thread::sleep_for(5min); GSM::get_instance().get_battery_status(main_battery, gsm_battery); } diff --git a/openstratos.h b/openstratos.h index 3ab7e71..f1c9b9e 100644 --- a/openstratos.h +++ b/openstratos.h @@ -1,8 +1,6 @@ #ifndef OPENSTRATOS_H_ #define OPENSTRATOS_H_ -#include - #include #include @@ -35,15 +33,11 @@ namespace os void aquire_fix(Logger* logger); void start_recording(Logger* logger); void send_init_sms(Logger* logger); - void wait_launch(Logger* logger); - void go_up(Logger* logger); + void wait_launch(Logger* logger, double& launch_altitude); + void go_up(Logger* logger, double launch_altitude); void go_down(Logger* logger); void land(Logger* logger); void shut_down(Logger* logger); - - inline bool has_launched(double launch_altitude); - inline bool has_bursted(double maximum_altitude); - inline bool has_landed(); } using namespace std; diff --git a/testing/gps_test.cc b/testing/gps_test.cc index a1d3c1e..e647605 100644 --- a/testing/gps_test.cc +++ b/testing/gps_test.cc @@ -23,7 +23,7 @@ describe("GPS", [](){ it("GGA frame parser test", [&](){ GPS::get_instance().parse("$GPGGA,151025,2011.3454,N,12020.2464,W,1,05,1.53,20134.13,M,20103.45,M,,*56"); - AssertThat(GPS::get_instance().is_active(), Equals(true)); + AssertThat(GPS::get_instance().is_fixed(), Equals(true)); tm gps_time = GPS::get_instance().get_time(); AssertThat(gps_time.tm_hour, Equals(15)); @@ -52,7 +52,7 @@ describe("GPS", [](){ GPS::get_instance().parse("$GPGGA,170810,2316.3654,S,12225.2464,E,0,07,1.89,18647.15,M,18640.35,M,,*53"); - AssertThat(GPS::get_instance().is_active(), Equals(false)); + AssertThat(GPS::get_instance().is_fixed(), Equals(false)); AssertThat(GPS::get_instance().get_time().tm_hour, Equals(hour)); AssertThat(GPS::get_instance().get_time().tm_min, Equals(min)); @@ -68,7 +68,7 @@ describe("GPS", [](){ it("GSA frame parser test", [&](){ GPS::get_instance().parse("$GPGSA,A,3,,,,,,16,18,,22,24,,,3.6,2.1,2.2*3C"); - AssertThat(GPS::get_instance().is_active(), Equals(true)); + AssertThat(GPS::get_instance().is_fixed(), Equals(true)); AssertThat(GPS::get_instance().get_HDOP(), Is().EqualToWithDelta(2.1, 0.0005)); AssertThat(GPS::get_instance().get_VDOP(), Is().EqualToWithDelta(2.2, 0.0005)); }); @@ -79,7 +79,7 @@ describe("GPS", [](){ GPS::get_instance().parse("$GPGSA,A,1,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*36"); - AssertThat(GPS::get_instance().is_active(), Equals(false)); + AssertThat(GPS::get_instance().is_fixed(), Equals(false)); AssertThat(GPS::get_instance().get_HDOP(), Equals(hdop)); AssertThat(GPS::get_instance().get_VDOP(), Equals(vdop)); }); @@ -87,7 +87,7 @@ describe("GPS", [](){ it("RMC frame parser test", [&](){ GPS::get_instance().parse("$GPRMC,225446,A,4916.45,N,12311.12,W,000.5,054.7,191194,020.3,E*68"); - AssertThat(GPS::get_instance().is_active(), Equals(true)); + AssertThat(GPS::get_instance().is_fixed(), Equals(true)); tm gps_time = GPS::get_instance().get_time(); @@ -122,7 +122,7 @@ describe("GPS", [](){ GPS::get_instance().parse("$GPRMC,081836,V,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*75"); - AssertThat(GPS::get_instance().is_active(), Equals(false)); + AssertThat(GPS::get_instance().is_fixed(), Equals(false)); tm new_gps_time = GPS::get_instance().get_time(); diff --git a/utils.h b/utils.h index 40040ea..e2a4c68 100644 --- a/utils.h +++ b/utils.h @@ -1,6 +1,8 @@ #ifndef UTILS_H_ #define UTILS_H_ +#include + #include #include @@ -55,6 +57,54 @@ namespace os { else if (end_alt > 8000) return set_state(GOING_DOWN); else return set_state(LANDED); } + + inline bool has_launched(double launch_altitude) + { + for (int i = 0; ! GPS::get_instance().is_fixed() && i < 10; ++i); + if ( ! GPS::get_instance().is_fixed()) return false; + + double first_altitude = GPS::get_instance().get_altitude(); + if (first_altitude > launch_altitude + 100) return true; + + this_thread::sleep_for(5s); + double second_altitude = GPS::get_instance().get_altitude(); + + #if defined SIM || defined REAL_SIM + return true; + #else + return second_altitude > first_altitude + 10; + #endif + } + + inline bool has_bursted(double maximum_altitude) + { + for (int i = 0; ! GPS::get_instance().is_fixed() && i < 10; ++i); + if ( ! GPS::get_instance().is_fixed()) return false; + + double first_altitude = GPS::get_instance().get_altitude(); + if (first_altitude < maximum_altitude - 1000) return true; + + this_thread::sleep_for(6s); + double second_altitude = GPS::get_instance().get_altitude(); + + #if defined SIM || defined REAL_SIM + return true; + #else + return second_altitude < first_altitude - 10; + #endif + } + + inline bool has_landed() + { + for (int i = 0; ! GPS::get_instance().is_fixed() && i < 10; ++i); + if ( ! GPS::get_instance().is_fixed()) return false; + + double first_altitude = GPS::get_instance().get_altitude(); + this_thread::sleep_for(5s); + double second_altitude = GPS::get_instance().get_altitude(); + + return abs(first_altitude-second_altitude) < 5; + } } #endif // UTILS_H_ From c96f22d31a35c079143bbbf7c64844739e6d1f32 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 17:50:58 +0200 Subject: [PATCH 138/169] Small debug log added --- openstratos.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index 5aeb0ab..bd242d3 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -334,7 +334,26 @@ void os::initialize(Logger* logger, tm* now) logger->log("Checking batteries..."); double main_battery, gsm_battery; - GSM::get_instance().get_battery_status(main_battery, gsm_battery); + if ( ! GSM::get_instance().get_battery_status(main_battery, gsm_battery) + { + logger->log("Error checking batteries."); + + logger->log("Turning GSM off..."); + if (GSM::get_instance().turn_off()) + logger->log("GSM off."); + else + logger->log("Error turning GSM off."); + + logger->log("Turning GPS off..."); + if (GPS::get_instance().turn_off()) + logger->log("GPS off."); + else + logger->log("Error turning GPS off."); + + sync(); + reboot(RB_POWER_OFF); + } + logger->log("Batteries checked => Main battery: "+ (main_battery > -1 ? to_string(main_battery*100)+"%" : "disconnected") + " - GSM battery: "+ to_string(gsm_battery*100) +"%"); From 90961bf156bc1f373d681c83f5d582599daf6dcf Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 5 Sep 2015 22:27:07 +0200 Subject: [PATCH 139/169] Bumped version to 1.0-rc1 This release candidate is due September 9th. If no new bugs are found before September 14th, this should be released as 1.0 stable and used on the flight on September 19th. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4ed6251..ad87ade 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT(OpenStratos, 1.0.0-dev, https://github.com/OpenStratos/server/issues) +AC_INIT(OpenStratos, 1.0-rc1, https://github.com/OpenStratos/server/issues) AC_CONFIG_SRCDIR([openstratos.cc]) AM_INIT_AUTOMAKE([subdir-objects]) AC_CONFIG_HEADERS([config.h]) From 64c4346d48053392c004524553490c0c2be1b12d Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 12:53:10 +0200 Subject: [PATCH 140/169] Fixed small compilation issue --- openstratos.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index bd242d3..0f8655d 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -334,7 +334,7 @@ void os::initialize(Logger* logger, tm* now) logger->log("Checking batteries..."); double main_battery, gsm_battery; - if ( ! GSM::get_instance().get_battery_status(main_battery, gsm_battery) + if ( ! GSM::get_instance().get_battery_status(main_battery, gsm_battery)) { logger->log("Error checking batteries."); From 790f99acf66bfd9c17d0cf6a972810113fa8540b Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 15:34:54 +0200 Subject: [PATCH 141/169] Added no power off mode --- README | 22 ++++++++- openstratos.cc | 132 +++++++++++++++++++++++++++++++++++++++---------- openstratos.h | 13 ++--- 3 files changed, 132 insertions(+), 35 deletions(-) diff --git a/README b/README index 5b02f53..0d24b7b 100644 --- a/README +++ b/README @@ -93,11 +93,29 @@ It can be combined with the *NO_SMS* flag or/and one of the simulation flags: ./configure CPPFLAGS="-DNO_SMS -DDEBUG" ``` +### No power off mode ### + +For some testing there is no need to reboot or shut down the system in failures. For this, the +software provides the no power off mode, that will prevent the software from shutting the +Raspberry Pi down. For using this mode the directory should be cleaned with ```make clean``` and +then pass the *NO_POWER_OFF* flag to the configure script: + +``` +./configure CPPFLAGS="-DNO_POWER_OFF" +``` + +It can be combined with the *NO_SMS* flag, the *DEBUG* flag or/and one of the simulation flags: + +``` +./configure CPPFLAGS="-DREAL_SIM -DNO_SMS -DDEBUG -DNO_POWER_OFF" +./configure CPPFLAGS="-DSIM -DDEBUG -DNO_POWER_OFF" +./configure CPPFLAGS="-DNO_SMS -DDEBUG -DNO_POWER_OFF" + ## License ## This software is licensed under the GNU General Public License version 3. You can use, copy, modify -the software as long as all the derivative work is published under the same license. A copy of the license can be found in the *[COPYING](COPYING)* file of the repository where a detailed explanation of the -copying rights can be found. +the software as long as all the derivative work is published under the same license. A copy of the license can be found in the *[COPYING](COPYING)* file of the repository where a detailed explanation +of the copying rights can be found. ## Contributing guidelines ## diff --git a/openstratos.cc b/openstratos.cc index 0f8655d..43376c9 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -119,7 +119,12 @@ void os::safe_mode() case INITIALIZING: case ACQUIRING_FIX: remove(STATE_FILE); - reboot(RB_AUTOBOOT); + delete logger; + #ifndef NO_POWER_OFF + reboot(RB_AUTOBOOT); + #else + exit(0); + #endif break; case FIX_ACQUIRED: // It could be that the SMS was sent but the state didn't change case WAITING_LAUNCH: @@ -145,7 +150,12 @@ void os::safe_mode() if (count == 100) { logger->log("Not getting fix. Going to recovery mode."); - reboot(RB_AUTOBOOT); + delete logger; + #ifndef NO_POWER_OFF + reboot(RB_AUTOBOOT); + #else + exit(1); + #endif } logger->log("GPS fix acquired."); @@ -156,7 +166,12 @@ void os::safe_mode() if ( ! GSM::get_instance().initialize()) { logger->log("GSM initialization error. Going to recovery mode."); - reboot(RB_AUTOBOOT); + delete logger; + #ifndef NO_POWER_OFF + reboot(RB_AUTOBOOT); + #else + exit(1); + #endif } logger->log("GSM initialized."); @@ -175,7 +190,12 @@ void os::safe_mode() else { logger->log("Error initializing GPS. Going to recovery mode."); - reboot(RB_AUTOBOOT); + delete logger; + #ifndef NO_POWER_OFF + reboot(RB_AUTOBOOT); + #else + exit(1); + #endif } break; case SHUT_DOWN: @@ -281,7 +301,12 @@ void os::main_while(Logger* logger, State* state) } else { - reboot(RB_AUTOBOOT); + delete logger; + #ifndef NO_POWER_OFF + reboot(RB_AUTOBOOT); + #else + exit(1); + #endif } } } @@ -297,8 +322,14 @@ void os::initialize(Logger* logger, tm* now) if (available_disk_space < FLIGHT_LENGTH*9437184000) // 1.25 times the flight length { logger->log("Error: Not enough disk space."); - sync(); - reboot(RB_POWER_OFF); + + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } logger->log("Disk space enough for about " + to_string(available_disk_space/7549747200) + @@ -312,8 +343,14 @@ void os::initialize(Logger* logger, tm* now) if ( ! GPS::get_instance().initialize()) { logger->log("GPS initialization error."); - sync(); - reboot(RB_POWER_OFF); + + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } logger->log("GPS initialized."); @@ -327,8 +364,13 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - sync(); - reboot(RB_POWER_OFF); + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } logger->log("GSM initialized."); @@ -350,8 +392,13 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - sync(); - reboot(RB_POWER_OFF); + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } logger->log("Batteries checked => Main battery: "+ (main_battery > -1 ? to_string(main_battery*100)+"%" : "disconnected") + @@ -373,15 +420,19 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - sync(); - reboot(RB_POWER_OFF); + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } logger->log("Waiting for GSM connectivity..."); while ( ! GSM::get_instance().has_connectivity()) - { this_thread::sleep_for(1s); - } + logger->log("GSM connected."); logger->log("Testing camera recording..."); @@ -393,8 +444,14 @@ void os::initialize(Logger* logger, tm* now) if ( ! Camera::get_instance().record(10000)) { logger->log("Error starting recording"); - sync(); - reboot(RB_POWER_OFF); + + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } this_thread::sleep_for(11s); if (file_exists("data/video/test.h264")) @@ -422,8 +479,13 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - sync(); - reboot(RB_POWER_OFF); + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } } @@ -461,8 +523,13 @@ void os::start_recording(Logger* logger) else logger->log("Error turning GPS off."); - sync(); - reboot(RB_POWER_OFF); + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } logger->log("Recording started."); } @@ -511,8 +578,13 @@ void os::send_init_sms(Logger* logger) else logger->log("Error turning GPS off."); - sync(); - reboot(RB_POWER_OFF); + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(1); + #endif } logger->log("Initialization SMS sent."); } @@ -1011,6 +1083,12 @@ void os::shut_down(Logger* logger) logger->log("Error turning GPS off."); logger->log("Powering off..."); - sync(); - reboot(RB_POWER_OFF); + + delete logger; + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #else + exit(0); + #endif } diff --git a/openstratos.h b/openstratos.h index f1c9b9e..deac4ad 100644 --- a/openstratos.h +++ b/openstratos.h @@ -3,10 +3,15 @@ #include #include +#ifdef DEBUG + #include +#endif #include -#include -#include +#ifndef NO_POWER_OFF + #include + #include +#endif #include @@ -19,10 +24,6 @@ #include "camera/Camera.h" #include "gsm/GSM.h" -#ifdef DEBUG - #include -#endif - namespace os { void main_logic(); From 36b1d6d660f463a998fb4e3f8533633de3ca1d86 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 17:40:26 +0200 Subject: [PATCH 142/169] Some fixes, might be the solution to #51. --- openstratos.cc | 3 +-- threads.cc | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 43376c9..6c563c5 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -103,7 +103,7 @@ void os::safe_mode() int count = 0; double latitude = 0, longitude = 0; - if (last_state > INITIALIZING) + if (last_state > ACQUIRING_FIX) { struct timeval timer; gettimeofday(&timer, NULL); @@ -119,7 +119,6 @@ void os::safe_mode() case INITIALIZING: case ACQUIRING_FIX: remove(STATE_FILE); - delete logger; #ifndef NO_POWER_OFF reboot(RB_AUTOBOOT); #else diff --git a/threads.cc b/threads.cc index 873c017..d55dd5a 100644 --- a/threads.cc +++ b/threads.cc @@ -38,7 +38,7 @@ void os::system_thread_fn(State& state) FILE *gpu_temp_process, *cpu_command_process; char gpu_response[11]; char cpu_command[100]; - struct sysinfo* info; + struct sysinfo info; while (state != SHUT_DOWN) { @@ -70,8 +70,8 @@ void os::system_thread_fn(State& state) cpu_logger.log(to_string((stof(s_data[2])+stof(s_data[4]))/ (stof(s_data[2])+stof(s_data[4])+stof(s_data[5])))); - sysinfo(info); - ram_logger.log(to_string(info->freeram/info->totalram)); + sysinfo(&info); + ram_logger.log(to_string(info.freeram/info.totalram)); this_thread::sleep_for(30s); } From 28508d8cbfd4d41e50c18219e18af5f55c9b7e0a Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 21:50:13 +0200 Subject: [PATCH 143/169] More fixes. Should fix #50, #53 and #54. --- openstratos.cc | 153 +++++++++++++++++++++++++++++++++++++++++-------- threads.cc | 3 +- utils.h | 4 +- 3 files changed, 131 insertions(+), 29 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 6c563c5..c290231 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -545,12 +545,13 @@ void os::send_init_sms(Logger* logger) logger->log("Error getting battery status."); logger->log("Sending initialization SMS..."); - if ( ! GSM::get_instance().send_SMS("Init: OK\r\n"+ + if ( ! GSM::get_instance().send_SMS( + "Init: OK\r\nAlt: "+ to_string(GPS::get_instance().get_latitude()) + + "\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) + + "\r\nLon: "+ to_string(GPS::get_instance().get_longitude()) + + "\r\nFix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +"\r\n"+ (bat_status ? "Main bat: "+to_string(main_battery*100)+"%\r\n"+ "GSM bat: "+to_string(gsm_battery*100)+"%\r\n" : "Bat: ERR\r\n")+ - "Lat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ - "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +"\r\n"+ "Waiting Launch", SMS_PHONE)) { logger->log("Error sending initialization SMS."); @@ -618,8 +619,8 @@ void os::go_up(Logger* logger, double launch_altitude) logger->log("Trying to send launch confirmation SMS..."); if ( ! GSM::get_instance().send_SMS( - "Launched.\r\nAlt: "+ to_string(launch_altitude) + - "m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Launched\r\nAlt: "+ to_string(launch_altitude) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + @@ -636,7 +637,7 @@ void os::go_up(Logger* logger, double launch_altitude) double current_altitude = GPS::get_instance().get_altitude(); #if !defined SIM && !defined REAL_SIM - while (current_altitude = GPS::get_instance().get_altitude() < 1500) + while (current_altitude = GPS::get_instance().get_altitude() < 1200) { if (current_altitude > maximum_altitude) maximum_altitude = current_altitude; this_thread::sleep_for(2s); @@ -644,7 +645,7 @@ void os::go_up(Logger* logger, double launch_altitude) #else this_thread::sleep_for(225s); #endif - logger->log("1.5 km mark."); + logger->log("1.2 km mark."); logger->log("Getting battery values..."); if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) @@ -654,7 +655,8 @@ void os::go_up(Logger* logger, double launch_altitude) logger->log("Trying to send \"going up\" SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: > 1.5km\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Alt: "+ to_string(GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + @@ -689,6 +691,12 @@ void os::go_up(Logger* logger, double launch_altitude) else return; #endif + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); logger->log("10 km mark passed going up."); @@ -705,6 +713,12 @@ void os::go_up(Logger* logger, double launch_altitude) else return; #endif + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); logger->log("15 km mark passed going up."); @@ -721,6 +735,12 @@ void os::go_up(Logger* logger, double launch_altitude) else return; #endif + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); logger->log("20 km mark passed going up."); @@ -737,6 +757,12 @@ void os::go_up(Logger* logger, double launch_altitude) else return; #endif + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); logger->log("25 km mark passed going up."); @@ -753,6 +779,12 @@ void os::go_up(Logger* logger, double launch_altitude) else return; #endif + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); logger->log("30 km mark passed going up."); @@ -769,6 +801,12 @@ void os::go_up(Logger* logger, double launch_altitude) else return; #endif + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); #elif defined REAL_SIM && !defined SIM @@ -784,8 +822,16 @@ void os::go_up(Logger* logger, double launch_altitude) #endif while ( ! has_bursted(maximum_altitude)) + { if ((current_altitude = GPS::get_instance().get_altitude()) > maximum_altitude) maximum_altitude = current_altitude; + + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } } void os::go_down(Logger* logger) @@ -801,7 +847,14 @@ void os::go_down(Logger* logger) logger->log("25 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 25000) + { this_thread::sleep_for(5s); + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } logger->log("25 km mark passed going down."); #endif @@ -814,8 +867,16 @@ void os::go_down(Logger* logger) logger->log("15 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 15000) + { this_thread::sleep_for(5s); + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } + logger->log("15 km mark passed going down."); #endif @@ -827,22 +888,38 @@ void os::go_down(Logger* logger) logger->log("5 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 5000) + { this_thread::sleep_for(5s); + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } + logger->log("5 km mark passed going down."); #endif #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); - logger->log("2.5 km mark passed going down."); + logger->log("2 km mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(525s); - logger->log("2.5 km mark passed going down."); + logger->log("2 km mark passed going down."); #else - while (GPS::get_instance().get_altitude() > 2500) + while (GPS::get_instance().get_altitude() > 2000) + { this_thread::sleep_for(5s); - logger->log("2.5 km mark passed going down."); + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } + + logger->log("2 km mark passed going down."); #endif logger->log("Turning on GSM..."); @@ -858,7 +935,7 @@ void os::go_down(Logger* logger) } if (count == 20) { - logger->log("No connectivity, waiting for 1.5 km mark or landing."); + logger->log("No connectivity, waiting for 1.2 km mark or landing."); } else { @@ -872,7 +949,8 @@ void os::go_down(Logger* logger) logger->log("Trying to send first SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: < 2.5km\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Alt: "+ to_string(GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + @@ -892,13 +970,20 @@ void os::go_down(Logger* logger) #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); - logger->log("1.5 km mark passed going down."); + logger->log("1.2 km mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(225s); - logger->log("1.5 km mark passed going down."); + logger->log("1.2 km mark passed going down."); #else - while (GPS::get_instance().get_altitude() > 1500 && ! (landed = has_landed())); - if ( ! landed) logger->log("1.5 km mark passed going down."); + while (GPS::get_instance().get_altitude() > 1200 && ! (landed = has_landed())) + { + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } + if ( ! landed) logger->log("1.2 km mark passed going down."); #endif if ( ! landed) @@ -926,7 +1011,8 @@ void os::go_down(Logger* logger) logger->log("Trying to send second SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: < 1.5km\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Alt: "+ to_string(GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + @@ -950,7 +1036,14 @@ void os::go_down(Logger* logger) this_thread::sleep_for(175s); logger->log("500 m mark passed going down."); #else - while (GPS::get_instance().get_altitude() > 500 && ! (landed = has_landed())); + while (GPS::get_instance().get_altitude() > 500 && ! (landed = has_landed())) + { + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } if ( ! landed) logger->log("500 m mark passed going down."); #endif @@ -982,7 +1075,8 @@ void os::go_down(Logger* logger) logger->log("Trying to send third SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: < 500m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Alt: "+ to_string(GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + @@ -997,7 +1091,14 @@ void os::go_down(Logger* logger) } } - while ( ! has_landed()); + while ( ! has_landed()) + { + if (get_available_disk_space() < 2000000000) + { + logger->log("Not enough disk space. Stopping video..."); + Camera::get_instance().stop(); + } + } logger->log("Landed."); } @@ -1023,7 +1124,8 @@ void os::land(Logger* logger) logger->log("Sending landed SMS..."); if ( ! GSM::get_instance().send_SMS( - "Landed.\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Landed.\r\nAlt: "+ to_string(GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + @@ -1040,7 +1142,8 @@ void os::land(Logger* logger) logger->log("Sending second landed SMS..."); while ( ! GSM::get_instance().send_SMS( - "Landed.\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Landed.\r\nAlt: "+ to_string(GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + diff --git a/threads.cc b/threads.cc index d55dd5a..940c635 100644 --- a/threads.cc +++ b/threads.cc @@ -71,7 +71,7 @@ void os::system_thread_fn(State& state) (stof(s_data[2])+stof(s_data[4])+stof(s_data[5])))); sysinfo(&info); - ram_logger.log(to_string(info.freeram/info.totalram)); + ram_logger.log(to_string(((double) info.freeram)/info.totalram)); this_thread::sleep_for(30s); } @@ -124,7 +124,6 @@ void os::picture_thread_fn(State& state) this_thread::sleep_for(4min); } - logger.log("Going down, no more pictures are being taken, picture thread is closing."); } diff --git a/utils.h b/utils.h index e2a4c68..2080550 100644 --- a/utils.h +++ b/utils.h @@ -48,9 +48,9 @@ namespace os { inline State get_real_state() { - double start_alt = 0;//GPS::get_instance().get_altitude(); + double start_alt = GPS::get_instance().get_altitude(); this_thread::sleep_for(5s); - double end_alt = 0;//GPS::get_instance().get_altitude(); + double end_alt = GPS::get_instance().get_altitude(); if (end_alt - start_alt < -10) return set_state(GOING_DOWN); else if (end_alt - start_alt > 5) return set_state(GOING_UP); From 5214939424eb2a6ab78f73a89d8c4adcf41504f3 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 22:45:01 +0200 Subject: [PATCH 144/169] Fixed #55 --- openstratos.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index c290231..f075d4c 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -318,7 +318,7 @@ void os::initialize(Logger* logger, tm* now) float available_disk_space = get_available_disk_space(); logger->log("Available disk space: " + to_string(available_disk_space/1073741824) + " GiB"); - if (available_disk_space < FLIGHT_LENGTH*9437184000) // 1.25 times the flight length + if (available_disk_space < (FLIGHT_LENGTH*1.25+0.5)*7549747200) { logger->log("Error: Not enough disk space."); @@ -643,7 +643,7 @@ void os::go_up(Logger* logger, double launch_altitude) this_thread::sleep_for(2s); } #else - this_thread::sleep_for(225s); + this_thread::sleep_for(124s); #endif logger->log("1.2 km mark."); @@ -679,7 +679,7 @@ void os::go_up(Logger* logger, double launch_altitude) this_thread::sleep_for(2min); logger->log("5 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1225s); + this_thread::sleep_for(1357s); logger->log("5 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -701,7 +701,7 @@ void os::go_up(Logger* logger, double launch_altitude) this_thread::sleep_for(2min); logger->log("10 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1750s); + this_thread::sleep_for(1786s); logger->log("10 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -723,7 +723,7 @@ void os::go_up(Logger* logger, double launch_altitude) this_thread::sleep_for(2min); logger->log("15 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1725s); + this_thread::sleep_for(1786s); logger->log("15 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -745,7 +745,7 @@ void os::go_up(Logger* logger, double launch_altitude) this_thread::sleep_for(2min); logger->log("20 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1750s); + this_thread::sleep_for(1786s); logger->log("20 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -767,7 +767,7 @@ void os::go_up(Logger* logger, double launch_altitude) this_thread::sleep_for(2min); logger->log("25 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1750s); + this_thread::sleep_for(1786s); logger->log("25 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -789,7 +789,7 @@ void os::go_up(Logger* logger, double launch_altitude) this_thread::sleep_for(2min); logger->log("30 km mark passed going up."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1725s); + this_thread::sleep_for(1786s); logger->log("30 km mark passed going up."); #else while ( ! (bursted = has_bursted(maximum_altitude)) && @@ -810,7 +810,7 @@ void os::go_up(Logger* logger, double launch_altitude) #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(1650s); + this_thread::sleep_for(1740s); #else while ( ! (bursted = has_bursted(maximum_altitude)) && (current_altitude = GPS::get_instance().get_altitude()) < 35000) @@ -843,7 +843,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("25 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(325s); + this_thread::sleep_for(317s); logger->log("25 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 25000) @@ -863,7 +863,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("15 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(700s); + this_thread::sleep_for(684s); logger->log("15 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 15000) @@ -905,7 +905,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("2 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(525s); + this_thread::sleep_for(650s); logger->log("2 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 2000) @@ -972,7 +972,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("1.2 km mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(225s); + this_thread::sleep_for(183s); logger->log("1.2 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 1200 && ! (landed = has_landed())) @@ -1033,7 +1033,7 @@ void os::go_down(Logger* logger) this_thread::sleep_for(1min); logger->log("500 m mark passed going down."); #elif defined REAL_SIM && !defined SIM - this_thread::sleep_for(175s); + this_thread::sleep_for(117s); logger->log("500 m mark passed going down."); #else while (GPS::get_instance().get_altitude() > 500 && ! (landed = has_landed())) From 76e44108af28c61b842fa2226caf2e95ec83c303 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 22:59:36 +0200 Subject: [PATCH 145/169] No need for that delete, using RAII. --- openstratos.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index f075d4c..e8e19c9 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -1186,7 +1186,6 @@ void os::shut_down(Logger* logger) logger->log("Powering off..."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); From a1f2322227ea6499f10f516ae1da9d9c70ab0f7d Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 23:35:28 +0200 Subject: [PATCH 146/169] Fixed small issues when shutting the app down. --- openstratos.cc | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index e8e19c9..0631b36 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -120,6 +120,7 @@ void os::safe_mode() case ACQUIRING_FIX: remove(STATE_FILE); #ifndef NO_POWER_OFF + sync(); reboot(RB_AUTOBOOT); #else exit(0); @@ -151,6 +152,7 @@ void os::safe_mode() logger->log("Not getting fix. Going to recovery mode."); delete logger; #ifndef NO_POWER_OFF + sync(); reboot(RB_AUTOBOOT); #else exit(1); @@ -167,6 +169,7 @@ void os::safe_mode() logger->log("GSM initialization error. Going to recovery mode."); delete logger; #ifndef NO_POWER_OFF + sync(); reboot(RB_AUTOBOOT); #else exit(1); @@ -191,6 +194,7 @@ void os::safe_mode() logger->log("Error initializing GPS. Going to recovery mode."); delete logger; #ifndef NO_POWER_OFF + sync(); reboot(RB_AUTOBOOT); #else exit(1); @@ -300,8 +304,8 @@ void os::main_while(Logger* logger, State* state) } else { - delete logger; #ifndef NO_POWER_OFF + sync(); reboot(RB_AUTOBOOT); #else exit(1); @@ -322,7 +326,6 @@ void os::initialize(Logger* logger, tm* now) { logger->log("Error: Not enough disk space."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -343,7 +346,6 @@ void os::initialize(Logger* logger, tm* now) { logger->log("GPS initialization error."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -363,7 +365,6 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -391,7 +392,6 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -419,7 +419,6 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -444,7 +443,6 @@ void os::initialize(Logger* logger, tm* now) { logger->log("Error starting recording"); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -478,7 +476,6 @@ void os::initialize(Logger* logger, tm* now) else logger->log("Error turning GPS off."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -522,7 +519,6 @@ void os::start_recording(Logger* logger) else logger->log("Error turning GPS off."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); @@ -578,7 +574,6 @@ void os::send_init_sms(Logger* logger) else logger->log("Error turning GPS off."); - delete logger; #ifndef NO_POWER_OFF sync(); reboot(RB_POWER_OFF); From c9411f5a020758cbf2162c041e966e9a94ae50df Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 8 Sep 2015 23:43:28 +0200 Subject: [PATCH 147/169] Fixed small issue in safe mode and better exit. --- openstratos.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 0631b36..4ff993a 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -29,6 +29,11 @@ int main(void) safe_mode(); } + #ifndef NO_POWER_OFF + sync(); + reboot(RB_POWER_OFF); + #endif + return 0; } @@ -228,7 +233,6 @@ void os::safe_mode() logger->log("Initializing GPS..."); while ( ! GPS::get_instance().initialize() && ++count < 5) logger->log("GPS initialization error."); - shut_down(logger); if (count < 5) { @@ -251,7 +255,10 @@ void os::safe_mode() main_while(logger, &state); shut_down(logger); } - + else + { + shut_down(logger); + } } if (logger) delete logger; @@ -1180,11 +1187,4 @@ void os::shut_down(Logger* logger) logger->log("Error turning GPS off."); logger->log("Powering off..."); - - #ifndef NO_POWER_OFF - sync(); - reboot(RB_POWER_OFF); - #else - exit(0); - #endif } From c8f35ba0d714abb0f048e47541cda12878ee72f4 Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 9 Sep 2015 00:22:55 +0200 Subject: [PATCH 148/169] Fixed possible log deletion. --- openstratos.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index 4ff993a..9ed4d6a 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -108,6 +108,13 @@ void os::safe_mode() int count = 0; double latitude = 0, longitude = 0; + check_or_create("data/logs"); + check_or_create("data/logs/main"); + check_or_create("data/logs/system"); + check_or_create("data/logs/camera"); + check_or_create("data/logs/GPS"); + check_or_create("data/logs/GSM"); + if (last_state > ACQUIRING_FIX) { struct timeval timer; @@ -213,7 +220,8 @@ void os::safe_mode() logger->log("Recovery mode"); logger->log("Initializing GSM..."); - while ( ! GSM::get_instance().initialize()) GSM::get_instance().turn_off(); + while ( ! GSM::get_instance().initialize()) + logger->log("GSM initialization error."); logger->log("GSM initialized"); logger->log("Waiting for GSM connectivity..."); while ( ! GSM::get_instance().has_connectivity()) this_thread::sleep_for(5s); From 55a909f2f296347983a2370cfe040eaf5da0860b Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 9 Sep 2015 00:34:57 +0200 Subject: [PATCH 149/169] Fixed recovery mode: WiringPi was not initialized --- gsm/GSM.cc | 4 ++-- openstratos.cc | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 5e15457..6a6d676 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -71,8 +71,6 @@ bool GSM::initialize() this->logger->log("Turning module on..."); this->turn_on(); - this->logger->log("Module on. Sleeping 3 seconds to let it turn completely on..."); - this_thread::sleep_for(3s); if (this->get_status()) { this->logger->log("Status checked. Module is on."); @@ -82,6 +80,8 @@ bool GSM::initialize() this->logger->log("Error: Status checked. Module is off. Finishing initialization."); return false; } + this->logger->log("Sleeping 3 seconds to let it turn completely on..."); + this_thread::sleep_for(3s); this->occupied = true; this->logger->log("Starting serial connection..."); diff --git a/openstratos.cc b/openstratos.cc index 9ed4d6a..c981277 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -219,6 +219,10 @@ void os::safe_mode() case SAFE_MODE: logger->log("Recovery mode"); + logger->log("Initializing WiringPi..."); + wiringPiSetup(); + logger->log("WiringPi initialized."); + logger->log("Initializing GSM..."); while ( ! GSM::get_instance().initialize()) logger->log("GSM initialization error."); From 3c9ba045838d997bc9e906c35815d0d0b2a52207 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 10 Sep 2015 13:22:03 +0200 Subject: [PATCH 150/169] Trying to fix multiline SMSs (#56) --- constants.h | 2 +- gsm/GSM.cc | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/constants.h b/constants.h index df052e2..d94956a 100644 --- a/constants.h +++ b/constants.h @@ -1,7 +1,7 @@ #ifndef CONSTANTS_H_ #define CONSTANTS_H_ - #define FLIGHT_LENGTH 4.222 // Hours + #define FLIGHT_LENGTH 4.4333 // Hours #define BAT_GSM_MAX 4.2 #define BAT_GSM_MIN 3.7 diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 6a6d676..535137f 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -5,6 +5,7 @@ #include #include #include +#include #include @@ -147,7 +148,10 @@ bool GSM::send_SMS(const string& message, const string& number) } this->serial->println(message); - this->serial->read_line(); // Eat message echo + + for (int i = 0; i < std::count(message.begin(), message.end(), '\n'); i++) + this->serial->read_line(); // Eat message echo + this->serial->println(); this->serial->read_line(); // Eat prompt this->serial->write('\x1A'); @@ -240,6 +244,7 @@ bool GSM::get_location(double& latitude, double& longitude) } string response = this->send_command_read("AT+CIPGSMLOC=1,1"); + this->serial->read_line(); // Eat new line if (response == "ERROR" || this->serial->read_line() != "OK") { this->logger->log("Error getting location on 'AT+CIPGSMLOC=1,1' response."); From c4724532f436c504c464e1217bc6d406babb4868 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 10 Sep 2015 14:41:09 +0200 Subject: [PATCH 151/169] Fixed #56 --- gsm/GSM.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 535137f..08f57b9 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -149,13 +149,13 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->println(message); - for (int i = 0; i < std::count(message.begin(), message.end(), '\n'); i++) + for (int i = 0; i <= std::count(message.begin(), message.end(), '\n'); i++) this->serial->read_line(); // Eat message echo this->serial->println(); this->serial->read_line(); // Eat prompt this->serial->write('\x1A'); - this->serial->read_line(10); // Eat prompt (timeout 10 seconds) + this->serial->read_line(60); // Eat prompt (timeout 60 seconds) // Read line if (this->serial->read_line().find("+CMGS") == string::npos) From 1e829e6fca665980f83498464ec61027df8ee2db Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 10 Sep 2015 15:02:59 +0200 Subject: [PATCH 152/169] Added number of satellites to SMSs. We were reaching the 160 characters in some SMSs, so I decided to cut the altitude and battery levels to integer precission. This gives us enough precission to understand what is happening and to make decisions, but does not fill the SMSs with small numbers. For example, there is no need to know that the battery is at 94.400000%. If we get 94% is fine. Moreover, some of these numbers only had one decimal point number, so we were using two many characters for nothing. --- gsm/GSM.cc | 2 +- openstratos.cc | 79 +++++++++++++++++++++++++++----------------------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index 08f57b9..d67ceca 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -125,7 +125,7 @@ bool GSM::send_SMS(const string& message, const string& number) while (this->occupied) this_thread::sleep_for(10ms); this->occupied = true; - this->logger->log("Sending SMS: \""+message+"\" to number "+number+"."); + this->logger->log("Sending SMS: \""+message+"\" ("+ to_string(message.length()) +" characters) to number "+number+"."); if (message.length() > 160) { this->logger->log("Error: SMS has more than 10 characters"); diff --git a/openstratos.cc b/openstratos.cc index c981277..513ae0e 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -561,12 +561,12 @@ void os::send_init_sms(Logger* logger) logger->log("Sending initialization SMS..."); if ( ! GSM::get_instance().send_SMS( - "Init: OK\r\nAlt: "+ to_string(GPS::get_instance().get_latitude()) + + "Init: OK\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + "\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) + "\r\nLon: "+ to_string(GPS::get_instance().get_longitude()) + "\r\nFix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +"\r\n"+ - (bat_status ? "Main bat: "+to_string(main_battery*100)+"%\r\n"+ - "GSM bat: "+to_string(gsm_battery*100)+"%\r\n" : "Bat: ERR\r\n")+ + (bat_status ? "Main bat: "+to_string((int) main_battery*100)+"%\r\n"+ + "GSM bat: "+to_string((int) gsm_battery*100)+"%\r\n" : "Bat: ERR\r\n")+ "Waiting Launch", SMS_PHONE)) { logger->log("Error sending initialization SMS."); @@ -633,12 +633,13 @@ void os::go_up(Logger* logger, double launch_altitude) logger->log("Trying to send launch confirmation SMS..."); if ( ! GSM::get_instance().send_SMS( - "Launched\r\nAlt: "+ to_string(launch_altitude) + + "Launch\r\nAlt: "+ to_string((int) launch_altitude) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending launch confirmation SMS."); } @@ -669,12 +670,13 @@ void os::go_up(Logger* logger, double launch_altitude) logger->log("Trying to send \"going up\" SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: "+ to_string(GPS::get_instance().get_altitude()) + + "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending \"going up\" SMS."); } @@ -963,12 +965,13 @@ void os::go_down(Logger* logger) logger->log("Trying to send first SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: "+ to_string(GPS::get_instance().get_altitude()) + - " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ - "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) + "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending first SMS."); } @@ -1025,12 +1028,13 @@ void os::go_down(Logger* logger) logger->log("Trying to send second SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: "+ to_string(GPS::get_instance().get_altitude()) + + "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending second SMS."); } @@ -1089,12 +1093,13 @@ void os::go_down(Logger* logger) logger->log("Trying to send third SMS..."); if ( ! GSM::get_instance().send_SMS( - "Alt: "+ to_string(GPS::get_instance().get_altitude()) + + "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending third SMS."); } @@ -1138,12 +1143,13 @@ void os::land(Logger* logger) logger->log("Sending landed SMS..."); if ( ! GSM::get_instance().send_SMS( - "Landed.\r\nAlt: "+ to_string(GPS::get_instance().get_altitude()) + + "Landed.\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE)) + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending landed SMS. Trying again in 10 minutes..."); } @@ -1156,13 +1162,14 @@ void os::land(Logger* logger) logger->log("Sending second landed SMS..."); while ( ! GSM::get_instance().send_SMS( - "Landed.\r\nAlt: "+ to_string(GPS::get_instance().get_altitude()) + - " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ - "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string(main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string(gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "FIX: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +".", SMS_PHONE) || - ! GPS::get_instance().is_fixed() && + "Landed.\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE) || + ! GPS::get_instance().is_fixed() && (main_battery >= 0 || main_battery < -1) && gsm_battery >= 0) { logger->log("Error sending second SMS or GPS without fix, trying again in 5 minutes."); From b31aba07b8e4cc9de7191a1083856317b54b19f8 Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 10 Sep 2015 15:35:52 +0200 Subject: [PATCH 153/169] Small styling change to camera --- camera/Camera.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index ca6e85d..51440f6 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -42,13 +42,9 @@ Camera::~Camera() { this->logger->log("Stopping video recording..."); if ( ! this->stop()) - { this->logger->log("Error soping video recording."); - } else - { this->logger->log("Video recording stopped."); - } } this->logger->log("Shut down finished"); delete this->logger; @@ -171,7 +167,7 @@ bool Camera::stop() if ( ! this->is_really_recording()) { - this->logger->log("Warning: error was already stopped."); + this->logger->log("Warning: video was already stopped."); this->recording = false; return true; } From b3ba102ff2d3ab99bb3c9491244d10711be263ee Mon Sep 17 00:00:00 2001 From: Razican Date: Thu, 10 Sep 2015 19:35:06 +0200 Subject: [PATCH 154/169] Small polishing --- gsm/GSM.cc | 13 +++++++--- openstratos.cc | 69 +++++++++++++++++++++----------------------------- startup.sh | 3 +++ 3 files changed, 41 insertions(+), 44 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index d67ceca..e5f9d38 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -148,17 +148,20 @@ bool GSM::send_SMS(const string& message, const string& number) } this->serial->println(message); + this->command_logger->log("Sent: '"+message+"'"); for (int i = 0; i <= std::count(message.begin(), message.end(), '\n'); i++) - this->serial->read_line(); // Eat message echo + this->command_logger->log("Received: '"+this->serial->read_line()+"'"); // Eat message echo this->serial->println(); this->serial->read_line(); // Eat prompt this->serial->write('\x1A'); this->serial->read_line(60); // Eat prompt (timeout 60 seconds) - // Read line - if (this->serial->read_line().find("+CMGS") == string::npos) + // Read +CMGS response + response = this->serial->read_line(); + this->command_logger->log("Received: '"+response+"'"); + if (response.find("+CMGS") == string::npos) { this->logger->log("Error sending SMS. Could not read '+CMGS'."); this->occupied = false; @@ -167,7 +170,9 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->read_line(); // Eat new line // Read OK (timeout 10 seconds) - if (this->serial->read_line(10) != "OK") + string response = this->serial->read_line(10); + this->command_logger->log("Received: '"+response+"'"); + if (response != "OK") { this->logger->log("Error sending SMS. Could not read 'OK'."); this->occupied = false; diff --git a/openstratos.cc b/openstratos.cc index 513ae0e..d2979ae 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -172,7 +172,7 @@ void os::safe_mode() } logger->log("GPS fix acquired."); - this_thread::sleep_for(10s); + this_thread::sleep_for(1min); state = (state == LANDED) ? LANDED : get_real_state(); logger->log("Initializing GSM..."); @@ -261,7 +261,7 @@ void os::safe_mode() } logger->log("GPS fix acquired."); - this_thread::sleep_for(10s); + this_thread::sleep_for(1min); state = (state == LANDED) ? LANDED : get_real_state(); main_while(logger, &state); @@ -290,6 +290,7 @@ void os::main_while(Logger* logger, State* state) } else if (*state == FIX_ACQUIRED) { + this_thread::sleep_for(5min); // start_recording(logger); send_init_sms(logger); *state = set_state(WAITING_LAUNCH); @@ -304,8 +305,6 @@ void os::main_while(Logger* logger, State* state) else if (*state == GOING_UP) { go_up(logger, launch_altitude); - logger->log("Balloon burst."); - *state = set_state(GOING_DOWN); logger->log("State changed to "+ state_to_string(*state) +"."); } @@ -562,11 +561,12 @@ void os::send_init_sms(Logger* logger) logger->log("Sending initialization SMS..."); if ( ! GSM::get_instance().send_SMS( "Init: OK\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + - "\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) + - "\r\nLon: "+ to_string(GPS::get_instance().get_longitude()) + - "\r\nFix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") +"\r\n"+ - (bat_status ? "Main bat: "+to_string((int) main_battery*100)+"%\r\n"+ - "GSM bat: "+to_string((int) gsm_battery*100)+"%\r\n" : "Bat: ERR\r\n")+ + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()) + "Waiting Launch", SMS_PHONE)) { logger->log("Error sending initialization SMS."); @@ -848,6 +848,8 @@ void os::go_up(Logger* logger, double launch_altitude) Camera::get_instance().stop(); } } + + logger->log("Balloon burst at about "+ to_string((int) maximum_altitude) +" m."); } void os::go_down(Logger* logger) @@ -857,10 +859,8 @@ void os::go_down(Logger* logger) #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); - logger->log("25 km mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(317s); - logger->log("25 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 25000) { @@ -871,16 +871,14 @@ void os::go_down(Logger* logger) Camera::get_instance().stop(); } } - - logger->log("25 km mark passed going down."); #endif + logger->log("25 km mark passed going down."); + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); - logger->log("15 km mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(684s); - logger->log("15 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 15000) { @@ -892,16 +890,14 @@ void os::go_down(Logger* logger) Camera::get_instance().stop(); } } - - logger->log("15 km mark passed going down."); #endif + logger->log("15 km mark passed going down."); + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(2min); - logger->log("5 km mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(1450s); - logger->log("5 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 5000) { @@ -913,16 +909,14 @@ void os::go_down(Logger* logger) Camera::get_instance().stop(); } } - - logger->log("5 km mark passed going down."); #endif + logger->log("5 km mark passed going down."); + #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); - logger->log("2 km mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(650s); - logger->log("2 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 2000) { @@ -934,9 +928,8 @@ void os::go_down(Logger* logger) Camera::get_instance().stop(); } } - - logger->log("2 km mark passed going down."); #endif + logger->log("2 km mark passed going down."); logger->log("Turning on GSM..."); GSM::get_instance().turn_on(); @@ -987,10 +980,8 @@ void os::go_down(Logger* logger) #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); - logger->log("1.2 km mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(183s); - logger->log("1.2 km mark passed going down."); #else while (GPS::get_instance().get_altitude() > 1200 && ! (landed = has_landed())) { @@ -1000,11 +991,12 @@ void os::go_down(Logger* logger) Camera::get_instance().stop(); } } - if ( ! landed) logger->log("1.2 km mark passed going down."); #endif if ( ! landed) { + logger->log("1.2 km mark passed going down."); + count = 0; while ( ! GSM::get_instance().has_connectivity()) { @@ -1049,10 +1041,8 @@ void os::go_down(Logger* logger) #if defined SIM && !defined REAL_SIM this_thread::sleep_for(1min); - logger->log("500 m mark passed going down."); #elif defined REAL_SIM && !defined SIM this_thread::sleep_for(117s); - logger->log("500 m mark passed going down."); #else while (GPS::get_instance().get_altitude() > 500 && ! (landed = has_landed())) { @@ -1062,12 +1052,11 @@ void os::go_down(Logger* logger) Camera::get_instance().stop(); } } - if ( ! landed) logger->log("500 m mark passed going down."); #endif if ( ! landed) { - logger->log("500 m mark."); + logger->log("500 m mark passed going down."); count = 0; while ( ! GSM::get_instance().has_connectivity()) @@ -1143,13 +1132,13 @@ void os::land(Logger* logger) logger->log("Sending landed SMS..."); if ( ! GSM::get_instance().send_SMS( - "Landed.\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + - " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ - "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + - "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "Landed\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ + "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending landed SMS. Trying again in 10 minutes..."); } @@ -1162,7 +1151,7 @@ void os::land(Logger* logger) logger->log("Sending second landed SMS..."); while ( ! GSM::get_instance().send_SMS( - "Landed.\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + + "Landed\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ diff --git a/startup.sh b/startup.sh index 26fa1c2..1f153c0 100755 --- a/startup.sh +++ b/startup.sh @@ -1,5 +1,8 @@ #!/bin/sh +echo "[`date`] Stopping SSH daemon..." >> /root/control.log +/etc/init.d/ssh stop + echo "[`date`] Starting OpenStratos..." >> /root/control.log /root/openstratos >> /root/control.log 2>&1 & sleep 5 From e04fc50b700ce65536416209db73855306cbc917 Mon Sep 17 00:00:00 2001 From: Razican Date: Fri, 11 Sep 2015 23:41:51 +0200 Subject: [PATCH 155/169] Small polishing --- camera/Camera.cc | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 51440f6..8f6ca44 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -197,10 +197,7 @@ int os::get_file_count(const string& path) struct dirent *ep; dp = opendir(path.c_str()); - while (ep = readdir(dp)) - { - i++; - } + while (ep = readdir(dp)) i++; (void) closedir(dp); return i-2; @@ -210,9 +207,8 @@ const string os::generate_exif_data() { string exif; while (GPS::get_instance().get_PDOP() > 5) - { this_thread::sleep_for(1s); - } + double gps_lat = GPS::get_instance().get_latitude(); double gps_lon = GPS::get_instance().get_longitude(); double gps_alt = GPS::get_instance().get_altitude(); From c42b39964655f28294b1bd3a42f19f3f24a76320 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 15 Sep 2015 14:41:26 +0200 Subject: [PATCH 156/169] Fixed small build issue --- gsm/GSM.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index e5f9d38..a3e0fc6 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -159,7 +159,7 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->read_line(60); // Eat prompt (timeout 60 seconds) // Read +CMGS response - response = this->serial->read_line(); + string response = this->serial->read_line(); this->command_logger->log("Received: '"+response+"'"); if (response.find("+CMGS") == string::npos) { @@ -170,7 +170,7 @@ bool GSM::send_SMS(const string& message, const string& number) this->serial->read_line(); // Eat new line // Read OK (timeout 10 seconds) - string response = this->serial->read_line(10); + response = this->serial->read_line(10); this->command_logger->log("Received: '"+response+"'"); if (response != "OK") { From 56249db2fa4d899eb564a5401788656b10ab0e5a Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 15 Sep 2015 16:15:31 +0200 Subject: [PATCH 157/169] Small fixes in SMSs --- openstratos.cc | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index d2979ae..9b016f3 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -563,11 +563,11 @@ void os::send_init_sms(Logger* logger) "Init: OK\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()) + - "Waiting Launch", SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()) + + "\r\nWaiting Launch", SMS_PHONE)) { logger->log("Error sending initialization SMS."); @@ -636,10 +636,10 @@ void os::go_up(Logger* logger, double launch_altitude) "Launch\r\nAlt: "+ to_string((int) launch_altitude) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending launch confirmation SMS."); } @@ -673,10 +673,10 @@ void os::go_up(Logger* logger, double launch_altitude) "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending \"going up\" SMS."); } @@ -961,8 +961,8 @@ void os::go_down(Logger* logger) "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { @@ -1023,8 +1023,8 @@ void os::go_down(Logger* logger) "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { @@ -1085,8 +1085,8 @@ void os::go_down(Logger* logger) "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { @@ -1135,8 +1135,8 @@ void os::land(Logger* logger) "Landed\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { @@ -1154,8 +1154,8 @@ void os::land(Logger* logger) "Landed\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ - (bat_status ? "Main bat: "+ to_string((int) main_battery*100) +"%\r\n"+ - "GSM bat: "+ to_string((int) gsm_battery*100) +"%\r\n" : "Bat: ERR\r\n") + + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE) || ! GPS::get_instance().is_fixed() && @@ -1166,11 +1166,11 @@ void os::land(Logger* logger) GSM::get_instance().get_battery_status(main_battery, gsm_battery); } - if ((main_battery < 0.05 && main_battery > -1) || gsm_battery < 0.05) + if ((main_battery < 0 && main_battery > -1) || gsm_battery < 0) { logger->log("Not enough battery."); - logger->log("Main battery: "+ to_string(main_battery) + - "% - GSM battery: "+ to_string(gsm_battery) +"%"); + logger->log("Main battery: "+ to_string(main_battery*100) + + "% - GSM battery: "+ to_string(gsm_battery*100) +"%"); } else { From e43922f0137d0382c1136d4d45021f0592d14ad1 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 15 Sep 2015 23:10:15 +0200 Subject: [PATCH 158/169] Fixed #39 --- camera/Camera.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/camera/Camera.cc b/camera/Camera.cc index 8f6ca44..3d66d5a 100644 --- a/camera/Camera.cc +++ b/camera/Camera.cc @@ -1,7 +1,6 @@ #include "camera/Camera.h" #include -#include #include #include @@ -181,13 +180,7 @@ bool Camera::stop() bool Camera::is_really_recording() const { - FILE* process = popen("pgrep raspivid", "r"); - char response[5]; - fgets(response, 5, process); - pclose(process); - - if (process == NULL) this->logger->log("Error checking if raspivid is really recording"); - return (process != NULL && response != NULL); + return (0 == system("pidof -x raspivid > /dev/null")); } int os::get_file_count(const string& path) From 8ac34a91f387e8054c81ad0a233d855fe049e797 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 15 Sep 2015 23:15:38 +0200 Subject: [PATCH 159/169] Beter syntax on SMS sending. --- openstratos.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 9b016f3..3d99105 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -1150,7 +1150,7 @@ void os::land(Logger* logger) this_thread::sleep_for(10min); logger->log("Sending second landed SMS..."); - while ( ! GSM::get_instance().send_SMS( + while (( ! GSM::get_instance().send_SMS( "Landed\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ @@ -1158,7 +1158,7 @@ void os::land(Logger* logger) "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE) || - ! GPS::get_instance().is_fixed() && + ! GPS::get_instance().is_fixed()) && (main_battery >= 0 || main_battery < -1) && gsm_battery >= 0) { logger->log("Error sending second SMS or GPS without fix, trying again in 5 minutes."); From 696415bcb12a2794ee11703f5f4cb8c16574bdb5 Mon Sep 17 00:00:00 2001 From: Razican Date: Tue, 15 Sep 2015 23:43:05 +0200 Subject: [PATCH 160/169] Trying to fix GSM localization. --- gsm/GSM.cc | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index a3e0fc6..ea477e0 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -236,7 +236,10 @@ bool GSM::get_location(double& latitude, double& longitude) return false; } - if (this->send_command_read("AT+SAPBR=1,1") != "OK") + this->serial->println("AT+SAPBR=1,1"); + this->serial->read_line(5); // Eat message echo + + if (this->serial->read_line(5) != "OK") { this->logger->log("Error getting location on 'AT+SAPBR=1,1' response."); if (this->send_command_read("AT+SAPBR=0,1") != "OK") @@ -248,9 +251,11 @@ bool GSM::get_location(double& latitude, double& longitude) return false; } - string response = this->send_command_read("AT+CIPGSMLOC=1,1"); - this->serial->read_line(); // Eat new line - if (response == "ERROR" || this->serial->read_line() != "OK") + this->serial->println("AT+CIPGSMLOC=1,1"); + this->serial->read_line(10); // Eat message echo + string response = this->serial->read_line(10); + this->serial->read_line(10); // Eat new line + if (response == "ERROR" || this->serial->read_line(10) != "OK") { this->logger->log("Error getting location on 'AT+CIPGSMLOC=1,1' response."); if (this->send_command_read("AT+SAPBR=0,1") != "OK") @@ -262,7 +267,10 @@ bool GSM::get_location(double& latitude, double& longitude) return false; } - if (this->send_command_read("AT+SAPBR=0,1") != "OK") + this->serial->println("AT+SAPBR=0,1"); + this->serial->read_line(5); // Eat message echo + + if (this->serial->read_line(5) != "OK") this->logger->log("Error turning GPRS down."); else this->logger->log("GPRS off."); @@ -385,19 +393,6 @@ bool GSM::turn_off() const } } -bool GSM::init_GPRS() const -{ - return (this->send_command_read("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"") == "OK" && - this->send_command_read("AT+SAPBR=3,1,\"APN\",\"" + string(GSM_LOC_SERV) + ";") == "OK" && - this->send_command_read("AT+SAPBR=1,1") == "OK" & - this->send_command_read("AT+SAPBR=2,1") == "OK"); -} - -bool GSM::tear_down_GPRS() const -{ - return this->send_command_read("AT+SAPBR=0,1") == "OK"; -} - const string GSM::send_command_read(const string& command) const { this->command_logger->log("Sent: '"+command+"'"); From fa3edda9dca5057535dd46021e27f050771cffef Mon Sep 17 00:00:00 2001 From: Razican Date: Wed, 16 Sep 2015 00:13:43 +0200 Subject: [PATCH 161/169] Fixed #58 and small recovery mode fix --- gsm/GSM.cc | 46 +++++++++++++++++++++++++++------------------- openstratos.cc | 1 + 2 files changed, 28 insertions(+), 19 deletions(-) diff --git a/gsm/GSM.cc b/gsm/GSM.cc index ea477e0..14d97fe 100644 --- a/gsm/GSM.cc +++ b/gsm/GSM.cc @@ -237,9 +237,13 @@ bool GSM::get_location(double& latitude, double& longitude) } this->serial->println("AT+SAPBR=1,1"); - this->serial->read_line(5); // Eat message echo + this->command_logger->log("Sent: 'AT+SAPBR=1,1'"); + this->serial->read_line(2); // Eat message echo - if (this->serial->read_line(5) != "OK") + string response = this->serial->read_line(); + this->command_logger->log("Received: '"+ response +"'"); + + if (response != "OK") { this->logger->log("Error getting location on 'AT+SAPBR=1,1' response."); if (this->send_command_read("AT+SAPBR=0,1") != "OK") @@ -253,9 +257,23 @@ bool GSM::get_location(double& latitude, double& longitude) this->serial->println("AT+CIPGSMLOC=1,1"); this->serial->read_line(10); // Eat message echo - string response = this->serial->read_line(10); - this->serial->read_line(10); // Eat new line - if (response == "ERROR" || this->serial->read_line(10) != "OK") + response = this->serial->read_line(); + this->command_logger->log("Received: '"+ response +"'"); + + stringstream ss(response); + string data; + vector s_data; + + // We put all fields in a vector + while(getline(ss, data, ',')) s_data.push_back(data); + + latitude = stod(s_data[2]); + longitude = stod(s_data[1]); + + this->serial->read_line(); // Eat new line + response = this->serial->read_line(); + this->command_logger->log("Received: '"+ response +"'"); + if (response == "ERROR" || response != "OK") { this->logger->log("Error getting location on 'AT+CIPGSMLOC=1,1' response."); if (this->send_command_read("AT+SAPBR=0,1") != "OK") @@ -268,25 +286,15 @@ bool GSM::get_location(double& latitude, double& longitude) } this->serial->println("AT+SAPBR=0,1"); - this->serial->read_line(5); // Eat message echo - - if (this->serial->read_line(5) != "OK") + this->serial->read_line(2); // Eat message echo + response = this->serial->read_line(); + this->command_logger->log("Received: '"+ response +"'"); + if (response != "OK") this->logger->log("Error turning GPRS down."); else this->logger->log("GPRS off."); this->occupied = false; - - stringstream ss(response); - string data; - vector s_data; - - // We put all fields in a vector - while(getline(ss, data, ',')) s_data.push_back(data); - - latitude = stod(s_data[2]); - longitude = stod(s_data[1]); - return true; } diff --git a/openstratos.cc b/openstratos.cc index 3d99105..cb689a5 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -243,6 +243,7 @@ void os::safe_mode() logger->log("Mayday messages sent."); logger->log("Initializing GPS..."); + count = 0; while ( ! GPS::get_instance().initialize() && ++count < 5) logger->log("GPS initialization error."); From 5333cbe16050972bcdb04f47d3fce9b8e0ae9260 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 19 Sep 2015 20:04:59 +0200 Subject: [PATCH 162/169] Smaall cleanups and fixes --- openstratos.cc | 8 +++++--- startup.sh | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index cb689a5..6736583 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -291,7 +291,9 @@ void os::main_while(Logger* logger, State* state) } else if (*state == FIX_ACQUIRED) { - this_thread::sleep_for(5min); // + logger->log("Sleeping 2 minutes for fix stabilization.") + this_thread::sleep_for(2min); + start_recording(logger); send_init_sms(logger); *state = set_state(WAITING_LAUNCH); @@ -422,7 +424,7 @@ void os::initialize(Logger* logger, tm* now) logger->log("Batteries checked => Main battery: "+ (main_battery > -1 ? to_string(main_battery*100)+"%" : "disconnected") + " - GSM battery: "+ to_string(gsm_battery*100) +"%"); - if ((main_battery < 0.95 && main_battery > -1) || gsm_battery < 0.95) + if ((main_battery < 0.9 && main_battery > -1) || gsm_battery < 0.85) { logger->log("Error: Not enough battery."); @@ -612,7 +614,7 @@ void os::wait_launch(Logger* logger, double& launch_altitude) this_thread::sleep_for(2min); #endif #ifdef REAL_SIM - this_thread::sleep_for(20min); + this_thread::sleep_for(10min); #endif while ( ! has_launched(launch_altitude)) diff --git a/startup.sh b/startup.sh index 1f153c0..fdfb25c 100755 --- a/startup.sh +++ b/startup.sh @@ -8,6 +8,7 @@ echo "[`date`] Starting OpenStratos..." >> /root/control.log sleep 5 while true; do - (pgrep procname && sleep 60) || - (echo "[`date`] Process not running, restarting..." >> /root/control.log; shutdown -r now) + (pgrep openstratos && sleep 60) || + (echo "[`date`] Process not running, restarting..." >> /root/control.log; + shutdown -r now; sleep 5) done From d1fdd93f193c49d2a1c4c8842862a65c6faf4836 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 19 Sep 2015 20:23:20 +0200 Subject: [PATCH 163/169] Fixed build error --- openstratos.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index 6736583..bf0ec0e 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -291,7 +291,7 @@ void os::main_while(Logger* logger, State* state) } else if (*state == FIX_ACQUIRED) { - logger->log("Sleeping 2 minutes for fix stabilization.") + logger->log("Sleeping 2 minutes for fix stabilization."); this_thread::sleep_for(2min); start_recording(logger); From d8a5d5a8102ab057156dec12e4e5642a48d3fb96 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 19 Sep 2015 21:29:22 +0200 Subject: [PATCH 164/169] Added validity check in GPS frames --- gps/GPS.cc | 2 +- openstratos.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gps/GPS.cc b/gps/GPS.cc index 4737f2c..3d14fc7 100644 --- a/gps/GPS.cc +++ b/gps/GPS.cc @@ -198,7 +198,7 @@ bool GPS::is_valid(string frame) void GPS::parse(const string& frame) { - if (frame.length() > 1) + if (frame.length() > 1 && is_valid(frame)) { this->frame_logger->log(frame); string frame_type = frame.substr(1, frame.find_first_of(',')-1); diff --git a/openstratos.cc b/openstratos.cc index bf0ec0e..1396681 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -291,8 +291,8 @@ void os::main_while(Logger* logger, State* state) } else if (*state == FIX_ACQUIRED) { - logger->log("Sleeping 2 minutes for fix stabilization."); this_thread::sleep_for(2min); + logger->log("Sleeping 2 minutes for fix stabilization."); start_recording(logger); send_init_sms(logger); From 10f5a5a7cf88d9072f5c8374de5888bd087d55fa Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 19 Sep 2015 21:53:22 +0200 Subject: [PATCH 165/169] Fixed SMSs --- openstratos.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/openstratos.cc b/openstratos.cc index 1396681..e6b95cb 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -967,7 +967,7 @@ void os::go_down(Logger* logger) (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending first SMS."); } @@ -1029,7 +1029,7 @@ void os::go_down(Logger* logger) (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending second SMS."); } @@ -1091,7 +1091,7 @@ void os::go_down(Logger* logger) (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending third SMS."); } @@ -1141,7 +1141,7 @@ void os::land(Logger* logger) (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending landed SMS. Trying again in 10 minutes..."); } @@ -1160,7 +1160,7 @@ void os::land(Logger* logger) (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "Sat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE) || + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE) || ! GPS::get_instance().is_fixed()) && (main_battery >= 0 || main_battery < -1) && gsm_battery >= 0) { From 6ba1721911a6de9d82621fa177e45d47e775b673 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 19 Sep 2015 22:09:04 +0200 Subject: [PATCH 166/169] Added double battery check on initialization --- openstratos.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index e6b95cb..375e889 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -397,7 +397,8 @@ void os::initialize(Logger* logger, tm* now) logger->log("Checking batteries..."); double main_battery, gsm_battery; - if ( ! GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + if ( ! GSM::get_instance().get_battery_status(main_battery, gsm_battery) && + ! GSM::get_instance().get_battery_status(main_battery, gsm_battery)) { logger->log("Error checking batteries."); From 557f61937ba22ca25a3cd7402ce40e6afcadb892 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 19 Sep 2015 22:34:43 +0200 Subject: [PATCH 167/169] Added second attempt in launch SMS --- openstratos.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index 375e889..612829d 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -680,7 +680,16 @@ void os::go_up(Logger* logger, double launch_altitude) (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + - "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE) && + // Second attempt + ! GSM::get_instance().send_SMS( + "Alt: "+ to_string((int) GPS::get_instance().get_altitude()) + + " m\r\nLat: "+ to_string(GPS::get_instance().get_latitude()) +"\r\n"+ + "Lon: "+ to_string(GPS::get_instance().get_longitude()) +"\r\n"+ + (bat_status ? "Main bat: "+ to_string((int) (main_battery*100)) +"%\r\n"+ + "GSM bat: "+ to_string((int) (gsm_battery*100)) +"%\r\n" : "Bat: ERR\r\n") + + "Fix: "+ (GPS::get_instance().is_fixed() ? "OK" : "ERR") + + "\r\nSat: "+ to_string(GPS::get_instance().get_satellites()), SMS_PHONE)) { logger->log("Error sending \"going up\" SMS."); } From ba1c0fd359d1a0f84c98e84408209940524bbca3 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 19 Sep 2015 23:18:13 +0200 Subject: [PATCH 168/169] Added second battery checks --- openstratos.cc | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/openstratos.cc b/openstratos.cc index 612829d..7be98ce 100644 --- a/openstratos.cc +++ b/openstratos.cc @@ -1138,7 +1138,8 @@ void os::land(Logger* logger) bool bat_status = false; logger->log("Getting battery values..."); - if (bat_status = GSM::get_instance().get_battery_status(main_battery, gsm_battery)) + if (bat_status = (GSM::get_instance().get_battery_status(main_battery, gsm_battery) || + GSM::get_instance().get_battery_status(main_battery, gsm_battery))) logger->log("Battery status received."); else logger->log("Error getting battery status."); @@ -1162,6 +1163,13 @@ void os::land(Logger* logger) this_thread::sleep_for(10min); + logger->log("Getting battery values..."); + if (bat_status = (GSM::get_instance().get_battery_status(main_battery, gsm_battery) || + GSM::get_instance().get_battery_status(main_battery, gsm_battery))) + logger->log("Battery status received."); + else + logger->log("Error getting battery status."); + logger->log("Sending second landed SMS..."); while (( ! GSM::get_instance().send_SMS( "Landed\r\nAlt: "+ to_string((int) GPS::get_instance().get_altitude()) + From 1d474cd4b7e8bd0b3de09d188dfffccb27129675 Mon Sep 17 00:00:00 2001 From: Razican Date: Sat, 26 Sep 2015 18:01:20 +0200 Subject: [PATCH 169/169] Bumped version number --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index ad87ade..d35f714 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.68]) -AC_INIT(OpenStratos, 1.0-rc1, https://github.com/OpenStratos/server/issues) +AC_INIT(OpenStratos, 1.0, https://github.com/OpenStratos/server/issues) AC_CONFIG_SRCDIR([openstratos.cc]) AM_INIT_AUTOMAKE([subdir-objects]) AC_CONFIG_HEADERS([config.h])