SensorGroupTemplate.h 2.79 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
/*
 * SensorGroupTemplate.h
 *
 *  Created on: 03.08.2018
 *      Author: Micha Mueller
 */

#ifndef SENSORGROUPTEMPLATE_H_
#define SENSORGROUPTEMPLATE_H_

11
#include "SensorGroupInterface.h"
12

13 14 15
#include "timestamp.h"

#include <vector>
16
#include <memory>
17

18 19 20 21 22
template <typename S>
class SensorGroupTemplate : public SensorGroupInterface {
	//the template shall only be instantiated for classes which derive from SensorBase
	static_assert(std::is_base_of<SensorBase, S>::value, "S must derive from SensorBase!");

23 24 25
protected:
	using S_Ptr = std::shared_ptr<S>;

26 27 28 29
public:
	SensorGroupTemplate(const std::string groupName) :
		SensorGroupInterface(groupName) {}

30 31 32
	SensorGroupTemplate(const SensorGroupTemplate& other) :
		SensorGroupInterface(other) {
		for(auto s : other._sensors) {
33
			S_Ptr sensor = std::make_shared<S>(*s);
34 35 36 37 38
			_sensors.push_back(sensor);
			_baseSensors.push_back(sensor);
		}
	}

39
	virtual ~SensorGroupTemplate() {
40 41
		_sensors.clear();
		_baseSensors.clear();
42 43
	}

44 45 46 47 48 49
	SensorGroupTemplate& operator=(const SensorGroupTemplate& other) {
		SensorGroupInterface::operator=(other);
		_sensors.clear();
		_baseSensors.clear();

		for(auto s : other._sensors) {
50
			S_Ptr sensor = std::make_shared<S>(*s);
51 52 53 54 55 56 57
			_sensors.push_back(sensor);
			_baseSensors.push_back(sensor);
		}

		return *this;
	}

58
	virtual void pushBackSensor(SBasePtr s) override {
59 60
		//check if dynamic cast returns nullptr
		if (S_Ptr dSensor = std::dynamic_pointer_cast<S>(s)) {
61 62 63
			_sensors.push_back(dSensor);
			_baseSensors.push_back(s);
		} else {
64
			LOG(warning) << "Group " << _groupName << ": Type mismatch when storing sensor! Sensor omitted";
65 66 67
		}
	}

68
	virtual std::vector<SBasePtr>& getSensors() override	{ return _baseSensors; }
69

Alessio Netti's avatar
Alessio Netti committed
70
	virtual void init(boost::asio::io_service& io) override {
71
		SensorGroupInterface::init(io);
72 73

		for(auto s : _sensors) {
74
			s->initSensor(_interval);
75 76 77
		}
	}

78
	virtual void printConfig(LOG_LEVEL ll) override {
79
	  LOG_VAR(ll) << "            Sensors:";
80 81 82 83 84 85
	  for(auto s : _sensors) {
	    s->SensorBase::printConfig(ll, lg);
	    s->printConfig(ll, lg);
	  }
	}

86
protected:
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
	/** Calculate timestamp for the next reading
	 * @return 	Timestamp in the future to wait for
	 */
	uint64_t nextReadingTime() {
		uint64_t now = getTimestamp();
		uint64_t next;
		if (_sync) {
			uint64_t interval64 = static_cast<uint64_t>(_interval);
			uint64_t now_ms = now / 1000 / 1000;
			uint64_t waitToStart = interval64 - (now_ms%interval64); //synchronize all measurements with other sensors
			if(!waitToStart ){ // less than 1 ms seconds is too small, so we wait the entire interval for the next measurement
					return (now_ms + interval64)*1000*1000;
			}
			return (now_ms + waitToStart)*1000*1000;
		} else {
			return now + MS_TO_NS(_interval);
		}
	}

106 107
	std::vector<S_Ptr> _sensors;
	std::vector<SBasePtr> _baseSensors;
108 109 110
};

#endif /* SENSORGROUPTEMPLATE_H_ */