A **sensor node**, also known as a **mote**, is a node in a sensor network that is capable of performing some processing, gathering sensory information and communicating with other connected nodes in the network.
The main components of a sensor node are a **microcontroller**, **transceiver/Communication Module**, **memory**, **power source** and one or more **sensors.**
A basic IMU (Intertial Measurement Unit) generally provides raw sensor data, whereas an AHRS takes this data one step further, converting it into heading or direction in degrees, converting the raw altitude data into standard units like feet or meters, etc.
An attitude and heading reference system (AHRS) consists of sensors on three axes that provide attitude information for aircraft, including roll, pitch and yaw. These are sometimes referred to as MARG (Magnetic, Angular Rate, and Gravity) sensors and consist of either solid-state or microelectromechanical systems (MEMS) gyroscopes, accelerometers and magnetometers. They are designed to replace traditional mechanical gyroscopic flight instruments.
Adafruit's 10DOF https://en.wikipedia.org/wiki/Degrees_of_freedom[(10 Degrees of Freedom)] breakout board allows you to capture ten distinct types of motion or orientation related data.
- open up the Serial Monitor (Tools > Serial Monitor),
- set the baud rate to 115200
.output
image:./sensors_01_AHRSOutput.png[alt="AHRS raw data"]
This raw data shows the main orientation data, consisting of 'roll', 'pitch' and 'heading' (or 'yaw) in degrees, followed by the current altitude and temperature
The AHRS sketchs reads raw data from the board's accelerometer/magnetometer and converts the raw data into easy to understand **Euler angles.**
In this case, we can see that the **roll is about 18°**, the **pitch is about 78°** and the **heading or yaw is about 32°**, and the sketch will keep updating itself with the latest values at whatever speed we've set in the sketch.
.Euler angles, one of the possible ways to describe an orientation
image:./Eulerangles.svg.png[alt="Euler angles"]
The first attempt to represent an orientation is attributed to Leonhard Euler. He imagined three reference frames that could rotate one around the other, and realized that by starting with a fixed reference frame and performing three rotations, he could get any other reference frame in the space (using two rotations to fix the vertical axis and other to fix the other two axes). The values of these three rotations are called Euler angles.
.Tait–Bryan angles, another way to describe orientation
These are three angles, also known as yaw, pitch and roll, Navigation angles and Cardan angles. Mathematically they constitute a set of six possibilities inside the twelve possible sets of Euler angles, the ordering being the one best used for describing the orientation of a vehicle such as an airplane. In aerospace engineering they are usually referred to as Euler angles.
To visualize the data, we've put together a basic **Processing** sketch that loads a 3D model and renders it using the data generated by the AHRS sketch.
==== The tools, languages, and frameworks
===== Processing
Processing is an open-source graphical library and integrated development environment (IDE) built for the electronic arts, new media art, and visual design communities with the purpose of teaching non-programmers the fundamentals of computer programming in a visual context.
Processing uses the Java language, with additional simplifications such as additional classes and aliased mathematical functions and operations. It also provides a graphical user interface for simplifying the compilation and execution stage.
The Processing language and IDE were the precursor to other projects including Arduino, Wiring and p5.js.
===== p5.js
In 2013, Lauren McCarthy created p5.js, a native JavaScript alternative to Processing.js that has the official support of the Processing Foundation.
===== Processing.py
Python Mode for Processing, or Processing.py is a Python interface to the underlying Java toolkit. It was chiefly developed by Jonathan Feinberg starting in 2010, with contributions from James Gilles and Ben Alkov
===== Three.js
Three.js is a cross-browser JavaScript library and Application Programming Interface (API) used to create and display animated 3D computer graphics in a web browser. Three.js uses WebGL.
[NOTE]
====
**ThreeJS** is a wrapper around the browser’s native WebGL API. It’s the de facto standard 3D library — there are others, like BabylonJS, but Three is just miles more popular. The native browser APIs are… painful to work with, you can think of ThreeJS kinda like a jQuery for in-browser 3D graphics. Doesn’t give you anything that’s not already there, it just wraps it all into a user-friendly API
**P5** is not a 3d graphics library, it’s an API for doing creative coding: things like procedural generation, natural simulations etc. It has some 3D features because it wraps the native WebGL API, but that’s not it’s core purpose. It is a artistic and teaching tool — it is occasionally used in production outside of artistic audio/visual stuff, but not often. It’s basically the JS version of Processing.
====
https://www.slideshare.net/victorporof/processingjs-vs-threejs[More: Processing.js vs. three.js]
==== Requirements
- https://processing.org/[Processing 2.x]
- https://code.google.com/archive/p/saitoobjloader/#Download[OBJ Loader library for Processing]
- http://www.lagers.org.uk/g4p/[G4P GUI library for Processing]
[NOTE]
====
The OBJ library is required to load 3D models. It isn't strictly necessary and you could also render a boring cube in Processing, but why play with cubes when you have rabbits?!
====
==== Write the Processing Sketch
.Processing Sketch
[source,c]
----
import processing.serial.*;
import java.awt.datatransfer.*;
import java.awt.Toolkit;
import processing.opengl.*;
import saito.objloader.*;
import g4p_controls.*;
float roll = 0.0F;
float pitch = 0.0F;
float yaw = 0.0F;
float temp = 0.0F;
float alt = 0.0F;
OBJModel model;
// Serial port state.
Serial port;
String buffer = "";
final String serialConfigFile = "serialconfig.txt";
boolean printSerial = false;
// UI controls.
GPanel configPanel;
GDropList serialList;
GLabel serialLabel;
GCheckbox printSerialCheckbox;
void setup()
{
size(400, 500, OPENGL);
frameRate(30);
model = new OBJModel(this);
model.load("bunny.obj");
model.scale(20);
// Serial port setup.
// Grab list of serial ports and choose one that was persisted earlier or default to the first port.