diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..f7f858d
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 2.8)
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+project(Ranger)
+add_executable(ranger "main.cpp" "ranger.cpp" "laser.cpp"
+ "radar.cpp" "sonar.cpp" "user_interface.cpp"
+ "ranger_fusion_interface.cpp" "ranger_fusion.cpp")
diff --git a/CMakeLists.txt.user b/CMakeLists.txt.user
new file mode 100644
index 0000000..948545e
--- /dev/null
+++ b/CMakeLists.txt.user
@@ -0,0 +1,252 @@
+
+
+
+
+
+ EnvironmentId
+ {3e2d47c9-94d4-4eba-9948-8d61a16c598b}
+
+
+ ProjectExplorer.Project.ActiveTarget
+ 0
+
+
+ ProjectExplorer.Project.EditorSettings
+
+ true
+ false
+ true
+
+ Cpp
+
+ CppGlobal
+
+
+
+ QmlJS
+
+ QmlJSGlobal
+
+
+ 2
+ UTF-8
+ false
+ 4
+ false
+ 80
+ true
+ true
+ 1
+ true
+ false
+ 0
+ true
+ true
+ 0
+ 8
+ true
+ 1
+ true
+ true
+ true
+ false
+
+
+
+ ProjectExplorer.Project.PluginSettings
+
+
+
+ ProjectExplorer.Project.Target.0
+
+ Desktop Qt 5.8.0 GCC 64bit
+ Desktop Qt 5.8.0 GCC 64bit
+ qt.58.gcc_64_kit
+ 0
+ 0
+ 1
+
+
+ /home/v/MEGA/UTS/2017_Aut/41012_PMS/A2/build-Ranger
+
+
+
+
+ all
+
+ true
+ Make
+
+ CMakeProjectManager.MakeStep
+
+ 1
+ Build
+
+ ProjectExplorer.BuildSteps.Build
+
+
+
+
+
+ clean
+
+ true
+ Make
+
+ CMakeProjectManager.MakeStep
+
+ 1
+ Clean
+
+ ProjectExplorer.BuildSteps.Clean
+
+ 2
+ false
+
+ Default
+ Default
+ CMakeProjectManager.CMakeBuildConfiguration
+
+ 1
+
+
+ 0
+ Deploy
+
+ ProjectExplorer.BuildSteps.Deploy
+
+ 1
+ Deploy locally
+
+ ProjectExplorer.DefaultDeployConfiguration
+
+ 1
+
+
+ false
+ false
+ 1000
+
+ true
+
+ false
+ false
+ false
+ false
+ true
+ 0.01
+ 10
+ true
+ 1
+ 25
+
+ 1
+ true
+ false
+ true
+ valgrind
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+
+ Ranger
+
+
+ /tmp/qtc-cmake-BJepJc
+ 2
+
+ Ranger (disabled)
+
+ CMakeProjectManager.CMakeRunConfiguration.Ranger
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+
+ false
+ false
+ 1000
+
+ true
+
+ false
+ false
+ false
+ false
+ true
+ 0.01
+ 10
+ true
+ 1
+ 25
+
+ 1
+ true
+ false
+ true
+ valgrind
+
+ 0
+ 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+ 10
+ 11
+ 12
+ 13
+ 14
+
+ ranger
+
+
+ /home/v/MEGA/UTS/2017_Aut/41012_PMS/A2/build-Ranger
+ 2
+
+ ranger
+
+ CMakeProjectManager.CMakeRunConfiguration.ranger
+ 3768
+ false
+ true
+ false
+ false
+ true
+
+ 2
+
+
+
+ ProjectExplorer.Project.TargetCount
+ 1
+
+
+ ProjectExplorer.Project.Updater.FileVersion
+ 18
+
+
+ Version
+ 18
+
+
diff --git a/laser.cpp b/laser.cpp
new file mode 100644
index 0000000..e1c5dad
--- /dev/null
+++ b/laser.cpp
@@ -0,0 +1,19 @@
+// 11970720
+// Vincent Jadraque
+
+#include "laser.h"
+
+Laser::Laser()
+{
+ setModel("UTM-XXL");
+ setBaud(38400); // default; 38400 or 115200
+ setPort(0); // default; 0-20
+ setFieldOfView(180);
+ setAngularResolution(15); // default; 15 or 30
+ setMaxDistance(8.0);
+}
+
+Laser::~Laser()
+{
+ // for demonstration only
+}
diff --git a/laser.h b/laser.h
new file mode 100644
index 0000000..0440ad6
--- /dev/null
+++ b/laser.h
@@ -0,0 +1,13 @@
+#ifndef LASER_H
+#define LASER_H
+
+#include "ranger.h"
+
+class Laser : public Ranger
+{
+public:
+ Laser();
+ ~Laser();
+};
+
+#endif // LASER_H
diff --git a/main.cpp b/main.cpp
new file mode 100644
index 0000000..9136344
--- /dev/null
+++ b/main.cpp
@@ -0,0 +1,76 @@
+// 11970720
+// Vincent Jadraque
+
+#include // cout
+#include // usleep
+
+#include "ranger.h"
+#include "laser.h"
+#include "sonar.h"
+#include "radar.h"
+#include "user_interface.h"
+#include "ranger_fusion.h"
+
+using namespace std;
+
+int main(int argc, char *argv[])
+{
+ // initialise laser sensor
+ Laser laser;
+
+ // query fixed parameters
+ showFixedParameters(laser);
+ cout << "Field of View ............. " << laser.getFieldOfView() << "\n\n" << endl;
+ // configure rest of parameters
+ askBaud(laser);
+ askPort(laser);
+ askAngularResolution(laser);
+ showNumberOfSamples(laser);
+ std::cout << "\n\n" << std::endl;
+// printReadings(laser);
+
+ // initialise radar sensor
+ Radar radar;
+
+ // query fixed parameters
+ showFixedParameters(radar);
+ // configure rest of parameters
+ askFOV(radar);
+ askBaud(radar);
+ askPort(radar);
+ showNumberOfSamples(radar);
+ std::cout << "\n\n" << std::endl;
+// printReadings(radar);
+
+ // initialise sonar sensor
+ Sonar sonar;
+
+ // query fixed parameters
+ showFixedParameters(sonar);
+ cout << "Field of View ............. " << sonar.getFieldOfView() << "\n\n" << endl;
+ // configure rest of parameters
+ askBaud(sonar);
+ askPort(sonar);
+ showNumberOfSamples(sonar);
+ std::cout << "\n\n" << std::endl;
+// printReadings(sonar);
+
+ std::vector rangers;
+ rangers = {&laser, &radar, &sonar};
+
+ RangerFusion fusion(rangers);
+ int a = 1;
+ askFusionType(fusion);
+
+ while(1)
+ {
+ std::cout << "\n\nData set " << a << ":" << std::endl;
+ printRawData(fusion);
+
+ printFusedData(fusion);
+ usleep(2000000);
+ a++;
+ }
+
+ return 0;
+}
diff --git a/radar.cpp b/radar.cpp
new file mode 100644
index 0000000..4294900
--- /dev/null
+++ b/radar.cpp
@@ -0,0 +1,27 @@
+// 11970720
+// Vincent Jadraque
+
+#include "radar.h"
+
+Radar::Radar()
+{
+ setModel("RAD-001");
+ setBaud(38400); // default; 38400 or 115200
+ setPort(0); // default; 0-20
+ setFieldOfView(20); // default; 20 or 40
+ setMaxDistance(16.0);
+ setNumberOfSamples(1);
+}
+
+Radar::~Radar()
+{
+ // for demonstration purposes only
+}
+
+int Radar::getNumberOfSamples()
+{
+ setNumberOfSamples(1);
+ return number_of_samples_;
+}
+
+
diff --git a/radar.h b/radar.h
new file mode 100644
index 0000000..1ec9675
--- /dev/null
+++ b/radar.h
@@ -0,0 +1,15 @@
+#ifndef RADAR_H
+#define RADAR_H
+
+#include "ranger.h"
+
+class Radar : public Ranger
+{
+public:
+ Radar();
+ ~Radar();
+
+ int getNumberOfSamples();
+};
+
+#endif // RADAR_H
diff --git a/ranger.cpp b/ranger.cpp
new file mode 100644
index 0000000..e483e69
--- /dev/null
+++ b/ranger.cpp
@@ -0,0 +1,185 @@
+// 11970720
+// Vincent Jadraque
+
+#include "ranger.h"
+
+#include
+
+
+Ranger::Ranger()
+{
+ min_distance_ = 0.2;
+ setMeanRNG(6.0);
+ setStdDevRNG(5.0);
+ angular_resolution_ = 15;
+}
+
+Ranger::~Ranger()
+{
+ // demonstration only
+}
+
+std::string Ranger::getModel() const
+{
+ return model_;
+}
+
+bool Ranger::checkBaud(int baud)
+{
+ checkOption(baud);
+}
+
+int Ranger::getBaud() const
+{
+ return baud_;
+}
+
+void Ranger::setBaud(int baud)
+{
+ baud_ = baud;
+}
+
+// check whether port chosen is between 0 and 20
+bool Ranger::checkPort(int port)
+{
+ if(port >= 0 && port < 21)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void Ranger::setPort(int port)
+{
+ char portString[3] = {0};
+
+ memset(port_, '\0', sizeof port_);
+ strcat(port_, "/dev/ttyACM");
+
+ sprintf(portString, "%d", port);
+
+ strcat(port_, portString);
+}
+
+char *Ranger::getPort()
+{
+ return port_;
+}
+
+bool Ranger::checkFieldOfView(int test_FOV)
+{
+ checkOption(test_FOV);
+}
+
+int Ranger::getFieldOfView() const
+{
+ return field_of_view_;
+}
+
+void Ranger::setFieldOfView(int field_of_view)
+{
+ field_of_view_ = field_of_view;
+}
+
+bool Ranger::checkAngularResolution(int angular_resolution)
+{
+ checkOption(angular_resolution);
+}
+
+int Ranger::getAngularResolution()
+{
+ return angular_resolution_;
+}
+
+void Ranger::setAngularResolution(int angular_resolution)
+{
+ angular_resolution_ = angular_resolution;
+}
+
+double Ranger::getMaxDistance() const
+{
+ return max_distance_;
+}
+
+void Ranger::setMaxDistance(double max_distance)
+{
+ max_distance_ = max_distance;
+}
+
+double Ranger::getMinDistance() const
+{
+ return min_distance_;
+}
+
+void Ranger::setMinDistance(double min_distance)
+{
+ min_distance_ = min_distance;
+}
+
+int Ranger::getNumberOfSamples()
+{
+ number_of_samples_ = 1 + 2 * ((field_of_view_/2)/angular_resolution_);
+ return number_of_samples_;
+}
+
+void Ranger::setNumberOfSamples(int number_of_samples)
+{
+ number_of_samples_ = number_of_samples;
+}
+
+double Ranger::getStdDevRNG() const
+{
+ return std_dev_RNG_;
+}
+
+std::vector Ranger::readSensor()
+{
+ std::random_device rd;
+ std::default_random_engine generator(rd());
+
+ std::normal_distribution normal(getMeanRNG(), getStdDevRNG());
+
+ int n = getNumberOfSamples();
+ std::vector vi1 = {};
+
+ for(int i = 0; i < n; i++)
+ {
+ // add check to limit max value
+ double v = normal(generator);
+ if(v > getMaxDistance())
+ vi1.push_back(getMaxDistance());
+ else if(v < getMinDistance())
+ vi1.push_back(getMinDistance());
+ else
+ vi1.push_back(v);
+ }
+ return vi1;
+}
+
+void Ranger::setStdDevRNG(double std_dev_RNG)
+{
+ std_dev_RNG_ = std_dev_RNG;
+}
+
+double Ranger::getMeanRNG() const
+{
+ return mean_RNG_;
+}
+
+void Ranger::setMeanRNG(double mean_RNG)
+{
+ mean_RNG_ = mean_RNG;
+}
+
+bool Ranger::checkOption(int input)
+{
+ return (input == 1 || input == 2) ? true : false;
+}
+
+void Ranger::setModel(const std::string &model)
+{
+ model_ = model;
+}
diff --git a/ranger.h b/ranger.h
new file mode 100644
index 0000000..9addb50
--- /dev/null
+++ b/ranger.h
@@ -0,0 +1,65 @@
+#ifndef RANGER_H
+#define RANGER_H
+
+#include
+#include
+#include
+
+class Ranger
+{
+public:
+ Ranger();
+ ~Ranger();
+
+ std::string getModel() const;
+
+ bool checkBaud(int baud);
+ int getBaud() const;
+ void setBaud(int baud);
+
+ bool checkPort(int port);
+ char *getPort();
+ void setPort(int port);
+
+ bool checkFieldOfView(int test_FOV);
+ int getFieldOfView() const;
+ void setFieldOfView(int field_of_view);
+
+ bool checkAngularResolution(int angular_resolution);
+ int getAngularResolution();
+ void setAngularResolution(int angular_resolution);
+
+ double getMinDistance() const;
+ double getMaxDistance() const;
+
+ virtual int getNumberOfSamples();
+
+ std::vector readSensor();
+
+protected:
+ void setModel(const std::string &model);
+ void setMinDistance(double min_distance);
+ void setMaxDistance(double max_distance);
+ virtual void setNumberOfSamples(int number_of_samples);
+ double getMeanRNG() const;
+ double getStdDevRNG() const;
+ int number_of_samples_; // = 1+2*((FOV/2)/angular_res'n
+
+
+private:
+ void setMeanRNG(double mean_RNG);
+ void setStdDevRNG(double std_dev_RNG);
+ bool checkOption(int input);
+ // variables representing parameter list
+ std::string model_;
+ int baud_; // configurable
+ char port_[17]; // configurable
+ int field_of_view_; // degrees
+ double max_distance_; // metres
+ double mean_RNG_; // 6.0
+ double std_dev_RNG_; // 5.0
+ int angular_resolution_; // degrees
+ double min_distance_; // metres
+};
+
+#endif // RANGER_H
diff --git a/ranger_fusion.cpp b/ranger_fusion.cpp
new file mode 100644
index 0000000..5544da4
--- /dev/null
+++ b/ranger_fusion.cpp
@@ -0,0 +1,118 @@
+#include "ranger_fusion.h"
+#include
+
+RangerFusion::RangerFusion()
+{
+ // fusion type (0 - min; 1 - avg; 2 - max) will be set to average
+ setFusionType(AVG);
+}
+
+RangerFusion::RangerFusion(vector rangers)
+{
+ // fusion type (0 - min; 1 - avg; 2 - max) will be set to average
+ setFusionType(AVG);
+ setRangers(rangers);
+}
+
+RangerFusion::~RangerFusion()
+{
+ // for demonstration purposes only
+}
+
+void RangerFusion::setRangers(vector rangers)
+{
+ // sort rangers by field of view (large to small)
+ std::sort (rangers.begin(), rangers.end(),
+ [](Ranger * a, Ranger * b){return b->getFieldOfView() < a->getFieldOfView();}
+ );
+ rangers_ = rangers;
+}
+
+vector RangerFusion::getRangers()
+{
+ return rangers_;
+}
+
+vector > RangerFusion::getRawRangeData()
+{
+// for(auto r : rangers_)
+// {
+// raw_range_data_.push_back(r->readSensor());
+// }
+ raw_range_data_.clear();
+
+ for(vector::iterator i = rangers_.begin(); i != rangers_.end(); i++)
+ {
+ raw_range_data_.push_back((*i)->readSensor());
+ }
+ return raw_range_data_;
+}
+
+vector RangerFusion::getFusedRangeData()
+{
+ // make vector for how many times the radar and sonar sensors' field of view
+ // overlaps with the laser's samples
+ // e.g. if angular res'n of laser is 15, and radar FOV is 20,
+ // laser has 13 samples, radar overlaps once, and sonar overlaps 3 times
+ // so NoS = {13, 1, 3};
+ fused_range_data_.clear();
+
+ std::vector overlap;
+ for(int n = 0; n < rangers_.size(); n++)
+ {
+ overlap.push_back(1 + 2 * ((rangers_.at(n)->getFieldOfView()/2)/rangers_.at(n)->getAngularResolution()));
+ }
+
+ int a = 0;
+
+ int s = 1;
+ int r = 2;
+
+ int ol_s = (overlap.at(0) - overlap.at(s))/2;
+ int ol_r = (overlap.at(0) - overlap.at(r))/2;
+
+ double raw_s = raw_range_data_.at(s).at(0);
+ double raw_r = raw_range_data_.at(r).at(0);
+
+ double e;
+
+ for(vector::iterator i = raw_range_data_.at(0).begin(); i != raw_range_data_.at(0).end(); i++, a++)
+ {
+ e = *i;
+ if( (a >= ol_s) && (a < ol_s + overlap.at(s)) )
+ {
+ switch(fusion_type_)
+ {
+ case MIN: e = std::min((*i), raw_s); break;
+ case AVG: e = ((*i) + raw_s)/2.0; break;
+ case MAX: e = std::max((*i), raw_s); break;
+ }
+ }
+ if( (a >= ol_r) && (a < ol_r + overlap.at(r)) )
+ {
+ switch(fusion_type_)
+ {
+ case MIN: e = std::min(e, raw_r); break;
+ case AVG: e = (2.0 * e + raw_r)/3.0; break;
+ case MAX: e = std::max(e, raw_r); break;
+ }
+ }
+ fused_range_data_.push_back(e);
+ }
+
+ return fused_range_data_;
+}
+
+bool RangerFusion::checkFusionType(int test_fusion_type)
+{
+ return (test_fusion_type >=0 && test_fusion_type <= 2)? true : false;
+}
+int RangerFusion::getFusionType() const
+{
+ return fusion_type_;
+}
+
+void RangerFusion::setFusionType(int fusion_type)
+{
+ fusion_type_ = fusion_type;
+}
diff --git a/ranger_fusion.h b/ranger_fusion.h
new file mode 100644
index 0000000..433ed70
--- /dev/null
+++ b/ranger_fusion.h
@@ -0,0 +1,34 @@
+#ifndef RANGERFUSION_H
+#define RANGERFUSION_H
+
+#define MIN 0
+#define AVG 1
+#define MAX 2
+
+#include "ranger_fusion_interface.h"
+#include "ranger.h"
+
+class RangerFusion : public RangerFusionInterface
+{
+public:
+ RangerFusion();
+ RangerFusion(vector rangers);
+ ~RangerFusion();
+
+ void setRangers(vector rangers);
+ vector getRangers();
+ vector > getRawRangeData();
+ vector getFusedRangeData();
+
+ bool checkFusionType(int test_fusion_type);
+ int getFusionType() const;
+ void setFusionType(int fusion_type);
+
+private:
+ int fusion_type_;
+ vector rangers_;
+ vector > raw_range_data_;
+ vector fused_range_data_;
+};
+
+#endif // RANGERFUSION_H
diff --git a/ranger_fusion_interface.cpp b/ranger_fusion_interface.cpp
new file mode 100644
index 0000000..e7efaf1
--- /dev/null
+++ b/ranger_fusion_interface.cpp
@@ -0,0 +1,9 @@
+// 11970720
+// Vincent Jadraque
+
+#include "ranger_fusion_interface.h"
+
+RangerFusionInterface::RangerFusionInterface()
+{
+
+}
diff --git a/ranger_fusion_interface.h b/ranger_fusion_interface.h
new file mode 100644
index 0000000..d665968
--- /dev/null
+++ b/ranger_fusion_interface.h
@@ -0,0 +1,32 @@
+#ifndef FUSION_H
+#define FUSION_H
+
+#include
+
+using std::vector;
+
+// This is a forward declaration of the Ranger class (google it)
+// It tells the RangerFusionInterface that such a class exists
+// but does not specify its details
+class Ranger;
+
+// The RangerFusionInterface is a class which specifies the minimum
+// required interface for your RangerFusion class your ranger fusion
+// class must inherit from it
+class RangerFusionInterface
+{
+public:
+ RangerFusionInterface();
+
+ // Accepts container of rangers as per requirement C2 of assignment 2
+ virtual void setRangers(vector rangers) = 0;
+
+ // Returns a container of fused range readings as per C4 assignment 2
+ virtual vector getFusedRangeData() = 0;
+
+ // Returns a container of raw/unfused range readings as per C5 assignment 2
+ // vector of vectors
+ virtual vector > getRawRangeData() = 0;
+};
+
+#endif // FUSION_H
diff --git a/sonar.cpp b/sonar.cpp
new file mode 100644
index 0000000..b706fed
--- /dev/null
+++ b/sonar.cpp
@@ -0,0 +1,25 @@
+// 11970720
+// Vincent Jadraque
+
+#include "sonar.h"
+
+Sonar::Sonar()
+{
+ setModel("SONX-001");
+ setBaud(38400); // default; 38400 or 115200
+ setPort(0); // default; 0-20
+ setFieldOfView(90);
+ setMaxDistance(4.0);
+ setNumberOfSamples(1);
+}
+
+Sonar::~Sonar()
+{
+ // for demonstration purposes only
+}
+
+int Sonar::getNumberOfSamples()
+{
+ setNumberOfSamples(1);
+ return number_of_samples_;
+}
diff --git a/sonar.h b/sonar.h
new file mode 100644
index 0000000..4bb77eb
--- /dev/null
+++ b/sonar.h
@@ -0,0 +1,15 @@
+#ifndef SONAR_H
+#define SONAR_H
+
+#include "ranger.h"
+
+class Sonar : public Ranger
+{
+public:
+ Sonar();
+ ~Sonar();
+
+ int getNumberOfSamples();
+};
+
+#endif // SONAR_H
diff --git a/user_interface.cpp b/user_interface.cpp
new file mode 100644
index 0000000..ccbecd8
--- /dev/null
+++ b/user_interface.cpp
@@ -0,0 +1,244 @@
+// 11970720
+// Vincent Jadraque
+
+#include "ranger.h"
+#include "user_interface.h"
+#include // numeric_limits
+#include // setprecision
+
+
+void showFixedParameters(Ranger &sensor)
+{
+ std::cout << "\n\n\nFixed parameters:\n";
+ std::cout << "Model ..................... " << sensor.getModel() << std::endl;
+ std::cout << "Max Distance .............. " << std::fixed << std::setprecision(1);
+ std::cout << sensor.getMaxDistance() << " m" << std::endl;
+ std::cout << "Min Distance .............. " << sensor.getMinDistance() << " m" << std::endl;
+}
+
+void showNumberOfSamples(Ranger &sensor)
+{
+ std::cout << "Number of samples ......... " << sensor.getNumberOfSamples() << std::endl;
+}
+
+void askFOV(Radar &sensor)
+{
+ std::cout << "\n\nPlease specify Field of View for radar sensor " << sensor.getModel() << std::endl;
+ std::cout << "Enter '1' or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 1: 20 degrees" << std::endl;
+ std::cout << "Option 2: 40 degrees" << std::endl;
+
+ int test_FOV;
+
+ while(!(std::cin >> test_FOV))
+ {
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits::max(),'\n');
+ std::cout << "\n\n\nPlease input numeric values only\n" << std::endl;
+
+ std::cout << "Please specify Field of View.\nEnter '1' or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 1: 20 degrees" << std::endl;
+ std::cout << "Option 2: 40 degrees" << std::endl;
+ }
+
+ // if values are sane, set field of view; else use default
+ if(sensor.checkFieldOfView(test_FOV))
+ {
+ sensor.setFieldOfView(20 * test_FOV);
+ std::cout << "Valid option. Using ";
+ }
+ else
+ {
+ std::cout << "Invalid option. Using default ";
+ }
+ std::cout << "field of view: " << sensor.getFieldOfView() << "\n\n" << std::endl;
+}
+
+void askBaud(Ranger &sensor)
+{
+ std::cout << "\n\nPlease specify baud rate for " << sensor.getModel() << std::endl;
+ std::cout << "Enter '1' or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 1: 38400" << std::endl;
+ std::cout << "Option 2: 115200" << std::endl;
+
+ int test_baud;
+
+ while(!(std::cin >> test_baud))
+ {
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits::max(),'\n');
+ std::cout << "\n\n\nPlease input numeric values only\n" << std::endl;
+
+ std::cout << "Please specify baud rate for " << sensor.getModel() << std::endl;
+ std::cout << "Enter '1' or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 1: 38400" << std::endl;
+ std::cout << "Option 2: 115200" << std::endl;
+ }
+
+ // if values are sane, set baud; else use default
+ // Option 1: 38400
+ // Option 2: 115200
+ // baud = 38400 * (2 * test_baud - 1)
+
+ if(sensor.checkBaud(test_baud))
+ {
+ sensor.setBaud(38400 * (2 * test_baud - 1));
+ std::cout << "Valid option. Using ";
+ }
+ else
+ {
+ std::cout << "Invalid option. Using default ";
+ }
+ std::cout << "baud rate: " << sensor.getBaud() << "\n\n" << std::endl;
+}
+
+void askPort(Ranger &sensor)
+{
+ std::cout << "\n\nPlease specify " << sensor.getModel();
+ std::cout << " port number for /dev/ttyACMX ";
+ std::cout << "\nwhere X is an integer from 0 to 20" << std::endl;
+ std::cout << "Input X value:" << std::endl;
+
+ int test_port;
+
+ while(!(std::cin >> test_port))
+ {
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits::max(),'\n');
+ std::cout << "\n\n\nPlease input numeric values only\n" << std::endl;
+
+ std::cout << "Please specify " << sensor.getModel();
+ std::cout << " port number for /dev/ttyACMX ";
+ std::cout << "\nwhere X is an integer from 0 to 20\n" << std::endl;
+ std::cout << "Input X value:" << std::endl;
+ }
+
+ // if values are sane, set port; else use default
+ if(sensor.checkPort(test_port))
+ {
+ sensor.setPort(test_port);
+ std::cout << "Valid port number. Using ";
+ }
+ else
+ {
+ std::cout << "Specified port number out of range. Using default ";
+ }
+ std::cout << "sensor port: " << sensor.getPort() << std::endl;
+}
+
+void askAngularResolution(Laser &sensor)
+{
+ std::cout << "\n\nPlease specify angular resolution for laser sensor." << std::endl;
+ std::cout << "Enter '1' or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 1: 15 degrees" << std::endl;
+ std::cout << "Option 2: 30 degrees" << std::endl;
+
+ int test_angular_resolution;
+
+ while(!(std::cin >> test_angular_resolution))
+ {
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits::max(),'\n');
+ std::cout << "\n\n\nPlease input numeric values only\n" << std::endl;
+
+ std::cout << "Please specify angular resolution for laser sensor." << std::endl;
+ std::cout << "Enter '1' or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 1: 15 degrees" << std::endl;
+ std::cout << "Option 2: 30 degrees" << std::endl;
+ }
+
+ // if values are sane, set field of view; else use default
+ if(sensor.checkAngularResolution(test_angular_resolution))
+ {
+ sensor.setAngularResolution(15 * test_angular_resolution);
+ std::cout << "Valid option. Using ";
+ }
+ else
+ {
+ std::cout << "Invalid option. Using default ";
+ }
+ std::cout << "angular resolution: " << sensor.getAngularResolution() << "\n\n" << std::endl;
+}
+
+void askFusionType(RangerFusion &fusion)
+{
+ std::cout << "Please specify fusion type by entering '0', '1', or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 0: minimum" << std::endl;
+ std::cout << "Option 1: average" << std::endl;
+ std::cout << "Option 2: maximum" << std::endl;
+
+ int test_fusion_type;
+
+ while(!(std::cin >> test_fusion_type))
+ {
+ std::cin.clear();
+ std::cin.ignore(std::numeric_limits::max(),'\n');
+ std::cout << "\n\n\nPlease input numeric values only\n" << std::endl;
+
+ std::cout << "Please specify fusion type by entering '0', '1', or '2' corresponding to the option you wish:" << std::endl;
+ std::cout << "Option 0: minimum" << std::endl;
+ std::cout << "Option 1: average" << std::endl;
+ std::cout << "Option 2: maximum" << std::endl;
+ }
+
+ // if values are sane, set field of view; else use default
+ if(fusion.checkFusionType(test_fusion_type))
+ {
+ fusion.setFusionType(test_fusion_type);
+ std::cout << "Valid option. Using ";
+ }
+ else
+ {
+ std::cout << "Invalid option. Using default ";
+ }
+ std::cout << "fusion type: " << fusion.getFusionType() << "\n\n" << std::endl;
+}
+
+void printReadings(Ranger &sensor)
+{
+ std::vector v1;
+ v1.resize(sensor.getNumberOfSamples());
+ v1 = sensor.readSensor();
+ for(auto i = v1.begin(); i != v1.end(); ++i)
+ std::cout << *i << std::endl;
+}
+
+
+
+void printRawData(RangerFusion &fusion)
+{
+ vector > raw = fusion.getRawRangeData();
+ vector rangers = fusion.getRangers();
+
+ int a = 0;
+ int s = 0;
+
+ std::cout << "Printing raw data:" << std::endl;
+
+ for(vector::iterator i = rangers.begin(); i != rangers.end(); i++, a++)
+ {
+ std::cout << (*i)->getModel() << std::endl;
+
+ s = 1;
+
+ for(vector::iterator r = raw[a].begin(); r != raw[a].end(); r++, s++)
+ {
+ std::cout << "Sample " << s << ": " << *r << "m" << std::endl;
+ }
+
+ std::cout << std::endl;
+ }
+}
+
+void printFusedData(RangerFusion &fusion)
+{
+ std::vector fused;
+ fused = fusion.getFusedRangeData();
+ std::cout << "Printing fused data:" << std::endl;
+ int s = 0;
+ for(std::vector::iterator i = fused.begin(); i != fused.end(); i++, s++)
+ {
+ std::cout << "Angle " << s * fusion.getRangers().at(0)->getAngularResolution() << ": " << *i << "m" << std::endl;
+ }
+}
+
diff --git a/user_interface.h b/user_interface.h
new file mode 100644
index 0000000..a3a02b5
--- /dev/null
+++ b/user_interface.h
@@ -0,0 +1,25 @@
+#ifndef USER_INTERFACE_H
+#define USER_INTERFACE_H
+
+#include "ranger.h"
+#include "radar.h"
+#include "laser.h"
+#include "ranger_fusion.h"
+#include // streamsize;
+#include
+#include
+
+
+void showFixedParameters(Ranger &sensor);
+void showNumberOfSamples(Ranger &sensor);
+void askBaud(Ranger &sensor);
+void askPort(Ranger &sensor);
+void askFOV(Radar &sensor);
+void askAngularResolution(Laser &sensor);
+void askFusionType(RangerFusion &fusion);
+void printReadings(Ranger &sensor);
+void printRawData(RangerFusion &fusion);
+void printFusedData(RangerFusion &fusion);
+
+
+#endif // USER_INTERFACE_H