DISCLAIMER - This repository and its contents are not endorsed by, sponsored by, affiliated with, nor associated with the National Aeronautics and Space Administration (NASA). This repository is only a demonstration of some of the concepts that I explored while I was an intern at NASA's Langley Research Center.
While I was an intern at NASA, I noticed a lot of interest in "smart" technologies, e.g., "Edge" computing and Internet of Things (IoT) devices; augmented and virtual reality; machine learning; etc.
Since there's no MicroCenter or Home Depot in space (and space delivery is not included in Amazon Prime), one of the things I thought about was a portable, customizable, plug-and-play data analyzer, aka a smart sensor suite (S3). For less than $100, the S3, with a set of basic sensors, could replace the following devices:
- Gas Detector (O2, LEL, CO-H2S, NH3, NO2): $2571.91
- Light Meter $94.95
- Sound Level Meter: $76.68
- Temperature and Humidity Meter: $19.99
- Universal Remote Control: $9.99
In addition, users could add or create ad hoc sensors and actuators from simple components using wires, resistors, breadboards, etc. As a bonus, the S3 could communicate over Bluetooth, RF, and Wi-Fi wireless networks.
This device would also use machine learning, as well as rule-based, conditional logic, to analyze data on the "edge" and act on the results through actuators. This system would complement or replace rule-based, conditional logic systems, such as engine control units (i.e., ECU's, which use lookup tables), electronic flight control systems (i.e., EFCS's, which use flight control laws), heating, ventilation, and air conditioning (HVAC) control systems (which use target states), etc.
In this demo, we will create a device that collects and analyzes environmental data to determine if the thermal comfort level of a room complies with the American Society of Heating, Refrigerating and Air-Conditioning Engineers (ASHRAE) Standard 55-2017. This standard helps engineers design effective HVAC systems.
As a bonus, we will demonstrate how to collect and process data over-the-air (OTA) from satellite devices using the S3.
For this demo, we used:
- One (1) Raspberry Pi 3 Model B+ with 5V/2.5A power source as the S3
- One (1) GrovePi+ HAT (hardware attached on top) add-on board
- One (1) temperature and humidity sensor with a Grove connector (we used a simple DHT11)
- One (1) red and one (1) green LED's with Grove connectors
- One (1) 16 x 2 LCD RGB Backlight with Grove connector
- Four (4) 4-wire cables with four-pin female-to-female Grove connectors
This is not the only configuration the S3 can use; for our bonus demo, instead of connected sensors, the S3 uses a remote Raspberry Pi Zero W with a Waveshare Sense HAT (B).
- Features (aka the x's, input variable names) - The names of each value in a vector of values (e.g., temperature, humidity, etc.). Together, they imply a relationship (e.g., hot or cold, etc.).
- Labels (aka the y's, classes, targets, output variable names) - The name of the relationship between the values (e.g., hot or cold, etc.).
- Weights (aka the thetas) - The actual values in the vector of features (e.g., 37 deg C, 100%, etc.).
- Dataset - The collection of all the feature weights and label values.
- Classifier - An algorithm that tries to predict the relationship between features from unlabeled data.
- Model - An algorithm that accounts for the relationship between features and the correct label.
- The application loads and parses the dataset and tests all classifiers against the dataset.
- The application creates a model using the highest scoring classifier.
- The application then requests data from the sensors.
- The application runs the data against the model using the selected classifier.
- The application returns the results:
- If the result is "Neutral", it complies with ASHRAE Standard 55-2017. The application displays the data on its LCD screen and indicates compliance by lighting a green LED. The application can also forward this data to a supervisory control and data acquisition (SCADA) system via JSON.
- If the result is anything but "Neutral"), it does NOT comply with ASHRAE Standard 55-2017. The application displays the data on its LCD screen and indicates non-compliance by lighting a red LED. The application can also forward this data to a supervisory control and data acquisition (SCADA) system via JSON and/or adjust the HVAC system autonomously.
- The application repeats steps 3 through 7 until it is shut off.
For this demo, we will only measure operative temperature and relative humidity. However, the S3 can also process atmospheric pressure, air speed, metabolic rate, and the insulating effects of clothing level, to predict if the occupants will feel cold, cool, slightly cool, neutral, slightly warm, warm, or hot.
atmo_pres | air_speed | rel_humid | meta_rate | cloth_lvl | oper_temp | sens_desc |
---|---|---|---|---|---|---|
1013.25 | 0.1 | 50.0 | 1.0 | 0.61 | 23.0 | 2 |
1013.25 | 0.1 | 60.0 | 1.0 | 0.61 | 26.0 | 3 |
1013.25 | 0.1 | 70.0 | 1.0 | 0.61 | 28.0 | 4 |
While this task would be easy to accomplish with simple if-else-then program, we also wanted to demonstrate the capabilities of machine learning.
-
Install Raspbian for Robots on an SD card for the Raspberry Pi by following the instructions at https://www.dexterindustries.com/howto/install-raspbian-for-robots-image-on-an-sd-card/ to install Dexter Industries' version of Raspbian on your Raspberry Pi.
-
Set up the Raspberry Pi with the GrovePi HAT:
-
Follow the instructions at https://www.dexterindustries.com/GrovePi/get-started-with-the-grovepi/ to set up and update your system:
- For Step 2, use the custom software you installed on your card earlier.
- For Step 3, use "pi" for the username and "robots1234" for the password.
- For Step 4, don't forget to execute the DI Software Update, as well update and upgrade your software.
-
If you prefer to SSH, follow these instructions instead: https://www.dexterindustries.com/GrovePi/get-started-with-the-grovepi/setting-software/.
-
-
Increase the Raspberry Pi's swap file size to 1024 MB:
-
Input the following to stop the swapfile manager:
sudo /etc/init.d/dphys-swapfile stop
-
Input the following to open the swap file configuration:
sudo nano /etc/dphys-swapfile
-
Change CONF_SWAPSIZE=100 to CONF_SWAPSIZE=1024 and save (CTRLO, then CTRLX). Input the following to restart the swapfile manager:
sudo /etc/init.d/dphys-swapfile start
-
Reboot your Raspberry Pi.
-
-
Using the terminal, clone the Smart Sensor repository. By the way, since some of the scripts require elevated privileges (e.g., writing to a file, using the communications server, etc.), you will have to install all modules and packages using sudo or you will get a "Permission Denied" error:
pi@dex:~ $ sudo git clone https://github.com/garciart/SmartSensor # Clone the repository pi@dex:~ $ sudo chown -R pi:pi SmartSensor # If logged in as pi, assume ownership of all files in case you have to edit a script pi@dex:~ $ cd SmartSensor pi@dex:~ $ sudo chmod +x permissions.sh pi@dex:~ $ sudo ./permissions.sh # Make the scripts executable
-
Install the required dependencies:
-
Instead of a requirements.txt file, we created a shell script to install or update the dependencies:
pi@dex:~/SmartSensor $ sudo chmod +x setup.sh pi@dex:~/SmartSensor $ sudo ./setup.sh
-
Feel free to view the
setup.sh
script to get more information about the dependencies. To run the scripts, you will need to use Python 3. If you are using Python 3.5, that's ok. These scripts will run on Python 3.5 and higher. Also note that we use the newer Advanced Packaging Tool (APT) instead of apt-get. -
While we tried to ensure the shell script is correct, if you run into an issue, install the problem package separately, and then re-run
setup.sh
. If you have more problems, feel free to contact us at [email protected].
-
-
Our next step is to test the sensors:
-
Connect them as follows:
- DHT (11 or 22) to digital port 7 on the Grove Pi HAT
- RGB LCD to I2C port 2 on the Grove Pi HAT
- Green LED to digital port 5 on the Grove Pi HAT
- Red LED to digital port 6 on the Grove Pi HAT
- Once they are connected, run the following command:
pi@dex:~ /SmartSensor $ cd s3_scripts pi@dex:~ /SmartSensor/s3_scripts $ ./sensors_test.py
- We should see results similar to the following, but with different values for temperature and humidity:
pi@dex:~ /SmartSensor/s3_scripts $ Temperature: 20.5C | Humidity: 30%
-
-
Once the sensor test is complete, verify scikit-learn, TensorFlow, and the sensors work (disregard any TensorFlow warnings for now). We recommend examining the code as it runs:
pi@dex:~ /SmartSensor/s3_scripts $ cd .. pi@dex:~ /SmartSensor $ cd ml_scripts pi@dex:~ /SmartSensor/ml_scripts $ ./tf_premade.py pi@dex:~ /SmartSensor/ml_scripts $ ./sl_example.py pi@dex:~ /SmartSensor/ml_scripts $ ./tf_example.py
-
Notice that the scikit-learn example (sl_example.py) ran faster (4.6 sec vs 14.4 and 13.5 sec) and was much more accurate than the TensorFlow scripts (tf_premade.py and tf_example.py). We believe this is due to the dataset having six features, but with variations in only two of those features. If you run the scripts against the Iris dataset (remove the comments surrounding the Iris test and place them around the Thermal Comfort test), the accuracy of the TensorFlow scripts increases dramatically. However, for the S3, we will use the scikit classifiers.
scikit-learn Classification Test. ... Running samples using Gradient Boosting Classifier (test score was 1.00%)... Sample #1: Prediction: Slightly Cool (expected Slightly Cool) Sample #2: Prediction: Neutral (expected Neutral) Sample #3: Prediction: Slightly Warm (expected Slightly Warm) Running samples using Random Forest Classifier (test score was 1.00%)... Sample #1: Prediction: Slightly Cool (expected Slightly Cool) Sample #2: Prediction: Neutral (expected Neutral) Sample #3: Prediction: Slightly Warm (expected Slightly Warm) ... Elapsed time: 4.682486534118652 seconds. Job complete. Have an excellent day.
TensorFlow Classification Test using Premade Estimators. ... Prediction is "Slightly Cool" (32.4%), expected "Slightly Cool" Prediction is "Warm" (51.3%), expected "Neutral" Prediction is "Warm" (85.8%), expected "Slightly Warm" Elapsed time: 14.417850971221924 seconds. Job complete. Have an excellent day.
TensorFlow Classification Test using Keras. ... X=[1013.25 0.1 50. 1. 0.61 23. ], Predicted: Cool (1), Expected Slightly Cool X=[1013.25 0.1 60. 1. 0.61 26. ], Predicted: Cool (1), Expected Neutral X=[1013.25 0.1 76. 1. 0.61 28. ], Predicted: Cool (1), Expected Slightly Warm Elapsed time: 13.566766738891602 seconds. Job complete. Have an excellent day.
-
Finally, we'll put everything together in smart_sensor.py:
-
Test the Sensors (Optional) - First, we will make sure all the sensors and actuators work. In our case, the sensor is the DHT-11, and the actuators are the two LEDs, and the RGB LCD (which started crapping out on us). For production, you may remove this code if you like.
-
Prepare the Model: Next, we will train all the classifiers as we did in sl_example.py. We will then pick the most accurate classifier for our model and retrain it against the whole data set. You will not get the same classifier all the time; during our test runs, we used the Extra Trees, the Gradient Boosting, and the Random Forest classifiers.
-
Check the Model (Optional): This is another optional step; We will check the accuracy of the selected model against some sample data. By the way, even though the data is unlabeled, we know what the resulting predictions should be. Once again, for production, you may remove this code if you like.
-
Collect Sensor Data: This is GrovePi specific code. We collect three samples of temperature and humidity from the DHT sensor, reformat it into a list of tuples, and send it for processing.
-
Process Sensor Data: Here, we run the collected data against the selected model. We collect the results, average them together, and make a determination of the conditions in the room based on the ASHRAE 7-point scale for thermal comfort.
-
Shutdown: Finally, we shut down the sensors and actuators to extend their working life.
-
Here are the results of a sample run:
pi@dex:~ /SmartSensor/ml_scripts $ cd .. pi@dex:~ /SmartSensor $ cd s3_scripts pi@dex:~ /SmartSensor/s3_scripts $ ./smart_sensor.py Smart Sensor Application. Testing sensors... Temperature: 22.0C | Humidity: 45.0% Temperature: 22.0C | Humidity: 44.0% Temperature: 22.0C | Humidity: 44.0% Test complete. Training and testing model... Model selected: Extra Trees Classifier (1.00%). Training and testing model complete. Elapsed time: 15.283817291259766 seconds. Checking model against unlabeled data... Data to be evaluated: Sample #1: [[1013.25, 0.1, 50.0, 1.0, 0.61, 23.0]] = Slightly Cool Sample #2: [[1013.25, 0.1, 60.0, 1.0, 0.61, 26.0]] = Neutral Sample #3: [[1013.25, 0.1, 76.0, 1.0, 0.61, 28.0]] = Slightly Warm Prediction(s): Sample #1: Prediction: Slightly Cool (expected Slightly Cool) Sample #2: Prediction: Neutral (expected Neutral) Sample #3: Prediction: Slightly Warm (expected Slightly Warm) Collecting sensor data... Sample #1 collected: [[1013.25, 0.1, 44.0, 1.0, 0.61, 22.0]] Sample #2 collected: [[1013.25, 0.1, 44.0, 1.0, 0.61, 22.0]] Sample #3 collected: [[1013.25, 0.1, 44.0, 1.0, 0.61, 22.0]] Collection complete. Processing sensor data... Sensor data #1: Prediction: Slightly Cool Sensor data #2: Prediction: Slightly Cool Sensor data #3: Prediction: Slightly Cool Overall sensation: 2 (Slightly Cool) Shutting down board... Job complete. Have an excellent day. pi@dex:~ /SmartSensor/s3_scripts $
-
Data verified using the Thermal Comfort Tool from the Center for the Built Environment (CBE) at the University of California, Berkeley.
- Atmospheric Pressure(atmo_pres)
- Air Speed (air_speed)
- Relative Humidity (rel_humid)
- Metabolic Rate (meta_rate)
- Clothing Level (cloth_lvl)
- Operative Temperature (oper_temp)
- Label: Sensation (sens_desc)
- Label descriptions and value
- Cold (0)
- Cool (1)
- Slightly Cool (2)
- Neutral (3)
- Slightly Warm (4)
- Warm (5)
- Hot (6)
Like we stated earlier, for extra credit, we will demonstrate how to collect and process data over-the-air (OTA) from satellite devices using the S3 and a remote Raspberry Pi Zero W with a Waveshare Sense HAT (B). The Sense HAT is much more accurate than our DHT-11 and also provides us with barometric pressure readings.
You do not have to use our setup. You can use different combinations of devices, such as an ESP32, an ESP8226, a DHT-22, an M5StickC with an M5Stack sensor, etc. If you are going to use the Sense HAT (B), you need to install the BCM2835 library. For instructions, check out https://www.waveshare.com/wiki/Sense_HAT_(B)
-
Turn on both the Raspberry Pi 3 Model B+ and the Pi Zero W.
Note - By the way, for this demo, you do not need the GrovePi HAT or the GrovePi code. We just like the lights (and the board we printed out on our Ender 3. Thanks, Chris Cirone at https://www.thingiverse.com/thing:2161971!)
-
Make and test the connection:
-
Once they are started, make sure sock_test_server.py is on the S3 and sock_test_client.py on the Pi Zero.
-
Get the IP address of each device (while there are many ways of doing this, we found the easiest way was to execute "hostname -I" at the command line)
-
Open both scripts and replace the HOST value with the IP address of the device (leave PORT 333 the same, unless you are already using it).
-
Test the connection by running sock_test_server.py on the S3 first, and then running sock_test_client.py on the Pi Zero (you may have to use sudo to run the scripts). You should get results similar to the following:
- S3:
pi@dex:~ /SmartSensor/s3_scripts $ sudo ./sock_test_server.py Waiting for data... Received 'Hello, friend.' from client! Waiting for data... Received 'Hello, friend.' from client! Waiting for data... Received 'Good-bye!' from client! The client has signed off. pi@dex:~ /SmartSensor/s3_scripts $
- Pi Zero W:
pi@raspberrypi:~ /SmartSensor $ sudo ./sock_test_client.py Sending data... Received 'Hello back!' from server! Sending data... Received 'Hello back!' from server! Sending data... Received 'Good-bye!' from server! Signing off: Good-bye. pi@raspberrypi:~ /SmartSensor $
-
-
Get some data and process it using scikit-learn. Remember, it selects the best model after training, so your results may not be the same as ours:
- S3:
pi@dex:~ /SmartSensor/s3_scripts $ sudo ./smart_sensor_server.py Starting Smart Sensor Server... Training and testing model... Model selected: Random Forest Classifier (1.00%). Training and testing model complete. Elapsed time: 16.272276639938354 seconds. Checking model against unlabeled data... Data to be evaluated: Sample #1: [[1013.25, 0.1, 50.0, 1.0, 0.61, 23.0]] = Slightly Cool Sample #2: [[1013.25, 0.1, 60.0, 1.0, 0.61, 26.0]] = Neutral Sample #3: [[1013.25, 0.1, 76.0, 1.0, 0.61, 28.0]] = Slightly Warm Prediction(s): Sample #1: Prediction: Slightly Cool (expected Slightly Cool) Sample #2: Prediction: Neutral (expected Neutral) Sample #3: Prediction: Slightly Warm (expected Slightly Warm) Waiting for sensor data... Received [[[1031.76, 0.1, 36.83, 1.0, 0.61, 24.65]], [[1031.53, 0.1, 36.81, 1.0, 0.61, 24.65]], [[1031.57, 0.1, 36.83, 1.0, 0.61, 24.66]]] from client! Collection complete. Processing sensor data... Sensor data #1: Prediction: Neutral Sensor data #2: Prediction: Neutral Sensor data #3: Prediction: Neutral Overall sensation: 3 (Neutral) Waiting for sensor data... Received [[[1031.53, 0.1, 36.59, 1.0, 0.61, 24.68]], [[1031.55, 0.1, 36.59, 1.0, 0.61, 24.71]], [[1031.54, 0.1, 36.58, 1.0, 0.61, 24.68]]] from client! Collection complete. Processing sensor data... Sensor data #1: Prediction: Neutral Sensor data #2: Prediction: Neutral Sensor data #3: Prediction: Neutral Overall sensation: 3 (Neutral) Waiting for sensor data... Received [[[1031.57, 0.1, 36.73, 1.0, 0.61, 24.79]], [[1031.52, 0.1, 36.73, 1.0, 0.61, 24.76]], [[1031.51, 0.1, 36.72, 1.0, 0.61, 24.79]]] from client! Collection complete. Processing sensor data... Sensor data #1: Prediction: Neutral Sensor data #2: Prediction: Neutral Sensor data #3: Prediction: Neutral Overall sensation: 3 (Neutral) Shutting down board... Job complete. Have an excellent day. pi@dex:~/SmartSensor/s3_scripts $
- Pi Zero W:
pi@raspberrypi:~ /SmartSensor $ sudo ./smart_sensor_client.py Starting Smart Sensor Client... Collecting atmospheric pressure, temperature, and relative humidity... Sample #1 collected: [[1031.76, 0.1, 36.83, 1.0, 0.61, 24.65]] Sample #2 collected: [[1031.53, 0.1, 36.81, 1.0, 0.61, 24.65]] Sample #3 collected: [[1031.57, 0.1, 36.83, 1.0, 0.61, 24.66]]] Sending data... Received command for 30 second delay from server. Collecting atmospheric pressure, temperature, and relative humidity... Sample #1 collected: [[1031.53, 0.1, 36.59, 1.0, 0.61, 24.68]] Sample #2 collected: [[1031.55, 0.1, 36.59, 1.0, 0.61, 24.71]] Sample #3 collected: [[1031.54, 0.1, 36.58, 1.0, 0.61, 24.68]] Sending data... Received command for 30 second delay from server. Collecting atmospheric pressure, temperature, and relative humidity... Sample #1 collected: [[1031.57, 0.1, 36.73, 1.0, 0.61, 24.79]] Sample #2 collected: [[1031.52, 0.1, 36.73, 1.0, 0.61, 24.76]] Sample #3 collected: [[1031.51, 0.1, 36.72, 1.0, 0.61, 24.79]] Sending data... Shutting down client. Good-bye. pi@raspberrypi:~ /SmartSensor $
And that's it! Remember, you do not have to use our setup to create a socket server and client. Good luck!
-
ASHRAE. (2017). ANSI/ASHRAE standard 55-2017; Thermal environmental conditions for human occupancy (55). Atlanta, GA: Author.
-
Engineering ToolBox. (2004). Illuminance - recommended light level. Retrieved February 18, 2020, from https://www.engineeringtoolbox.com/light-level-rooms-d_708.html
-
Guenther, S. (2019, November 7). What Is PMV? What Is PPD? The basics of thermal comfort. Retrieved from https://www.simscale.com/blog/2019/09/what-is-pmv-ppd/
-
Hoyt, T., Schiavon, S., Tartarini, F., Cheung, T., Steinfeld, K., Piccioli, A., & Moon, D. (2019). CBE Thermal Comfort Tool. Retrieved from https://comfort.cbe.berkeley.edu/ Center for the Built Environment, University of California Berkeley