Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next pr #34

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions docs/architecture/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Architecture
============

.. toctree::
:maxdepth: 1

The Sampling Engine is designed to provide a configurable interface that allows the system
to work in either the distance or time domains.

The interface of the library is a simple Sampling Engine that is configured to operate an
internal sampling engine. The internal engine takes in time-based records and can generate
both distance-based and time-based records, and status records to specify which channels
are valid at which point during the data stream.

The time-based records are inserted into a queue on receipt, and then pushed into to the
sampling engine. The sampling engine pushes the records through a series of filters to make
the desired calculations. The status records are generated by checking the status of the filters
used for each channel. The filters are then read for their values with the new record pushed
into an output queue which will be read by the caller via the exteranally visible Sampling Engine.

NOTE: The sampling engine will eventually be able to delay records used for application specific
behavior using a similar mechanism.
2 changes: 2 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Contents:
.. toctree::
:maxdepth: 2

architecture/index

.. doxygenindex:: SamplingEngine


Expand Down
7 changes: 3 additions & 4 deletions include/samplingEngineInternal/filters/averaging.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ namespace filters
//! Constructor
AveragingFilter()
{
length = 0;
}
//! Destructor
~AveragingFilter()
Expand Down Expand Up @@ -64,7 +63,7 @@ namespace filters
sum += _value;
values.push_back(_value);

if (values.length() > length)
if (values.size() > length)
{
sum -= values.front();
values.pop_front();
Expand Down Expand Up @@ -94,8 +93,8 @@ namespace filters
protected:
typedef std::deque<T> datalist; /*!< internal type for storing the values */

size_t length; /*!< filter length */
T sum; /*!< Running summation of the values */
size_t length{0}; /*!< filter length */
T sum{0}; /*!< Running summation of the values */
datalist values; /*!< listing of values being averaged. */
};

Expand Down
37 changes: 37 additions & 0 deletions include/samplingEngineInternal/generator/time_record_generator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef INTERNAL_SAMPLING_ENGINE_RECORD_GENERATOR_H__
#define INTERNAL_SAMPLING_ENGINE_RECORD_GENERATOR_H__

#include <generator/time_generator.h>
#include <samplingEngineInternal/sensors/tachometer/abstractTachometer.h>

namespace samplingEngine
{
namespace generator
{
namespace time
{

class TimeRecordGenerator : public samplingEngine::generator::AbstractTimeRecordGenerator
{
public:
TimeRecordGenerator();
virtual ~TimeRecordGenerator();

virtual void configure(const samplingEngine::generator::TimeRecordGeneratorConfiguration& _config);
virtual void initialize();
virtual void shutdown();

virtual void generate_record(samplingEngine::records::time_record*& _record);
virtual void cleanup_record(samplingEngine::records::time_record*& _record);

protected:
const samplingEngine::generator::TimeRecordGeneratorConfiguration* configuration;
// sensor emulators

std::deque<sensor::abstractTachometerSensor> tachometers;
};
}
}
}

#endif //INTERNAL_SAMPLING_ENGINE_RECORD_GENERATOR_H__
13 changes: 13 additions & 0 deletions include/samplingEngineInternal/geometricEngine/channelOffsets.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ namespace geometricEngine
size_t offset;
size_t length;
uint16_t index;
bool zero_on_invalid;
};

typedef std::map<uint16_t, struct dataPoint> offsetMapping;
Expand All @@ -43,9 +44,21 @@ namespace geometricEngine
int32_t storeTimeValue(samplingEngine::channels::distance::distanceChannels channel, struct samplingEngine::records::time_record*& _record);
int32_t storeTimeStatusValue(samplingEngine::channels::distance::distanceChannels channel, struct samplingEngine::records::status_record*& _record);

size_t time_channel_size() const;
uint16_t time_channel_count() const;

size_t distance_channel_size() const;
uint16_t distance_channel_count() const;

protected:
struct channelOffsetMap timeRecords;
struct channelOffsetMap distanceRecords;

uint16_t size_time_channels;
uint16_t count_time_channels;

size_t size_distance_channels;
uint16_t count_distance_channels;
};
}

Expand Down
3 changes: 3 additions & 0 deletions include/samplingEngineInternal/geometricEngine/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ namespace geometricEngine
// number of distance samples necessary for all channels to be valid assuming data is
// within the tolerances of all the filters
uint64_t maximum_sample_buffering;
// the current distance record index relative to the start of the engine
// NOTE: this resets on `open`
uint64_t current_distance_record;
};
}

Expand Down
8 changes: 4 additions & 4 deletions include/samplingEngineInternal/interfaces/abstractFilter.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ namespace samplingEngine
virtual void processRecord(records::distance_record* _record)=0;

// output - function should update its portion of the records
virtual void updateRecord(const records::time_record*& _record)=0;
virtual void updateRecord(const records::distance_record*& _record)=0;
virtual void updateRecord(const records::status_record*& _record, bool timeDomain)=0;
virtual void updateRecord(records::time_record*& _record)=0;
virtual void updateRecord(records::distance_record*& _record)=0;
virtual void updateRecord(records::status_record*& _record, bool timeDomain)=0;

// set the current Time-based Record Input Index (start of time queue)
virtual void setTimeRecordInputIndex(uint64_t _input_index, size_t _data_size)=0;

// set the current Time-based Record Output Index (end of time queue)
virtual void setTimeRecordOutputIndex(uint64_t _input_inde, size_t _data_sizex)=0;
virtual void setTimeRecordOutputIndex(uint64_t _input_index, size_t _data_size)=0;
// set the current Distance Record Output Index
virtual void setDistanceRecordOutputIndex(uint64_t _input_index, size_t _data_size)=0;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef ABSTRACT_SENSOR_TACHOMETER_H__
#define ABSTRACT_SENSOR_TACHOMETER_H__

#include <deque>

#include <samplingEngine/configuration.h>

#include <samplingEngine/sensors/abstractSensor.h>

namespace sensor
{
class abstractTachometerSensor: samplingEngine::interfaces::abstractSensor
{
public:
//! Constructor
abstractTachometerSensor();
//! Destructor
virtual ~abstractTachometerSensor();

//! sensor name
/*!
Access the human readable name of the sensor
/returns std::string containing an UTF-8 ASCIIZ string with the name of the sensor
*/
virtual const std::string& sensorName()=0;

// open the sensor for use
virtual void open(const struct samplingEngine::config::engineConfiguration& _configuration)=0;
// is the sensor open for use?
virtual bool isOpen() const=0;

// reset the sensor data
virtual void reset()=0;

// close the sensor
virtual void close()=0;

// input - function should get the required information from the record
virtual void processRecord(const samplingEngine::records::time_record* _record)=0;

// output - function should update its portion of the records
virtual void updateRecord(samplingEngine::records::time_record*& _record)=0;
virtual void updateRecord(samplingEngine::records::status_record*& _record, bool timeDomain)=0;

// set the current Time-based Record Output Index (end of time queue)
virtual void setTimeRecordOutputIndex(uint64_t _input_index, size_t _data_size)=0;
};

typedef std::deque<abstractTachometerSensor*> tachometerSensorList;
}

#endif // ABSTRACT_SENSOR_TACHOMETER_H__
74 changes: 74 additions & 0 deletions include/samplingEngineInternal/sensors/tachometer/fakeTachometer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#ifndef FAKE_SENSOR_TACHOMETER_H__
#define FAKE_SENSOR_TACHOMETER_H__

#include <samplingEngine/channels/time_channels.h>

#include <samplingEngineInternal/sensors/tachometer/abstractTachometer.h>
#include <samplingEngineInternal/utils/sine_generator.h>

namespace sensor
{
namespace fake
{
class fakeTachometerSensor: sensor::abstractTachometerSensor
{
public:
//! Constructor
fakeTachometerSensor();
//! Destructor
virtual ~fakeTachometerSensor();

//! sensor name
/*!
Access the human readable name of the sensor
/returns std::string containing an UTF-8 ASCIIZ string with the name of the sensor
*/
const std::string& sensorName();

// open the sensor for use
void open(const struct samplingEngine::config::engineConfiguration& _configuration);
// is the sensor open for use?
bool isOpen() const;

// reset the sensor data
void reset();

// close the sensor
void close();

// input - function should get the required information from the record
void processRecord(const samplingEngine::records::time_record* _record);

// output - function should update its portion of the records
void updateRecord(samplingEngine::records::time_record*& _record);
void updateRecord(samplingEngine::records::status_record*& _record, bool _timeDomain);

// set the current Time-based Record Output Index (end of time queue)
void setTimeRecordOutputIndex(uint64_t _input_index, size_t _data_size);
protected:
// if officialTachometer is true, then this is the sole tachometer
// if it's false, then it needs to be stored into one of the MULTI_TACH channels
// so that the multiTachometer can combine them together
bool officialTachometer{false};
bool ascending{true};
uint32_t count_by{1};
uint32_t max{0x00FFFFFF};
uint32_t min{0x0};

// is the sensor active
bool active{false};

// location in time records
// samplingEngine::channels::time::timeChannels channelLocation;

// sine wave generator
utils::sineWaveGeneratorUnsignedInt32 sineWave;

private:
// official name
std::string name{"fake-tachometer"};
};
}
}

#endif // FAKE_SENSOR_TACHOMETER_H__
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#ifndef MULTI_TACHOMETER_H__
#define MULTI_TACHOMETER_H__

#include <stdint.h>

#include <samplingEngine/configuration.h>
#include <samplingEngine/channels/time_channels.h>

#include <samplingEngineInternal/sensors/tachometer/abstractTachometer.h>
#include <samplingEngineInternal/filters/averaging.h>

namespace sensor
{
namespace multi
{
class tachometerEntry {
public:
filters::AveragingFilterUInt32 tach32;
filters::AveragingFilterUInt16 tach16;

tachometerEntry();
~tachometerEntry();
void init();
void reset();
void apply(uint32_t _value);
};

//! multiTachometer - integrate multiple tachometer sensors
/*!
Receive multiple tachometers and combine them together into a single time-based channels.
This requires all the hardware sensors to be integrated into the time-based record prior
to this tachometer being used.

The multiTachometer works by averaging the hardware tachometer sensors and generating
a new tachometer sensor value.
*/
class multiTachometerSensor: abstractTachometerSensor
{
public:
//! Constructor
multiTachometerSensor();
//! Destructor
virtual ~multiTachometerSensor();

//! sensor name
/*!
Access the human readable name of the sensor
/returns std::string containing an UTF-8 ASCIIZ string with the name of the sensor
*/
const std::string& sensorName();

// open the sensor for use
void open(const struct samplingEngine::config::engineConfiguration& _configuration);
// is the sensor open for use?
bool isOpen() const;

// reset the sensor data
void reset();

// close the sensor
void close();

// input - function should get the required information from the record
void processRecord(const samplingEngine::records::time_record* _record);

// output - function should update its portion of the records
void updateRecord(samplingEngine::records::time_record*& _record);
void updateRecord(samplingEngine::records::status_record*& _record, bool timeDomain);

// set the current Time-based Record Output Index (end of time queue)
void setTimeRecordOutputIndex(uint64_t _input_index, size_t _data_size);
protected:
typedef std::map<samplingEngine::channels::time::timeChannels, struct tachometerEntry> tachTracker;

const std::string name{"multitach"};
bool active{false};

// reads the MULTI_TACH_ channels, combines them together using an averaging
// algorithm and then puts the result into the singular tachometer record.
// these channels are only in use when the multi-tach is in use
uint32_t runningAverage;

tachTracker inputTachometers;
};
}
}

#endif
Loading
Loading