Got the refactor building

This commit is contained in:
2024-08-22 23:00:55 -04:00
parent 3e4f0124db
commit 3a49761b66
10 changed files with 274 additions and 224 deletions

View File

@@ -7,19 +7,14 @@
#include "Cube.h"
#include "Vector3D.h"
template <V3D &BOARD_DIMS>
template <const V3D &BOARD_DIMS>
class Board{
public:
enum PLANE_NORMAL : uint32_t{
X = 0,
Y,
Z
};
Board();
~Board() = default;
constexpr V3D &GetSize() const{return BOARD_DIMS;}
constexpr const V3D &GetSize() const{return BOARD_DIMS;}
constexpr uint32_t GetNumberCubes() const{return BOARD_DIMS.x * BOARD_DIMS.y * BOARD_DIMS.z;}
/**
@@ -42,7 +37,7 @@ class Board{
void SetCubeOccupation(const V3D &position, bool occupation);
bool BoardStateChanged(){return this->boardStateHasChanged;}
void ClearBoardStateChanged(){this->boardStateHasChanged = false;}
void SetStateChanged(bool boardState){this->boardStateHasChanged = boardState;}
/**
* @brief Get a column along any axis
@@ -51,7 +46,7 @@ class Board{
* to fill. IE To fill one stack at 0,2 I would say give V3D(0,2,PLANE_NORMAL::Z)
* @returns an array of cubes along that column
*/
Cube * SliceBoard(const V3D &column);
Cube ** SliceBoard(const V3D &column);
private:
// this is a 3d array of cubes to represent the board. Good luck visualizing it
@@ -65,36 +60,34 @@ class Board{
| | /
|____________|/
*/
std::array<std::array<std::array<Cube, Z_SIZE>, Y_SIZE>, X_SIZE> cubes;
std::array<std::array<std::array<Cube, BOARD_DIMS.z>, BOARD_DIMS.y>, BOARD_DIMS.x> cubes;
bool boardStateHasChanged;
};
template <V3D &BOARD_DIMS>
template <const V3D &BOARD_DIMS>
Board<BOARD_DIMS>::Board(){
this->FillColor(Color(0,0,0));
this->FillColor(V3D{});
}
template <V3D &BOARD_DIMS>
template <const V3D &BOARD_DIMS>
void Board<BOARD_DIMS>::ToStackString(String &stringBuffer) const{
std::array<uint32_t, X_SIZE*Y_SIZE> linearizedBoard = this->LinearizeBoard();
std::array<uint32_t, BOARD_DIMS.x*BOARD_DIMS.y> linearizedBoard = this->LinearizeBoard();
stringBuffer += "!" + String(linearizedBoard[0]);
stringBuffer += String(linearizedBoard[0]);
for(uint32_t i = 0; i < X_SIZE * Y_SIZE; i++){
for(uint32_t i = 0; i < BOARD_DIMS.x * BOARD_DIMS.y; i++){
stringBuffer += "," + String(linearizedBoard[i]);
}
stringBuffer += ";";
}
template <V3D &BOARD_DIMS>
template <const V3D &BOARD_DIMS>
std::array<uint32_t, BOARD_DIMS.x * BOARD_DIMS.y> & Board<BOARD_DIMS>::LinearizeBoard() const{
// convert the board into one array where each entry represents the height of one stack
std::array<uint32_t, BOARD_DIMS.x * BOARD_DIMS.y> linearizedBoard;
for(uint32_t x{0}; x < X_SIZE; x++){
for(uint32_t y{0}; y < Y_SIZE; y++){
for(uint32_t z{0}; z < Z_SIZE; z++){
for(uint32_t x{0}; x < BOARD_DIMS.x; x++){
for(uint32_t y{0}; y < BOARD_DIMS.y; y++){
for(uint32_t z{0}; z < BOARD_DIMS.z; z++){
bool isOccupied{this->cubes[x][y][z].isOccupied};
linearizedBoard[x + y*3] += static_cast<uint32_t>(isOccupied);
}
@@ -103,63 +96,63 @@ std::array<uint32_t, BOARD_DIMS.x * BOARD_DIMS.y> & Board<BOARD_DIMS>::Linearize
return linearizedBoard;
}
template <V3D &BOARD_DIMS>
template <const V3D &BOARD_DIMS>
void Board<BOARD_DIMS>::FillColor(const V3D &color){
for(uint32_t x{0}; x < X_SIZE; x++){
for(uint32_t y{0}; y < Y_SIZE; y++){
for(uint32_t z{0}; z < Z_SIZE; z++){
for(uint32_t x{0}; x < BOARD_DIMS.x; x++){
for(uint32_t y{0}; y < BOARD_DIMS.y; y++){
for(uint32_t z{0}; z < BOARD_DIMS.z; z++){
this->cubes[x][y][z].color = color;
}
}
}
}
template <V3D &BOARD_DIMS>
template <const V3D &BOARD_DIMS>
void Board<BOARD_DIMS>::SetCubeColor(const V3D &position, const V3D &color){
this->cubes[position.x][position.y][position.z].color = color;
}
template <V3D &BOARD_DIMS>
template <const V3D &BOARD_DIMS>
void Board<BOARD_DIMS>::SetCubeOccupation(const V3D &position, bool occupation){
bool oldOccupation{this->cubes[position.x][position.y][position.z].occupied};
this->cubes[position.x][position.y][position.z].occupied = occupation;
bool oldOccupation{this->cubes[position.x][position.y][position.z].isOccupied};
this->cubes[position.x][position.y][position.z].isOccupied = occupation;
if(occupation != oldOccupation) this->boardStateHasChanged = true;
}
template <V3D &BOARD_DIMS>
Cube * Board<BOARD_DIMS>::SliceBoard(const V3D &column){
template <const V3D &BOARD_DIMS>
Cube ** Board<BOARD_DIMS>::SliceBoard(const V3D &column){
uint32_t columnLength{0};
V3D indexIncriment{};
V3D position{};
switch(column.z){
case Board::PLANE_NORMAL::X:
case BOARD_TYPES::PLANE_NORMAL::X:
columnLength = BOARD_DIMS.x;
indexIncriment.x = 1;
position.z = column.x;
position.y = column.y;
break;
case Board::PLANE_NORMAL::Y:
columnLength = BOARD_DIMS.Y;
case BOARD_TYPES::PLANE_NORMAL::Y:
columnLength = BOARD_DIMS.y;
indexIncriment.y = 1;
position.x = column.x;
position.z = column.y;
break;
default:
case Board::PLANE_NORMAL::Z:
columnLength = BOARD_DIMS.Z;
case BOARD_TYPES::PLANE_NORMAL::Z:
columnLength = BOARD_DIMS.z;
indexIncriment.z = 1;
position.x = column.x;
position.y = column.y;
break;
}
std::array<Cube *, columnLength> columnSlice;
Cube* columnSlice[columnLength];
for(uint32_t i = 0; i < columnLength; i++){
V3D cubePosition = indexIncriment * i + position;
columnSlice[i] = &(this->cubes[cubePosition.x][cubePosition.y][cubePosition.z]);
}
return columnSlice.data();
return columnSlice;
}

118
lib/Board/BoardDriver.h Normal file
View File

@@ -0,0 +1,118 @@
#pragma once
#include <cstdint>
#include <array>
#include <Adafruit_NeoPixel.h>
#include <Arduino.h>
#include "Cube.h"
#include "BoardTypes.h"
template <uint32_t NUM_STACKS>
class BoardDriver{
public:
BoardDriver(std::array<BOARD_TYPES::CubeStack, NUM_STACKS> &stacks, Adafruit_NeoPixel &pixelController);
~BoardDriver() = default;
void Init();
uint32_t GetNumberCubes(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD);
uint32_t GetNumberCubes(uint32_t stackIndex);
void UpdateStackLEDs(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD, Cube* cubes[], uint32_t numCubes);
void UpdateStackLEDs(uint32_t stackIndex, Cube* cubes[], uint32_t numCubes);
private:
std::array<BOARD_TYPES::CubeStack, NUM_STACKS> &stacks;
Adafruit_NeoPixel &pixelController;
std::array<uint16_t, NUM_STACKS> filteredReadings;
uint32_t xy2StackIndex(uint32_t x_coord, uint32_t y_coord, uint32_t numXStacks){
return x_coord + y_coord*numXStacks;
}
};
template<uint32_t NUM_STACKS>
void BoardDriver<NUM_STACKS>::Init(){
for(uint32_t i = 0; i < NUM_STACKS; i++){
pinMode(this->stacks[i].ledPin, OUTPUT);
}
// begin doesn't really do anything besides setting the pinmode
this->pixelController.begin();
}
template<uint32_t NUM_STACKS>
BoardDriver<NUM_STACKS>::BoardDriver(std::array<BOARD_TYPES::CubeStack, NUM_STACKS> &stacks, Adafruit_NeoPixel &pixelController):
stacks(stacks),
pixelController(pixelController)
{
for(uint32_t i = 0; i < NUM_STACKS; i++){
this->filteredReadings[i] = 0;
}
}
template<uint32_t NUM_STACKS>
void BoardDriver<NUM_STACKS>::UpdateStackLEDs(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD, Cube* cubes[], uint32_t numCubes){
this->UpdateStackLEDs(this->xy2StackIndex(X_COORD, Y_COORD, numXStacks), cubes, numCubes);
}
template<uint32_t NUM_STACKS>
void BoardDriver<NUM_STACKS>::UpdateStackLEDs(uint32_t stackIndex, Cube* cubes[], uint32_t numCubes){
this->pixelController.setPin(this->stacks[stackIndex].ledPin);
for(int i = 0; i < numCubes; i++){
V3D color{cubes[i]->color};
this->pixelController.setPixelColor(i*2, this->pixelController.Color(color.x, color.y, color.z));
this->pixelController.setPixelColor((i*2 + 1), this->pixelController.Color(color.x, color.y, color.z));
}
this->pixelController.show();
}
template<uint32_t NUM_STACKS>
uint32_t BoardDriver<NUM_STACKS>::GetNumberCubes(uint32_t numXStacks, uint32_t X_COORD, uint32_t Y_COORD){
return this->GetNumberCubes(this->xy2StackIndex(X_COORD, Y_COORD, numXStacks));
}
template<uint32_t NUM_STACKS>
uint32_t BoardDriver<NUM_STACKS>::GetNumberCubes(uint32_t stackIndex){
// read the ADC and return the number of cubes
/*
0 cubes: 1 : 4095-3400
1 cube: 1/2 3400-2500
2 cubes: 1/3 2500-1850
3 cubes: 1/4 1850-0
*/
uint16_t value = analogRead(this->stacks[stackIndex].adcPin);
uint16_t lowPassADCRead =
static_cast<uint16_t>(
(static_cast<float>(this->filteredReadings[stackIndex]) * 0.9)
+ (static_cast<float>(value) * 0.1)
);
// temporary definitions to define value ranges:
uint16_t zeroCubesHigh = 4095;
uint16_t zeroCubesLow = 3400;
uint16_t oneCubeLow = 2500;
uint16_t twoCubesLow = 1850;
uint16_t threeCubesLow = 0;
uint8_t stackHeight = 0;
if(lowPassADCRead >= zeroCubesLow && lowPassADCRead <= zeroCubesHigh){
stackHeight = 0;
}
else if(lowPassADCRead >= oneCubeLow){
stackHeight = 1;
}
else if(lowPassADCRead >= twoCubesLow){
stackHeight = 2;
}
else if(lowPassADCRead >= threeCubesLow){
stackHeight = 3;
}
return stackHeight;
}

142
lib/Board/BoardManager.h Normal file
View File

@@ -0,0 +1,142 @@
#pragma once
#include "Board.h"
#include "BoardDriver.h"
#include "Vector3D.h"
template <const V3D &BOARD_DIMS>
class BoardManager{
public:
BoardManager(BoardDriver<BOARD_WIDTH*BOARD_LENGTH> &boardDriver);
~BoardManager() = default;
void Init();
void Update();
void SetCubeColor(const V3D &position, const V3D &color);
void SetColumnColors(const V3D &column, const V3D *color);
/**
* @brief Fill a column along any axis with a color
* @param column .z specifies the normal direction of the plane (see PLANE_NORMAL), and
* the x,y values specify the location of the column in that plane
* to fill. IE To fill one stack at 0,2 I would say give V3D(0,2,PLANE_NORMAL::Z)
* @param color the color you want to fill the column with
*/
void FillColumnColor(const V3D &column, const V3D &color);
bool HasBoardChanged();
void ClearBoardChanged();
String &Board2StackString();
private:
BoardDriver<BOARD_WIDTH*BOARD_LENGTH> &driver;
Board<BOARD_DIMS> board{};
bool hasBoardChanged{false};
void updateBoardColors(const V3D &column);
uint32_t getColumnHeight(BOARD_TYPES::PLANE_NORMAL normal){
switch(normal){
case BOARD_TYPES::PLANE_NORMAL::X:
return BOARD_DIMS.x;
break;
case BOARD_TYPES::PLANE_NORMAL::Y:
return BOARD_DIMS.y;
break;
case BOARD_TYPES::PLANE_NORMAL::Z:
return BOARD_DIMS.z;
break;
default:
return 0;
}
}
};
template <const V3D &BOARD_DIMS>
BoardManager<BOARD_DIMS>::BoardManager(BoardDriver<BOARD_WIDTH*BOARD_LENGTH> &boardDriver):
driver(boardDriver){}
template <const V3D &BOARD_DIMS>
void BoardManager<BOARD_DIMS>::Init(){
this->driver.Init();
}
template <const V3D &BOARD_DIMS>
void BoardManager<BOARD_DIMS>::Update(){
// update the occupied cubes on the board and the cube colors
for(uint32_t x = 0; x < BOARD_DIMS.x; x++){
for(uint32_t y = 0; y < BOARD_DIMS.y; y++){
uint32_t stackIndex{y * BOARD_DIMS.x + x};
uint32_t numCubes{this->driver.GetNumberCubes(stackIndex)};
for(uint32_t z = 0; z < BOARD_DIMS.z; z++){
V3D cubePosition{x, y, z};
this->board.SetCubeOccupation(cubePosition, z < numCubes);
cubePosition.z = BOARD_TYPES::PLANE_NORMAL::Z;
this->driver.UpdateStackLEDs(stackIndex, this->board.SliceBoard(cubePosition), BOARD_DIMS.z);
}
}
}
}
template <const V3D &BOARD_DIMS>
void BoardManager<BOARD_DIMS>::updateBoardColors(const V3D &column){
Cube ** cubeSlice{this->board.SliceBoard(column)};
uint32_t numCubes{this->getColumnHeight(static_cast<BOARD_TYPES::PLANE_NORMAL>(column.z))};
this->driver.UpdateStackLEDs(BOARD_DIMS.x, cubeSlice, numCubes);
}
template <const V3D &BOARD_DIMS>
void BoardManager<BOARD_DIMS>::SetCubeColor(const V3D &position, const V3D &color){
this->board.SetCubeColor(position, color);
V3D slice{position.x, position.y, BOARD_TYPES::PLANE_NORMAL::Z};
this->updateBoardColors(slice);
}
template <const V3D &BOARD_DIMS>
void BoardManager<BOARD_DIMS>::SetColumnColors(const V3D &column, const V3D *color){
uint32_t columnHeight{this->getColumnHeight(static_cast<BOARD_TYPES::PLANE_NORMAL>(column.z))};
V3D position = column;
for(uint32_t z = 0; z < columnHeight; z++){
position.z = z;
this->board.SetCubeColor(position, color[z]);
}
this->updateBoardColors(column);
}
template <const V3D &BOARD_DIMS>
void BoardManager<BOARD_DIMS>::FillColumnColor(const V3D &column, const V3D &color){
uint32_t columnHeight{this->getColumnHeight(column.z)};
V3D position = column;
for(uint32_t z = 0; z < columnHeight; z++){
position.z = z;
this->board.SetCubeColor(position, color);
}
this->updateBoardColors(column);
}
template <const V3D &BOARD_DIMS>
bool BoardManager<BOARD_DIMS>::HasBoardChanged(){return this->hasBoardChanged;}
template <const V3D &BOARD_DIMS>
void BoardManager<BOARD_DIMS>::ClearBoardChanged(){this->hasBoardChanged = false;}
template <const V3D &BOARD_DIMS>
String &BoardManager<BOARD_DIMS>::Board2StackString(){
String message{};
this->board.ToStackString(message);
return message;
}

16
lib/Board/BoardTypes.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
#include <cstdint>
namespace BOARD_TYPES{
struct CubeStack{
uint8_t adcPin;
uint8_t ledPin;
};
enum PLANE_NORMAL : uint32_t{
X = 0,
Y,
Z
};
};

14
lib/Board/Cube.h Normal file
View File

@@ -0,0 +1,14 @@
/**
* @file Cube.h
* @brief An object to store the data of one cube
*/
#pragma once
#include "Vector3D.h"
class Cube{
public:
V3D color;
bool isOccupied{false};
};