Skip to content

Commit

Permalink
Merge remote-tracking branch 'refs/remotes/origin/30-system-implement…
Browse files Browse the repository at this point in the history
…-ride-task' into 30-system-implement-ride-task
  • Loading branch information
charliekush committed Aug 27, 2024
2 parents 48db040 + c72bbd7 commit c15530d
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 27 deletions.
Binary file added docs/control_flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 29 additions & 0 deletions docs/control_flow.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
@startuml
start

:get lowest priority task;
repeat :get proposed task run time;
if (clock) is (>run Time) then
:delay exists, set delay and set proposed run time to clock (try running task now);
else (no delay exists, set delay to 0)
endif

:Task Finish Time =Proposed Run Time + Task Duration;
while (there are higher priority tasks left to check && no conflicts exist)
if (Task Finish Time conflicts with Higher Priority Task Run Time) then
:conflict exists;
endif

endwhile;

if (if no conflict exists) then
:set next task to current task;
:update task's next run time to runTime+delay;
:return No Error;
stop
endif

repeat while (get lowest priority task not yet checked )
:no tasks left to check, return error: no task found to run next;
stop
@enduml
50 changes: 50 additions & 0 deletions docs/refs.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

@article{bonney:2016,
title={Can citizen science enhance public understanding of science?},
author={Rick Bonney and Tina B. Phillips and Heidi L. Ballard and Jody W. Enck},
journal={The Computer Journal},
volume={25},
number={1},
pages={2--16},
year={2016},
publisher={Public Understanding of Science}
}

@article{bresnahan:2022,
title={A high-tech, low-cost, Internet of Things surfboard fin for coastal citizen science, outreach, and education},
author={Philip Breshnahan, et. al},
journal={Continental Shelf Research},
volume={242},
number={1},
pages={21--31},
year={2022},
publisher={Oxford University Press}
}

@Article{Li2007,
author = {Li, Wenming and Kavi, Krishna and Akl, Robert},
journal = {Computers & Electrical Engineering},
title = {A non-preemptive scheduling algorithm for soft real-time systems},
year = {2007},
issn = {0045-7906},
month = jan,
number = {1},
pages = {12--29},
volume = {33},
doi = {10.1016/j.compeleceng.2006.04.002},
publisher = {Elsevier BV},
}

@Article{Hwang2003,
author = {Hwang, Paul A and Huang, Norden E and Wang, David W},
journal = {Applied Ocean Research},
title = {A note on analyzing nonlinear and nonstationary ocean wave data},
year = {2003},
issn = {0141-1187},
month = aug,
number = {4},
pages = {187--193},
volume = {25},
doi = {10.1016/j.apor.2003.11.001},
publisher = {Elsevier BV},
}
95 changes: 95 additions & 0 deletions docs/scheduler_documentation.tex
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{graphicx}

\title{Brief Overview of SmartFin Version 3 Scheduler Implementation}
\author{Antara Chugh}
\date{Summer 2024}

\begin{document}

\maketitle

\section{Background on the SmartFin System}

We are working to design a scheduler for multiple sensors running at various frequencies and durations on a single threaded system that can only run one sensor at a time. The hardware thus restricts the schedule to be non-pre-emptitive: we cannot stop or pause a sensor A from running if another sensor B must run during the duration sensor A is collecting data. From now on, we’ll refer to each sensor as a repeating, periodic task that must run for x amount of time every y seconds. \newline


\title{Table 1: Mean \& Standard Deviation Runtime of SmartFin Sensors}
\newline



\begin{tabular}{c|c}
\hspace{-3 cm}
\begin{tabular}{| l | l | l | l | l |}
\hline
Sensor & Mean (ms) & Standard Deviation (ms) & Mean + 3 Std (ms) & Frequency \\
\hline
Temperature & 0.873 & 0.002 & 0.881 & 1 Hz \\
\hline
Accelerometer & 5.244 & 0.004 & 5.255 & 30-300 Hz \\
\hline
Gyroscope & 5.209 & 0.003 & 5.218 & 30-300 Hz \\
\hline
Magnetometer & 5.212 & 0.004 & 5.221 & 30-300 Hz \\
\hline
GPS (reading no valid location) & 0.1443 & 0.022 & 0.2103 & 1 Hz \\
\hline
Wet/Dry Sensor & 1.02 & 0.002 & 1.025 & 1 Hz \\
\hline

\end{tabular}

\end{tabular}





\section{Scheduler Requirements}
\begin{itemize}
\item Non-preemptive
\item Maintain the frequency of each task (consistent data sampling)
\item Delay or “shift” a sampling schedule of a task rather than having a singular task out of place, as that data point would then not be usable
\item Have minimal “shifts”; if priority is implemented, then minimize the “shifts” of each task by priority
\end{itemize}

The most important quality for our schedule is that it maintains the frequency of each task as much as possible in order to maximize the percentage of samples that can be used for further data processing. For our system, a delay can better be defined as a shift of the sampling sequence: If task A was scheduled to run every 5 seconds starting at time 0, but a delay in the system prevented A from running at t=10 seconds and instead ran at t=12 seconds, we say that the sampling sequence of A was shifted, or delayed by 2 seconds. A will now run every 5 seconds starting from t=12, and thus will run again at t=17 seconds. Our scheduler thus seeks to minimize the amount of these “shifts” in the system. As noted above, we prefer these “shifts” over delays to singular tasks, as that would violate the consistent sample rate we hope to achieve.


In addition, minimizing the number of shifts in the sampling sequence may be more important for some tasks than others. For example, it is more important for data processing that the inertial measurement unit is sampled at a constant rate with little to no shifts than the GPS. Thus, there is incentive to introduce some method of maintaining priority of the tasks. This works best for systems with a small number of tasks that run for relatively short durations and have relatively long time between runs. For schedulers that are more overloaded, this notion of priority may shift the sampling schedules of low priority tasks too drastically, worst case stopping them from running at all. In this case, priority may have to be implemented differently, perhaps with a max shift time enforcement (no task can be shifted more than x seconds) or having no priority in the system at all.

Another factor to note is that the exact amount of time the system will run is variable, as surfers spend variable amounts of time in the water.

\section{Previous Works}
There has been much work already done on non-preemptive scheduler algorithms. \newline

Greedy algorithms are those based on making the most locally optimal decision. Earliest deadline first and earliest job finished are examples of greedy algorithms used for creating schedules with a single compute source and multiple tasks with potentially overlapping times (Karger 1997). \newline

Earliest Deadline First is a greedy algorithm for soft real time systems, which allow for tasks to be late (Karger 1997). It provides the optimal solution to minimizing lateness in the system. It schedules tasks by ascending deadlines, scheduling those with the earliest deadline first (as implied by its name).Though we wish to also minimize delays in the system, we would prefer to delay a task and all subsequent occurrences of that task to maintain a consistent sampling rate over having a task delayed and that data point rendered as not usable. Thus, earliest deadline first is not a feasible algorithm, as it cannot guarantee consistent periodic intervals of each task. \newline

Earliest Job Finish is a greedy algorithm for hard real time systems with limited compute power (Karger 1997). It aims to perform as many tasks as possible, given that no task can be late. It also sorts the tasks by ascending deadlines, scheduling tasks that work together. Earliest job finish would not be a feasible algorithm as jobs would be skipped completely, again failing to maintain a consistent data sampling rate. \newline

\section{Current Algorithm}

Our current implementation is a greedy algorithm which picks tasks based on whether the time frame of their next run can finish before any task of higher priority. Otherwise, the task is shifted.

\begin{figure}[h]
\centering
\includegraphics[width=0.6\textwidth]{control_flow.png}
\caption{Control Flow Diagram of the Algorithm}
\label{fig:example}
\end{figure}

\section{Scheduler Limitations}
Due to the fact that the SmartFin is a uniprocessor device and the periodicity and length of the tasks, mathematically, it is not possible for all combinations of tasks to run with no shifts in the system. Further, even when allowing for shifts, there exist combinations of tasks in which preserving the frequencies of each task is simply not possible.


\bibliographystyle{plain} % We choose the "plain" reference style

\bibliography{refs} % Entries are in the refs.bib file
Karger, David, and Cli Stein. Scheduling Algorithms. 1997.

\end{document}

5 changes: 3 additions & 2 deletions src/scheduler.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* @file scheduler.cpp
* @brief Contains definitions for functions defined in @ref scheduler.hpp
* @author Charlie Kushelevsky ([email protected])
* @author Antara Chugh ([email protected]), Charlie Kushelevsky ([email protected])
* @version 1
*/
#include "scheduler.hpp"
Expand Down Expand Up @@ -70,7 +70,8 @@ void Scheduler::initializeScheduler()
* @param p_nextTime Pointer to where the time for the next event will
* be stored.
*
* @param currentTime The current system time
* @param currentTime The current system time, defined as time since system
* boot
* @return Returns SUCCESS if a suitable event is found,
* TASK_SEARCH_FAIL otherwise.
*
Expand Down
10 changes: 6 additions & 4 deletions src/scheduler.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @file charlie_scheduler.hpp
* @author Charlie Kushelevsky ([email protected])
* @author Antara Chugh ([email protected]), Charlie Kushelevsky ([email protected])
* @brief Header file for scheduler defined in @ref scheduler.cpp
* @version 1
*/
Expand All @@ -15,11 +15,13 @@
#include "Particle.h"
#else
#include "scheduler_test_system.hpp"
#endif // TEST_VERSION

#include <stddef.h>
#include <cstdint>


#endif // TEST_VERSION


/**
* @brief Ensemble function.
*
Expand Down Expand Up @@ -95,7 +97,7 @@ struct DeploymentSchedule_
class Scheduler : public AbstractScheduler {
private:
//! schedule table size
std::uint32_t tableSize;
uint32_t tableSize;
public:
//! the schedule table
DeploymentSchedule_t* scheduleTable;
Expand Down
40 changes: 19 additions & 21 deletions tests/fixed_google_tests.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* @file gtest.cpp
* @author Charlie Kushelevsky ([email protected])
* @author Antara Chugh ([email protected]), Charlie Kushelevsky ([email protected])
* @brief Google Tests for scheduler.cpp
*/

Expand All @@ -24,23 +24,9 @@
class SchedulerFixedTests : public ::testing::Test
{
protected:

/*every test will require a deployment table, we fill it with defaults.
Clock corresponds to millis(), record scheduler output in test log*/
std::uint32_t table_default_interval_A;
std::uint32_t table_default_interval_B;
std::uint32_t table_default_interval_C;
std::uint32_t table_default_duration_A;
std::uint32_t table_default_duration_B;
std::uint32_t table_default_duration_C;
std::uint32_t clock;


std::vector<DeploymentSchedule_> deployment_table;
std::vector<Log> test_log;

/*Constructor: sets up values*/

/**
* @brief constructor for tests, intializes default values
*/
SchedulerFixedTests()
{
table_default_interval_A = 75;
Expand All @@ -62,13 +48,25 @@ class SchedulerFixedTests : public ::testing::Test


};


/*Every test will require a deployment table, we fill it with defaults.
Clock corresponds to millis(), record scheduler output in test log*/
uint32_t table_default_interval_A;
uint32_t table_default_interval_B;
uint32_t table_default_interval_C;
uint32_t table_default_duration_A;
uint32_t table_default_duration_B;
uint32_t table_default_duration_C;
uint32_t clock;


std::vector<DeploymentSchedule_> deployment_table;
std::vector<Log> test_log;



/*Before every test, set the deployment table to default values, clock to
0, and empty test log*/
/*Before every test, set the deployment table to
default values, clock to 0, and empty test log*/
void SetUp() override {
deployment_table[0].ensembleInterval = table_default_interval_A;
deployment_table[1].ensembleInterval = table_default_interval_B;
Expand Down

0 comments on commit c15530d

Please sign in to comment.