Added abstract boot sequence to handle events and iteration count.

Implemented KnightRider bootsequence (KittBootSequence).
This commit is contained in:
T. van der Zwan 2013-09-09 15:24:36 +00:00
parent db708da60a
commit a567f0feeb
7 changed files with 198 additions and 59 deletions

View File

@ -0,0 +1,35 @@
#include "AbstractBootSequence.h"
AbstractBootSequence::AbstractBootSequence(Hyperion * hyperion, const int64_t interval, const unsigned iterationCnt) :
_timer(),
_hyperion(hyperion),
_priority(0),
_iterationCounter(iterationCnt)
{
_timer.setInterval(interval);
_timer.setSingleShot(false);
QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
}
void AbstractBootSequence::start()
{
_timer.start();
}
void AbstractBootSequence::update()
{
if (_iterationCounter == 0)
{
_timer.stop();
_hyperion->clear(_priority);
return;
}
// Obtain the next led-colors from the child-class
const std::vector<RgbColor>& colors = nextColors();
// Write the colors to hyperion
_hyperion->setColors(_priority, colors, -1);
// Decrease the loop count
--_iterationCounter;
}

View File

@ -0,0 +1,40 @@
#pragma once
// QT includes
#include <QTimer>
// Bootsequence includes
#include <bootsequence/BootSequence.h>
// Hyperion includes
#include <hyperion/Hyperion.h>
class AbstractBootSequence : public QObject, public BootSequence
{
Q_OBJECT
public:
AbstractBootSequence(Hyperion * hyperion, const int64_t interval, const unsigned iterationCnt);
virtual void start();
protected slots:
void update();
protected:
virtual const std::vector<RgbColor>& nextColors() = 0;
private:
/// The timer used to generate an 'update' signal every interval
QTimer _timer;
/// The Hyperion instance
Hyperion * _hyperion;
/// The priority of the boot sequence
int _priority;
/// The counter of the number of iterations left
int _iterationCounter;
};

View File

@ -5,17 +5,21 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/bootsequence)
# Group the headers that go through the MOC compiler
SET(BootsequenceQT_HEADERS
${CURRENT_SOURCE_DIR}/RainbowBootSequence.h
${CURRENT_SOURCE_DIR}/AbstractBootSequence.h
)
SET(BootsequenceHEADERS
${CURRENT_HEADER_DIR}/BootSequence.h
${CURRENT_HEADER_DIR}/BootSequenceFactory.h
${CURRENT_SOURCE_DIR}/RainbowBootSequence.h
${CURRENT_SOURCE_DIR}/KittBootSequence.h
)
SET(BootsequenceSOURCES
${CURRENT_SOURCE_DIR}/AbstractBootSequence.cpp
${CURRENT_SOURCE_DIR}/BootSequenceFactory.cpp
${CURRENT_SOURCE_DIR}/RainbowBootSequence.cpp
${CURRENT_SOURCE_DIR}/KittBootSequence.cpp
)
QT4_WRAP_CPP(BootsequenceHEADERS_MOC ${BootsequenceQT_HEADERS})

View File

@ -0,0 +1,67 @@
// Hyperion includes
#include <hyperion/ImageProcessorFactory.h>
// Local-Bootsequence includes
#include "KittBootSequence.h"
KittBootSequence::KittBootSequence(Hyperion * hyperion, const unsigned duration_ms) :
AbstractBootSequence(hyperion, 100, duration_ms/100),
_processor(ImageProcessorFactory::getInstance().newImageProcessor()),
_image(9, 1),
_ledColors(hyperion->getLedCount(), RgbColor::BLACK),
_forwardMove(false),
_currentLight(0)
{
// empty
}
KittBootSequence::~KittBootSequence()
{
delete _processor;
}
const std::vector<RgbColor>& KittBootSequence::nextColors()
{
// Switch the previous light 'off'
_image(_currentLight, 0) = RgbColor::BLACK;
// Move the current to the next light
moveNextLight();
// Switch the current light 'on'
_image(_currentLight, 0) = RgbColor::RED;
// Translate the 'image' to led colors
_processor->process(_image, _ledColors);
// Return the colors
return _ledColors;
}
void KittBootSequence::moveNextLight()
{
// Increase/Decrease the current light
if (_forwardMove)
{
++_currentLight;
if (_currentLight == _image.width())
{
_forwardMove = false;
--_currentLight;
}
}
else
{
if (_currentLight == 0)
{
_forwardMove = true;
}
else
{
--_currentLight;
}
}
}

View File

@ -0,0 +1,36 @@
#pragma once
// Bootsequence includes
#include "AbstractBootSequence.h"
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <hyperion/ImageProcessor.h>
class KittBootSequence : public AbstractBootSequence
{
public:
KittBootSequence(Hyperion * hyperion, const unsigned duration_ms);
virtual ~KittBootSequence();
virtual const std::vector<RgbColor>& nextColors();
private:
/// Image processor to compute led-colors from the image
ImageProcessor * _processor;
/// 1D-Image of the KITT-grill contains a single red pixel and the rest black
RgbImage _image;
/// The vector with led-colors
std::vector<RgbColor> _ledColors;
bool _forwardMove = true;
unsigned _currentLight = 0;
void moveNextLight();
};

View File

@ -6,49 +6,25 @@
#include "RainbowBootSequence.h"
RainbowBootSequence::RainbowBootSequence(Hyperion * hyperion, const unsigned duration_ms) :
_timer(),
_hyperion(hyperion),
_priority(0),
_ledColors(hyperion->getLedCount()),
_iterationCounter(hyperion->getLedCount())
AbstractBootSequence(hyperion, duration_ms/hyperion->getLedCount(), hyperion->getLedCount()),
_ledColors(hyperion->getLedCount())
{
for (unsigned iLed=0; iLed<_hyperion->getLedCount(); ++iLed)
for (unsigned iLed=0; iLed<hyperion->getLedCount(); ++iLed)
{
RgbColor& color = _ledColors[iLed];
HsvTransform::hsv2rgb(iLed*360/_hyperion->getLedCount(), 255, 255, color.red, color.green, color.blue);
HsvTransform::hsv2rgb(iLed*360/hyperion->getLedCount(), 255, 255, color.red, color.green, color.blue);
}
_timer.setInterval(duration_ms/_hyperion->getLedCount());
_timer.setSingleShot(false);
QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(update()));
}
void RainbowBootSequence::start()
const std::vector<RgbColor>& RainbowBootSequence::nextColors()
{
_timer.start();
}
void RainbowBootSequence::update()
{
if (_iterationCounter == 0)
// Rotate the colors left
const RgbColor headColor = _ledColors.front();
for (unsigned i=1; i<_ledColors.size(); ++i)
{
_timer.stop();
_hyperion->clear(_priority);
_ledColors[i-1] = _ledColors[i];
}
else
{
// Rotate the colors left
const RgbColor headColor = _ledColors.front();
for (unsigned i=1; i<_ledColors.size(); ++i)
{
_ledColors[i-1] = _ledColors[i];
}
_ledColors.back() = headColor;
_ledColors.back() = headColor;
// Write the colors to hyperion
_hyperion->setColors(_priority, _ledColors, -1);
// Decrease the loop count
--_iterationCounter;
}
return _ledColors;
}

View File

@ -5,19 +5,14 @@
#include <QTimer>
// Bootsequence include
#include <bootsequence/BootSequence.h>
// Hyperion includes
#include <hyperion/Hyperion.h>
#include "AbstractBootSequence.h"
///
/// The RainborBootSequence shows a 'rainbow' (all lights have a different color). The rainbow is
/// rotated over each led during the length of the sequence.
///
class RainbowBootSequence : public QObject, public BootSequence
class RainbowBootSequence : public AbstractBootSequence
{
Q_OBJECT
public:
///
/// Constructs the rainbow boot-sequence. Hyperion is used for writing the led colors. The given
@ -28,27 +23,13 @@ public:
///
RainbowBootSequence(Hyperion * hyperion, const unsigned duration_ms);
///
/// Starts the boot-sequence
///
virtual void start();
private slots:
protected:
///
/// Moves the rainbow one led further
///
void update();
const std::vector<RgbColor>& nextColors();
private:
/// The timer used to generate an 'update' signal every interval
QTimer _timer;
/// The Hyperion instance
Hyperion * _hyperion;
/// The priority of the boot sequence
int _priority;
/// The current color of the boot sequence (the rainbow)
std::vector<RgbColor> _ledColors;
/// The counter of the number of iterations left