Files
Bachelorarbeit-Rover/lib/Speedometer/speedometer.cpp
T

153 lines
3.9 KiB
C++

/**
* @file speedometer.cpp
* @author Alexander Klein (alex@kleiax.de)
* @brief Implementation of the class speedometer.h
* @see speedometer.h
* @version 0.1
* @date 2021-12-13
*
* @copyright Copyright (c) 2021
*
*/
#include "speedometer.h"
Speedometer::Speedometer(uint8_t pin, double diameter, uint16_t steps, uint8_t numOfValForAvg) {
this->init(pin, diameter, steps);
this->bufSize = numOfValForAvg;
}
Speedometer::Speedometer(uint8_t pin, double diameter, uint16_t steps) {
this->init(pin, diameter, steps);
}
Speedometer::~Speedometer() {
delete[] this->buf;
delete this->pulseCounter;
}
uint16_t Speedometer::loop() {
if (this->calibrationRunning)
return -1;
uint32_t time = millis();
uint16_t elapsed_time = time - this->last_millis_loop;
//Cancel if delayLoop is not reached
if (elapsed_time < this->delayLoop)
return elapsed_time;
runSpeedometer();
this->last_millis_loop = time;
return elapsed_time;
}
void Speedometer::runSpeedometer() {
uint32_t time = millis();
uint16_t elapsed_time = time - last_millis_calc;
last_millis_calc = time;
int16_t count = this->pulseCounter->get_value();
switch (this->currentDirection) {
case Direction::Forward :
this->addValToBuf(count);
break;
case Direction::Backward :
this->addValToBuf(-count);
break;
case Direction::None :
this->addValToBuf(0);
break;
default:
std::cout << "Wrong value in Speedometer::runSpeedometer" << std::endl;
break;
}
this->pulseCounter->clear();
this->pulseCounter->resume();
uint16_t count_abs = abs(this->calcAverage()); // Absolute time in milliseconds
double n = (double)count_abs / steps; // Wheel revolutions in absolute time
double u = (double)n / ((double)elapsed_time / 1000); // Wheel revolutions per second
double ms = u * (diameter * PI); // Speed in m/s
if (count > 0) {
this->speed = ms;
} else if (count < 0) {
this->speed = ms * (-1);
} else {
this->speed = 0;
}
// std::cout << "Speedometer::runSpeedometer speed: " << (int) this->speed << std::endl;
}
void Speedometer::setNumOfValForAvg(uint8_t val) {
this->bufSize = val;
updateAvgBufSize();
}
void Speedometer::setEncFilter(uint16_t val) {
if (val > 1023)
val = 1023;
this->pulseCounter->set_filter_value(val);
}
void Speedometer::calibrationMeasurementStart() {
this->calibrationRunning = true;
this->pulseCounter->clear();
this->pulseCounter->resume();
}
uint16_t Speedometer::calibrationMeasurementStop() {
this->calibrationRunning = false;
uint16_t res = abs(this->pulseCounter->get_value());
this->pulseCounter->clear();
this->pulseCounter->resume();
return res;
}
void Speedometer::init(uint8_t pin, double diameter, uint16_t steps) {
this->diameter = diameter;
this->steps = steps;
this->pulseCounter = new PulseCounter();
this->pulseCounter->initialise(pin, PCNT_PIN_NOT_USED);
this->pulseCounter->set_mode(PCNT_COUNT_INC, PCNT_COUNT_DIS, PCNT_MODE_KEEP, PCNT_MODE_KEEP);
this->pulseCounter->set_filter_value(1000); // ignore pulses less than 1000 x 2.5ns
this->pulseCounter->clear();
this->pulseCounter->resume();
initAvgBuf();
}
void Speedometer::initAvgBuf() {
this->buf = new int16_t[bufSize];
for (uint8_t i = 0; i < bufSize; i++)
this->buf[i] = 0;
}
void Speedometer::addValToBuf(int16_t val) {
this->buf[this->bufPos] = val;
this->bufPos++;
if (bufPos == bufSize)
bufPos = 0;
}
void Speedometer::updateAvgBufSize() {
delete[] this->buf;
initAvgBuf();
}
int16_t Speedometer::calcAverage() {
int16_t sum = 0;
for (int i = 0; i < this->bufSize; i++)
sum += this->buf[i];
return sum / this->bufSize;
}