added no aggregation for no activity, buffer memory swapping

This commit is contained in:
aj 2020-11-18 19:02:24 +00:00
parent da602ad67b
commit c15f893e47
9 changed files with 1689 additions and 1403 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
obj_*
*~
*~
code.pdf

197
Coursework-Reports/code.lyx Normal file
View File

@ -0,0 +1,197 @@
#LyX 2.3 created this file. For more info see http://www.lyx.org/
\lyxformat 544
\begin_document
\begin_header
\save_transient_properties true
\origin unavailable
\textclass article
\begin_preamble
\usepackage{color}
\definecolor{commentgreen}{RGB}{0,94,11}
\end_preamble
\use_default_options true
\begin_modules
customHeadersFooters
\end_modules
\maintain_unincluded_children false
\language english
\language_package default
\inputencoding auto
\fontencoding global
\font_roman "default" "default"
\font_sans "default" "default"
\font_typewriter "default" "default"
\font_math "auto" "auto"
\font_default_family default
\use_non_tex_fonts false
\font_sc false
\font_osf false
\font_sf_scale 100 100
\font_tt_scale 100 100
\use_microtype false
\use_dash_ligatures true
\graphics default
\default_output_format default
\output_sync 0
\bibtex_command default
\index_command default
\paperfontsize default
\spacing single
\use_hyperref true
\pdf_title "IoT Aggregation Algorithm Coursework"
\pdf_author "Andy Pack"
\pdf_subject "IoT"
\pdf_bookmarks true
\pdf_bookmarksnumbered false
\pdf_bookmarksopen false
\pdf_bookmarksopenlevel 1
\pdf_breaklinks true
\pdf_pdfborder true
\pdf_colorlinks false
\pdf_backref false
\pdf_pdfusetitle true
\papersize default
\use_geometry true
\use_package amsmath 1
\use_package amssymb 1
\use_package cancel 1
\use_package esint 1
\use_package mathdots 1
\use_package mathtools 1
\use_package mhchem 1
\use_package stackrel 1
\use_package stmaryrd 1
\use_package undertilde 1
\cite_engine basic
\cite_engine_type default
\biblio_style plain
\use_bibtopic false
\use_indices false
\paperorientation portrait
\suppress_date false
\justification true
\use_refstyle 1
\use_minted 0
\index Index
\shortcut idx
\color #008000
\end_index
\leftmargin 1cm
\topmargin 1.5cm
\rightmargin 1cm
\bottommargin 1.5cm
\secnumdepth 3
\tocdepth 3
\paragraph_separation indent
\paragraph_indentation default
\is_math_indent 0
\math_numbering_side default
\quotes_style english
\dynamic_quotes 0
\papercolumns 1
\papersides 1
\paperpagestyle fancy
\tracking_changes false
\output_changes false
\html_math_output 0
\html_css_as_file 0
\html_be_strict false
\end_header
\begin_body
\begin_layout Left Header
IoT Aggregation Algorithm Coursework
\end_layout
\begin_layout Left Footer
November 2020
\end_layout
\begin_layout Right Footer
Andy Pack / 6420013
\end_layout
\begin_layout Standard
\begin_inset CommandInset toc
LatexCommand lstlistoflistings
\end_inset
\begin_inset CommandInset include
LatexCommand lstinputlisting
filename "../Coursework/coursework.c"
lstparams "breaklines=true,frame=tb,language=C,basicstyle={\\ttfamily},commentstyle={\\color{commentgreen}\\itshape},keywordstyle={\\color{blue}},emphstyle={\\color{red}},stringstyle={\\color{red}},identifierstyle={\\color{cyan}},caption={Main coursework program: 2 processes for reading and aggregating data}"
\end_inset
\end_layout
\begin_layout Standard
\begin_inset Newpage pagebreak
\end_inset
\end_layout
\begin_layout Standard
\begin_inset CommandInset include
LatexCommand lstinputlisting
filename "../Coursework/buffer.h"
lstparams "breaklines=true,frame=tb,language=C,basicstyle={\\ttfamily},commentstyle={\\color{commentgreen}\\itshape},keywordstyle={\\color{blue}},emphstyle={\\color{red}},stringstyle={\\color{red}},identifierstyle={\\color{cyan}},caption={Buffer header file: get, free and manipulate buffers}"
\end_inset
\begin_inset Newpage pagebreak
\end_inset
\end_layout
\begin_layout Standard
\begin_inset CommandInset include
LatexCommand lstinputlisting
filename "../Coursework/math.h"
lstparams "breaklines=true,frame=tb,language=C,basicstyle={\\ttfamily},commentstyle={\\color{commentgreen}\\itshape},keywordstyle={\\color{blue}},emphstyle={\\color{red}},stringstyle={\\color{red}},identifierstyle={\\color{cyan}},caption={Math header file: mean, standard deviation, implementations of ceil, sqrt}"
\end_inset
\begin_inset Newpage pagebreak
\end_inset
\end_layout
\begin_layout Standard
\begin_inset CommandInset include
LatexCommand lstinputlisting
filename "../Coursework/io.h"
lstparams "breaklines=true,frame=tb,language=C,basicstyle={\\ttfamily},commentstyle={\\color{commentgreen}\\itshape},keywordstyle={\\color{blue}},emphstyle={\\color{red}},stringstyle={\\color{red}},identifierstyle={\\color{cyan}},caption={IO header file: init function for starting sensors}"
\end_inset
\begin_inset Newpage pagebreak
\end_inset
\end_layout
\begin_layout Standard
\begin_inset CommandInset include
LatexCommand lstinputlisting
filename "../Coursework/util.h"
lstparams "breaklines=true,frame=tb,language=C,basicstyle={\\ttfamily},commentstyle={\\color{commentgreen}\\itshape},keywordstyle={\\color{blue}},emphstyle={\\color{red}},stringstyle={\\color{red}},identifierstyle={\\color{cyan}},caption={Other utilities: short and float printing functions from earlier labs}"
\end_inset
\end_layout
\end_body
\end_document

View File

@ -11,20 +11,38 @@ typedef struct Buffer {
} Buffer;
Buffer
getBuffer(int size)
getBuffer(int size) // retrieve new buffer with malloc-ed memory space
{
float* memSpace = (float*) malloc(size * sizeof(float));
Buffer buffer = {memSpace, size, };
return buffer;
}
void
void
freeBuffer(Buffer buffer) // little abstraction function to act as buffer destructor
{
free(buffer.items);
}
void
swapBufferMemory(Buffer *first, Buffer *second) // swap memspaces between buffers
{
float* firstItems = first->items; // swap input buffer and output buffer item pointers
first->items = second->items;
second->items = firstItems;
int firstLength = first->length; // swap lengths to iterate correctly
first->length = second->length;
second->length = firstLength;
}
void // perform aggregation into groupSize (4 in the spec)
aggregateBuffer(Buffer bufferIn, Buffer bufferOut, int groupSize)
{
int requiredGroups = ceil((float)bufferIn.length/groupSize); // number of groups
int finalGroupSize = (bufferIn.length % groupSize) * groupSize;
int finalGroupSize = (bufferIn.length % groupSize) * groupSize; // work out length of final group if bufferIn not of length that divides nicely
if(requiredGroups > bufferOut.length) // error
if(requiredGroups > bufferOut.length) // error check
{
putFloat((float)bufferIn.length/groupSize);
printf(" length out buffer required, %i provided\n", bufferOut.length);
@ -39,9 +57,9 @@ aggregateBuffer(Buffer bufferIn, Buffer bufferOut, int groupSize)
int length = groupSize; // length of this group's size
if(g == requiredGroups - 1 && finalGroupSize != 0) length = finalGroupSize; // shorten if necessary
*outputPtr = calculateMean(inputPtr, length); // SET
*outputPtr = calculateMean(inputPtr, length); // SET OUTPUT VALUE
inputPtr += length; // increment both
inputPtr += length; // increment both cursors
outputPtr++;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -64,8 +64,8 @@
<width>321</width>
<z>0</z>
<height>160</height>
<location_x>48</location_x>
<location_y>710</location_y>
<location_x>51</location_x>
<location_y>875</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.Visualizer
@ -74,7 +74,7 @@
<viewport>0.9090909090909091 0.0 0.0 0.9090909090909091 153.72871631902638 172.41033658502872</viewport>
</plugin_config>
<width>314</width>
<z>5</z>
<z>6</z>
<height>179</height>
<location_x>40</location_x>
<location_y>20</location_y>
@ -90,7 +90,7 @@
<zoomfactor>500.0</zoomfactor>
</plugin_config>
<width>1217</width>
<z>4</z>
<z>5</z>
<height>183</height>
<location_x>424</location_x>
<location_y>852</location_y>
@ -102,7 +102,7 @@
<decorations>true</decorations>
</plugin_config>
<width>6</width>
<z>6</z>
<z>7</z>
<height>160</height>
<location_x>680</location_x>
<location_y>0</location_y>
@ -127,11 +127,11 @@
<interface>Temperature and Light</interface>
<scrollpos>0,0</scrollpos>
</plugin_config>
<width>397</width>
<width>340</width>
<z>1</z>
<height>179</height>
<location_x>2</location_x>
<location_y>247</location_y>
<location_x>28</location_x>
<location_y>227</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.MoteInterfaceViewer
@ -141,10 +141,23 @@
<scrollpos>0,0</scrollpos>
</plugin_config>
<width>317</width>
<z>2</z>
<z>4</z>
<height>206</height>
<location_x>28</location_x>
<location_y>445</location_y>
</plugin>
<plugin>
se.sics.cooja.plugins.MoteInterfaceViewer
<mote_arg>0</mote_arg>
<plugin_config>
<interface>Button</interface>
<scrollpos>0,0</scrollpos>
</plugin_config>
<width>296</width>
<z>2</z>
<height>115</height>
<location_x>54</location_x>
<location_y>699</location_y>
</plugin>
</simconf>

View File

@ -1,12 +1,17 @@
#define READING_INTERVAL 3 //in Hz
#define BUFFER_SIZE 9 // length of buffer to populate
#define READING_INTERVAL 2 //in Hz
#define BUFFER_SIZE 12 // length of buffer to populate
#define SD_THRESHOLD 300 // whether to aggregate or flatten
#define AGGREGATION_GROUP_SIZE 3 // group size to aggregate (4 in spec)
#define SD_THRESHOLD_SOME 400 // some activity, compress above, flatten below
#define SD_THRESHOLD_LOTS 1000 // lots of activity, don't aggregate
#define AGGREGATION_GROUP_SIZE 4 // group size to aggregate (4 in spec)
#define INITIAL_STATE true // whether begins running or not
#include "contiki.h"
#include <stdio.h> /* For printf() */
#include <stdbool.h>
#include "io.h"
#include "util.h" // for print methods
@ -16,50 +21,72 @@
static process_event_t event_buffer_full;
/*---------------------------------------------------------------------------*/
PROCESS(sensing_process, "Sensing process");
PROCESS(aggregator_process, "Aggregator process");
PROCESS(sensing_process, "Sensing process"); // collect data
PROCESS(aggregator_process, "Aggregator process"); // receive full data buffers for processing
AUTOSTART_PROCESSES(&sensing_process, &aggregator_process);
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(sensing_process, ev, data)
{
/*INIT*/
static struct etimer timer;
PROCESS_BEGIN();
event_buffer_full = process_alloc_event();
static struct etimer timer;
etimer_set(&timer, CLOCK_SECOND/READING_INTERVAL);
SENSORS_ACTIVATE(light_sensor);
leds_off(LEDS_ALL);
event_buffer_full = process_alloc_event();
initIO();
static bool isRunning = INITIAL_STATE;
static Buffer buffer;
buffer = getBuffer(BUFFER_SIZE);
clearBuffer(buffer);
printBuffer(buffer);putchar('\n');putchar('\n');
/*END INIT*/
static int counter = 0;
while(1)
{
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
leds_off(LEDS_RED);
PROCESS_WAIT_EVENT();
float light_lx = getLight(); // GET
if (ev == PROCESS_EVENT_TIMER){
if (isRunning == true) {
leds_off(LEDS_RED);
float light_lx = getLight(); // GET
buffer.items[counter] = light_lx; // STORE
printf("%2i/%i: ", counter + 1, buffer.length);putFloat(light_lx);putchar('\n'); // DISPLAY VALUE
//printBuffer(buffer, BUFFER_SIZE);putchar('\n'); // DISPLAY CURRENT BUFFER
counter++;
if(counter == buffer.length) // CHECK WHETHER FULL
{
process_post(&aggregator_process, event_buffer_full, &buffer);
counter = 0;
buffer = getBuffer(BUFFER_SIZE);
buffer.items[counter] = light_lx; // STORE
printf("%2i/%i: ", counter + 1, buffer.length);putFloat(light_lx);putchar('\n'); // DISPLAY CURRENT VALUE
//printBuffer(buffer);putchar('\n'); // DISPLAY CURRENT BUFFER
counter++;
if(counter == buffer.length) // CHECK WHETHER FULL
{
process_post(&aggregator_process, event_buffer_full, &buffer); // pass buffer to processing thread
counter = 0;
buffer = getBuffer(BUFFER_SIZE); // get new buffer for next data, no freeing in this thread
}
}
etimer_reset(&timer);
}
/* BUTTON CLICKED */
else if (ev == sensors_event && data == &button_sensor)
{
isRunning = !isRunning;
if (isRunning == true)
{
printf("Starting...\n");
}
else
{
printf("Stopping, clearing buffer...\n");
//freeBuffer(buffer);
//buffer = getBuffer(BUFFER_SIZE);
counter = 0; // just reset counter, used as index on buffer items, will overwrite
}
}
etimer_reset(&timer);
}
PROCESS_END();
@ -76,8 +103,8 @@ PROCESS_THREAD(aggregator_process, ev, data)
Buffer fullBuffer = *(Buffer *)data;
/*********************/
handleBufferRotation(fullBuffer);
free(fullBuffer.items);
handleBufferRotation(&fullBuffer); // pass by reference, edited if lots of activity
freeBuffer(fullBuffer);
/*********************/
}
@ -86,26 +113,41 @@ PROCESS_THREAD(aggregator_process, ev, data)
/*---------------------------------------------------------------------------*/
// Buffer filled with readings, process and aggregate
void
handleBufferRotation(Buffer inBuffer)
handleBufferRotation(Buffer *inBufferPtr)
{
printf("Buffer full, aggregating\n\n");
Buffer inBuffer = *inBufferPtr;
Buffer outBuffer; // OUTPUT BUFFER HOLDER
// above pointer is assigned a buffer in either of the below cases
Stats sd = calculateStdDev(inBuffer.items, inBuffer.length); // GET BUFFER STATISTICS
if(sd.std > SD_THRESHOLD)
{// buffer length by 4
printf("Significant STD: ");putFloat(sd.std);printf(", compressing buffer\n");
/* LOTS OF ACTIVITY - LEAVE */
if(sd.std > SD_THRESHOLD_LOTS)
{
printf("Lots of activity, std. dev.: ");putFloat(sd.std);printf(", leaving as-is\n");
outBuffer = getBuffer(1); // get a dummy buffer, will swap items for efficiency
swapBufferMemory(inBufferPtr, &outBuffer); // ensures both are freed but no need to copy items
}
/* SOME ACTIVITY - AGGREGATE */
else if(sd.std > SD_THRESHOLD_SOME)
{
printf("Some activity, std. dev.: ");putFloat(sd.std);printf(", compressing buffer\n");
int outLength = ceil((float)inBuffer.length/AGGREGATION_GROUP_SIZE); // CALCULATE NUMBER OF OUTPUT ELEMENTS
outBuffer = getBuffer(outLength); // CREATE OUTPUT BUFFER
aggregateBuffer(inBuffer, outBuffer, AGGREGATION_GROUP_SIZE);
}else
{// buffer length to 1
printf("Insignificant STD: ");putFloat(sd.std);printf(", squashing buffer\n");
}
/* NO ACTIVITY - FLATTEN */
else
{
printf("Insignificant std. dev.: ");putFloat(sd.std);printf(", squashing buffer\n");
outBuffer = getBuffer(1); // CREATE OUTPUT BUFFER
outBuffer.items[0] = sd.mean;
@ -114,7 +156,7 @@ handleBufferRotation(Buffer inBuffer)
/*********************/
handleFinalBuffer(outBuffer); // PASS FINAL BUFFER
free(outBuffer.items); // RELEASE ITEMS
freeBuffer(outBuffer); // RELEASE ITEMS
/*********************/
}

Binary file not shown.

View File

@ -2,8 +2,17 @@
#define _IO_GUARD
#include "dev/light-sensor.h"
#include "dev/button-sensor.h"
#include "dev/leds.h"
void
initIO()
{
SENSORS_ACTIVATE(light_sensor);
SENSORS_ACTIVATE(button_sensor);
leds_off(LEDS_ALL);
}
// get float from light sensor including transfer function
float
getLight(void)

View File

@ -36,7 +36,8 @@ calculateMean(float buffer[], int length)
printf("%i items is not valid length\n", length);
return 0;
}
/* SUM */
float sum = 0;
int i;
for(i = 0; i < length; i++)
@ -44,7 +45,7 @@ calculateMean(float buffer[], int length)
sum += buffer[i];
}
return sum / length;
return sum / length; // DIVIDE ON RETURN
}
Stats
@ -63,8 +64,8 @@ calculateStdDev(float buffer[], int length)
int i;
for(i = 0; i < length; i++)
{
float diffFromMean = buffer[i] - stats.mean;
sum += diffFromMean*diffFromMean;
float diffFromMean = buffer[i] - stats.mean; // (xi - mu)
sum += diffFromMean*diffFromMean; // Sum(diff squared)
}
stats.std = sqrt(sum/length);