From 50de931e8ae5f34a0b7a5ba5de5e2e2f39a8dc74 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 7 Dec 2024 16:09:15 +0100 Subject: [PATCH 01/17] =?UTF-8?q?=F0=9F=98=9B=20quadratic=20bezier=20curve?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- organism/Makefile | 21 ++++++++ organism/platformio.ini | 22 +++++++++ organism/src/main.cpp | 105 ++++++++++++++++++++++++++++++++++++++++ organism/src/main.h | 10 ++++ 4 files changed, 158 insertions(+) create mode 100644 organism/Makefile create mode 100644 organism/platformio.ini create mode 100644 organism/src/main.cpp create mode 100644 organism/src/main.h diff --git a/organism/Makefile b/organism/Makefile new file mode 100644 index 0000000..c5e3ab2 --- /dev/null +++ b/organism/Makefile @@ -0,0 +1,21 @@ +# Uncomment lines below if you have problems with $PATH +#SHELL := /bin/bash +#PATH := /usr/local/bin:$(PATH) + +all: + pio.exe -f -c vim run + +upload: + pio.exe -f -c vim run --target upload + +clean: + pio.exe -f -c vim run --target clean + +program: + pio.exe -f -c vim run --target program + +uploadfs: + pio.exe -f -c vim run --target uploadfs + +update: + pio.exe -f -c vim update diff --git a/organism/platformio.ini b/organism/platformio.ini new file mode 100644 index 0000000..0e62411 --- /dev/null +++ b/organism/platformio.ini @@ -0,0 +1,22 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:adafruit_matrixportal_esp32s3] +platform = espressif32 +board = adafruit_matrixportal_esp32s3 +framework = arduino +monitor_speed = 115200 + +lib_deps = + adafruit/Adafruit GFX Library + adafruit/Adafruit BusIO + Wire + fastled/FastLED + https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA.git diff --git a/organism/src/main.cpp b/organism/src/main.cpp new file mode 100644 index 0000000..c14dad6 --- /dev/null +++ b/organism/src/main.cpp @@ -0,0 +1,105 @@ +#include +#include "xtensa/core-macros.h" +#include + +#include "main.h" + +#define R1 42 +#define G1 40 +#define BL1 41 +#define R2 38 +#define G2 37 +#define BL2 39 +#define CH_A 45 +#define CH_B 36 +#define CH_C 48 +#define CH_D 35 +#define CH_E 21 +#define CLK 2 +#define LAT 47 +#define OE 14 + +#define PIN_E 21 +#define PANEL_WIDTH 64 +#define PANEL_HEIGHT 32 // Panel height of 64 will required PIN_E to be defined. + +#define PANELS_NUMBER 1 + +#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER +#define PANE_HEIGHT PANEL_HEIGHT +#define NUM_LEDS PANE_WIDTH*PANE_HEIGHT + +#define ONBOARD_LED 13 + +MatrixPanel_I2S_DMA *matrix = nullptr; + +int start_x = 5; +int start_y = 5; +int end_x = 59; +int end_y = 27; + +int anchor_x = 16; +int anchor_y = 24; + +void setup(){ + Serial.begin(BAUD_RATE); + pinMode(ONBOARD_LED, OUTPUT); + + // redefine pins if required + HUB75_I2S_CFG::i2s_pins _pins={R1, G1, BL1, R2, G2, BL2, CH_A, CH_B, CH_C, CH_D, CH_E, LAT, OE, CLK}; + HUB75_I2S_CFG mxconfig(PANEL_WIDTH, PANEL_HEIGHT, PANELS_NUMBER, _pins); + + mxconfig.gpio.e = PIN_E; + mxconfig.driver = HUB75_I2S_CFG::FM6126A; // for panels using FM6126A chips + + mxconfig.latch_blanking = 4; + mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M; + mxconfig.clkphase = false; + + //mxconfig.double_buff = true; + + matrix = new MatrixPanel_I2S_DMA(mxconfig); + matrix->begin(); + matrix->setBrightness8(64); + matrix->fillScreenRGB888(0, 0, 0); +} + +int interpolate(int from, int to, float percent) { + int difference = to - from; + return from + ( difference * percent ); +} + +void draw_bezier(int x1, int y1, int x2, int y2, int x3, int y3, float percent) { + // draw lines to p2 + matrix->drawLine(x1, y1, x2, y2, matrix->color565(16, 16, 16)); + matrix->drawLine(x2, y2, x3, y3, matrix->color565(16, 16, 16)); + + int xa = interpolate(x1, x2, percent); + int ya = interpolate(y1, y2, percent); + int xb = interpolate(x2, x3, percent); + int yb = interpolate(y2, y3, percent); + //matrix->drawLine(xa, ya, xb, yb, matrix->color565(0, 128, 0)); + + int x = interpolate(xa, xb, percent); + int y = interpolate(ya, yb, percent); + + matrix->drawPixel(x, y, matrix->color565(255, 255, 255)); +} + +void loop() { + // matrix ->flipDMABuffer(); + matrix->clearScreen(); + // delay(25); + anchor_y += 1; + if (anchor_y >= 32) { + anchor_y = 0; + } + for (float i = 0; i < 1; i += 0.02) { + draw_bezier(start_x, start_y, anchor_x, anchor_y, end_x, end_y, i); + } + matrix->drawPixel(start_x, start_y, matrix->color565(255, 0, 0)); + matrix->drawPixel(end_x, end_y, matrix->color565(255, 0, 0)); + matrix->drawPixel(anchor_x, anchor_y, matrix->color565(255, 0, 255)); + delay(100); +} + diff --git a/organism/src/main.h b/organism/src/main.h new file mode 100644 index 0000000..e4e784a --- /dev/null +++ b/organism/src/main.h @@ -0,0 +1,10 @@ +#include + +#define BAUD_RATE 115200 // serial debug port baud rate + +void buffclear(CRGB *buf); +uint16_t XY16( uint16_t x, uint16_t y); +void mxfill(CRGB *leds); +uint16_t colorWheel(uint8_t pos); +void drawText(int colorWheelOffset); + From 91c1bc50f317c62ca57eea9df23d65ac03e8dcf8 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 7 Dec 2024 19:24:18 +0100 Subject: [PATCH 02/17] basic blob --- organism/src/main.cpp | 86 ++++++++++++++++++++++++++++++++----------- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index c14dad6..f72484d 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -41,6 +41,15 @@ int end_y = 27; int anchor_x = 16; int anchor_y = 24; +#define BLOB_POINTS 14 +#define BLOB_RADIUS 12 +typedef struct { + int x_coords[BLOB_POINTS]; + int y_coords[BLOB_POINTS]; +} Blob; + +Blob blob; + void setup(){ Serial.begin(BAUD_RATE); pinMode(ONBOARD_LED, OUTPUT); @@ -62,6 +71,15 @@ void setup(){ matrix->begin(); matrix->setBrightness8(64); matrix->fillScreenRGB888(0, 0, 0); + + for(int i = 0; i < BLOB_POINTS; i++) { + //float angle = (360 / BLOB_POINTS) * (i+1); + float angle = ((PI * 2) / BLOB_POINTS) * (i+1); + blob.x_coords[i] = random(-6, 7) + 31 + round(BLOB_RADIUS * sin(angle)); + blob.y_coords[i] = random(-2, 7) + 15 + round(BLOB_RADIUS * cos(angle)); + //blob.x_coords[i] = random(0, 64); + //blob.y_coords[i] = random(0, 32); + } } int interpolate(int from, int to, float percent) { @@ -69,37 +87,61 @@ int interpolate(int from, int to, float percent) { return from + ( difference * percent ); } -void draw_bezier(int x1, int y1, int x2, int y2, int x3, int y3, float percent) { +void draw_bezier(int x1, int y1, int x2, int y2, int x3, int y3) { // draw lines to p2 - matrix->drawLine(x1, y1, x2, y2, matrix->color565(16, 16, 16)); - matrix->drawLine(x2, y2, x3, y3, matrix->color565(16, 16, 16)); + //matrix->drawLine(x1, y1, x2, y2, matrix->color565(16, 16, 16)); + //matrix->drawLine(x2, y2, x3, y3, matrix->color565(16, 16, 16)); - int xa = interpolate(x1, x2, percent); - int ya = interpolate(y1, y2, percent); - int xb = interpolate(x2, x3, percent); - int yb = interpolate(y2, y3, percent); - //matrix->drawLine(xa, ya, xb, yb, matrix->color565(0, 128, 0)); + for (float percent = 0; percent < 1; percent += 0.02) { + int xa = interpolate(x1, x2, percent); + int ya = interpolate(y1, y2, percent); + int xb = interpolate(x2, x3, percent); + int yb = interpolate(y2, y3, percent); + //matrix->drawLine(xa, ya, xb, yb, matrix->color565(0, 128, 0)); - int x = interpolate(xa, xb, percent); - int y = interpolate(ya, yb, percent); + int x = interpolate(xa, xb, percent); + int y = interpolate(ya, yb, percent); - matrix->drawPixel(x, y, matrix->color565(255, 255, 255)); + matrix->drawPixel(x, y, matrix->color565(255, 80, 83)); + } } + + void loop() { // matrix ->flipDMABuffer(); - matrix->clearScreen(); - // delay(25); - anchor_y += 1; - if (anchor_y >= 32) { - anchor_y = 0; + //matrix->clearScreen(); + matrix->fillScreenRGB888(15, 0, 10); + // draw grid + + int h_lines = PANEL_HEIGHT / 7; + int v_lines = PANEL_WIDTH / 7; + for(int i = 0; i < PANEL_WIDTH; i++) { + if(i % 7 == 2) { + matrix->drawFastVLine(i, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); + } } - for (float i = 0; i < 1; i += 0.02) { - draw_bezier(start_x, start_y, anchor_x, anchor_y, end_x, end_y, i); + for(int i = 0; i <= h_lines; i++) { + matrix->drawFastHLine(0, 7*i + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); } - matrix->drawPixel(start_x, start_y, matrix->color565(255, 0, 0)); - matrix->drawPixel(end_x, end_y, matrix->color565(255, 0, 0)); - matrix->drawPixel(anchor_x, anchor_y, matrix->color565(255, 0, 255)); - delay(100); + + for(int i = 0; i < BLOB_POINTS; i+=2) { + int end_offset = i + 2; + if ( end_offset >= BLOB_POINTS) { + end_offset = 0; + } + draw_bezier(blob.x_coords[i], + blob.y_coords[i], + blob.x_coords[i+1], + blob.y_coords[i+1], + blob.x_coords[end_offset], + blob.y_coords[end_offset] + ); + matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); + //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(0, 0, 128)); + //matrix->drawPixel(blob.x_coords[i+1], blob.y_coords[i+1], matrix->color565(128, 0, 0)); + //matrix->drawPixel(blob.x_coords[end_offset], blob.y_coords[end_offset], matrix->color565(0, 0, 128)); + } + delay(500); } From 4a7a3fd0089e12f4c8a9e15646a0157dde829674 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 7 Dec 2024 19:54:30 +0100 Subject: [PATCH 03/17] lookin okay --- organism/src/main.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index f72484d..3fa5a83 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -41,7 +41,7 @@ int end_y = 27; int anchor_x = 16; int anchor_y = 24; -#define BLOB_POINTS 14 +#define BLOB_POINTS 32 #define BLOB_RADIUS 12 typedef struct { int x_coords[BLOB_POINTS]; @@ -65,7 +65,7 @@ void setup(){ mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_10M; mxconfig.clkphase = false; - //mxconfig.double_buff = true; + mxconfig.double_buff = true; matrix = new MatrixPanel_I2S_DMA(mxconfig); matrix->begin(); @@ -92,7 +92,7 @@ void draw_bezier(int x1, int y1, int x2, int y2, int x3, int y3) { //matrix->drawLine(x1, y1, x2, y2, matrix->color565(16, 16, 16)); //matrix->drawLine(x2, y2, x3, y3, matrix->color565(16, 16, 16)); - for (float percent = 0; percent < 1; percent += 0.02) { + for (float percent = 0; percent < 1; percent += 0.01) { int xa = interpolate(x1, x2, percent); int ya = interpolate(y1, y2, percent); int xb = interpolate(x2, x3, percent); @@ -109,7 +109,7 @@ void draw_bezier(int x1, int y1, int x2, int y2, int x3, int y3) { void loop() { - // matrix ->flipDMABuffer(); + matrix ->flipDMABuffer(); //matrix->clearScreen(); matrix->fillScreenRGB888(15, 0, 10); // draw grid @@ -137,7 +137,15 @@ void loop() { blob.x_coords[end_offset], blob.y_coords[end_offset] ); - matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); + //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); + blob.x_coords[i+1] += random(-1, 2); + if (blob.x_coords[i+1] >= PANEL_WIDTH) { + blob.x_coords[i+1] = PANEL_WIDTH - 1; + } + if (blob.x_coords[i+1] < 0) { + blob.x_coords[i+1] = 0; + } + //blob.y_coords[i+1] += random(-1, 2); //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(0, 0, 128)); //matrix->drawPixel(blob.x_coords[i+1], blob.y_coords[i+1], matrix->color565(128, 0, 0)); //matrix->drawPixel(blob.x_coords[end_offset], blob.y_coords[end_offset], matrix->color565(0, 0, 128)); From 4f5cc216dd11b8dcef61dc228a28c7f0d1873ca2 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sun, 8 Dec 2024 15:40:14 +0100 Subject: [PATCH 04/17] color --- organism/src/main.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index 3fa5a83..b37f71e 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -102,7 +102,7 @@ void draw_bezier(int x1, int y1, int x2, int y2, int x3, int y3) { int x = interpolate(xa, xb, percent); int y = interpolate(ya, yb, percent); - matrix->drawPixel(x, y, matrix->color565(255, 80, 83)); + matrix->drawPixel(x, y, matrix->color565(106, 95, 219)); } } @@ -137,12 +137,12 @@ void loop() { blob.x_coords[end_offset], blob.y_coords[end_offset] ); - //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); + matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); blob.x_coords[i+1] += random(-1, 2); if (blob.x_coords[i+1] >= PANEL_WIDTH) { blob.x_coords[i+1] = PANEL_WIDTH - 1; } - if (blob.x_coords[i+1] < 0) { + if (blob.x_coords[i+1] < 0) { blob.x_coords[i+1] = 0; } //blob.y_coords[i+1] += random(-1, 2); From 7ef3ba9acbe31644e23aca4a8cb90bd1a7257a4b Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sun, 8 Dec 2024 18:11:22 +0100 Subject: [PATCH 05/17] =?UTF-8?q?=F0=9F=8D=84=20growing=20thing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- organism/src/main.cpp | 131 ++++++++++++++++++++++++++++++++---------- 1 file changed, 100 insertions(+), 31 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index b37f71e..c078de0 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -48,6 +48,19 @@ typedef struct { int y_coords[BLOB_POINTS]; } Blob; + +#define NUM_AGENTS 64 +#define AGENT_MOVE_DISTANCE 1 +#define AGENT_DROP_AMOUNT 100 +typedef struct { + int x_position; + int y_position; + float heading; +} SlimeAgent; + +uint16_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; +SlimeAgent agents[NUM_AGENTS]; + Blob blob; void setup(){ @@ -72,13 +85,23 @@ void setup(){ matrix->setBrightness8(64); matrix->fillScreenRGB888(0, 0, 0); - for(int i = 0; i < BLOB_POINTS; i++) { - //float angle = (360 / BLOB_POINTS) * (i+1); - float angle = ((PI * 2) / BLOB_POINTS) * (i+1); - blob.x_coords[i] = random(-6, 7) + 31 + round(BLOB_RADIUS * sin(angle)); - blob.y_coords[i] = random(-2, 7) + 15 + round(BLOB_RADIUS * cos(angle)); - //blob.x_coords[i] = random(0, 64); - //blob.y_coords[i] = random(0, 32); + //for(int i = 0; i < BLOB_POINTS; i++) { + // //float angle = (360 / BLOB_POINTS) * (i+1); + // float angle = ((PI * 2) / BLOB_POINTS) * (i+1); + // blob.x_coords[i] = random(-6, 7) + 31 + round(BLOB_RADIUS * sin(angle)); + // blob.y_coords[i] = random(-2, 7) + 15 + round(BLOB_RADIUS * cos(angle)); + // //blob.x_coords[i] = random(0, 64); + // //blob.y_coords[i] = random(0, 32); + //} + for(int a = 0; a < NUM_AGENTS; a++) { + agents[a].x_position = random(12, 52); + agents[a].y_position = random(12, 20); + agents[a].heading = (random(0, 100) / 100.0) * (PI*2); + } + for(int x = 0; x= 0) and (y >= 0); +} void loop() { matrix ->flipDMABuffer(); @@ -125,31 +151,74 @@ void loop() { matrix->drawFastHLine(0, 7*i + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); } - for(int i = 0; i < BLOB_POINTS; i+=2) { - int end_offset = i + 2; - if ( end_offset >= BLOB_POINTS) { - end_offset = 0; + for(int x = 0; xdrawPixel(x, y, attractant[x][y]); } - draw_bezier(blob.x_coords[i], - blob.y_coords[i], - blob.x_coords[i+1], - blob.y_coords[i+1], - blob.x_coords[end_offset], - blob.y_coords[end_offset] - ); - matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); - blob.x_coords[i+1] += random(-1, 2); - if (blob.x_coords[i+1] >= PANEL_WIDTH) { - blob.x_coords[i+1] = PANEL_WIDTH - 1; - } - if (blob.x_coords[i+1] < 0) { - blob.x_coords[i+1] = 0; - } - //blob.y_coords[i+1] += random(-1, 2); - //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(0, 0, 128)); - //matrix->drawPixel(blob.x_coords[i+1], blob.y_coords[i+1], matrix->color565(128, 0, 0)); - //matrix->drawPixel(blob.x_coords[end_offset], blob.y_coords[end_offset], matrix->color565(0, 0, 128)); } - delay(500); + + for(int a = 0; a < NUM_AGENTS; a++) { + matrix->drawPixel(agents[a].x_position, agents[a].y_position, attractant[agents[a].x_position][agents[a].y_position]); + // motor step + // check if agent can move forward + float target_x = agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE; + float target_y = agents[a].y_position + sin(agents[a].heading) * AGENT_MOVE_DISTANCE; + int move_x = round(target_x); + int move_y = round(target_y); + if (is_in_bounds(move_x, move_y)) { + agents[a].x_position = move_x; + agents[a].y_position = move_y; + attractant[move_x][move_y] += AGENT_DROP_AMOUNT; + } else { + agents[a].heading += (random(0,2) *2 -1 ) * (random(0, 30) / 100.0) * PI*2; + } + // sample step + int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE); + int front_y = round(agents[a].y_position + sin(agents[a].heading) * AGENT_MOVE_DISTANCE); + int left_x = round(agents[a].x_position + cos(agents[a].heading - ((random(0,30) / 100.0) * (PI * 2)))); + int left_y = round(agents[a].y_position + cos(agents[a].heading - ((random(0,30) / 100.0) * (PI * 2)))); + int right_x = round(agents[a].x_position + cos(agents[a].heading + ((random(0,30) / 100.0) * (PI * 2)))); + int right_y = round(agents[a].y_position + cos(agents[a].heading + ((random(0,30) / 100.0) * (PI * 2)))); + int front_value = attractant[front_x][front_y]; + int left_value = attractant[left_x][left_y]; + int right_value = attractant[right_x][right_y]; + if (front_value > right_value and front_value > left_value) { + ; + } else if (front_value < right_value and front_value < left_value) { + agents[a].heading += (random(0, 2) * 2 - 1) * (random(0, 30) / 100.0) * (PI*2) ; + } else if (left_value > right_value) { + agents[a].heading -= ((random(0,30) / 100.0) * (PI * 2)); + } else { + agents[a].heading += ((random(0,30) / 100.0) * (PI * 2)); + } + } + + + //for(int i = 0; i < BLOB_POINTS; i+=2) { + // int end_offset = i + 2; + // if ( end_offset >= BLOB_POINTS) { + // end_offset = 0; + // } + // draw_bezier(blob.x_coords[i], + // blob.y_coords[i], + // blob.x_coords[i+1], + // blob.y_coords[i+1], + // blob.x_coords[end_offset], + // blob.y_coords[end_offset] + // ); + // matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); + // blob.x_coords[i+1] += random(-1, 2); + // if (blob.x_coords[i+1] >= PANEL_WIDTH) { + // blob.x_coords[i+1] = PANEL_WIDTH - 1; + // } + // if (blob.x_coords[i+1] < 0) { + // blob.x_coords[i+1] = 0; + // } + // //blob.y_coords[i+1] += random(-1, 2); + // //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(0, 0, 128)); + // //matrix->drawPixel(blob.x_coords[i+1], blob.y_coords[i+1], matrix->color565(128, 0, 0)); + // //matrix->drawPixel(blob.x_coords[end_offset], blob.y_coords[end_offset], matrix->color565(0, 0, 128)); + //} + delay(100); } From 487f5880d7e6badede398a8247acb4646e7077e0 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Tue, 10 Dec 2024 10:49:03 +0100 Subject: [PATCH 06/17] =?UTF-8?q?=F0=9F=8D=83=20lots=20of=20fixes=20and=20?= =?UTF-8?q?clean=20up?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- organism/src/main.cpp | 196 +++++++++++++++++------------------------- 1 file changed, 80 insertions(+), 116 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index c078de0..b219f0f 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -33,35 +33,46 @@ MatrixPanel_I2S_DMA *matrix = nullptr; -int start_x = 5; -int start_y = 5; -int end_x = 59; -int end_y = 27; - -int anchor_x = 16; -int anchor_y = 24; - -#define BLOB_POINTS 32 -#define BLOB_RADIUS 12 -typedef struct { - int x_coords[BLOB_POINTS]; - int y_coords[BLOB_POINTS]; -} Blob; - - #define NUM_AGENTS 64 #define AGENT_MOVE_DISTANCE 1 -#define AGENT_DROP_AMOUNT 100 +#define AGENT_DROP_AMOUNT 1 +#define AGENT_ANGLE 0.175 +#define NUM_ITERATIONS 1000 typedef struct { int x_position; int y_position; float heading; } SlimeAgent; -uint16_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; +uint8_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; +int iterations = 0; SlimeAgent agents[NUM_AGENTS]; -Blob blob; +void init_attractant() { + memset(attractant, (uint8_t) 0, sizeof attractant); + // draw a circle out of attractant + //for (int p = 0; p < 64; p++) { + // float angle = ((PI * 2) / 64) * p; + // int x = 31 + round(10 * sin(angle)); + // int y = 15 + round(10 * cos(angle)); + // attractant[x][y] = 15; + //} +} + +void init_agents() { + for(int a = 0; a < NUM_AGENTS; a++) { + float angle = ((PI * 2) / NUM_AGENTS) * a; + //agents[a].x_position = 31 + round(10*sin(angle)); + //agents[a].y_position = 15 + round(10*cos(angle)); + // agents[a].heading = ((PI * 2) / NUM_AGENTS) * ); + + agents[a].x_position = random(12, 52); + agents[a].y_position = random(12, 20); + agents[a].heading = (random(0, 100) / 100.0) * (PI*2); + } +} + + void setup(){ Serial.begin(BAUD_RATE); @@ -85,80 +96,51 @@ void setup(){ matrix->setBrightness8(64); matrix->fillScreenRGB888(0, 0, 0); - //for(int i = 0; i < BLOB_POINTS; i++) { - // //float angle = (360 / BLOB_POINTS) * (i+1); - // float angle = ((PI * 2) / BLOB_POINTS) * (i+1); - // blob.x_coords[i] = random(-6, 7) + 31 + round(BLOB_RADIUS * sin(angle)); - // blob.y_coords[i] = random(-2, 7) + 15 + round(BLOB_RADIUS * cos(angle)); - // //blob.x_coords[i] = random(0, 64); - // //blob.y_coords[i] = random(0, 32); - //} - for(int a = 0; a < NUM_AGENTS; a++) { - agents[a].x_position = random(12, 52); - agents[a].y_position = random(12, 20); - agents[a].heading = (random(0, 100) / 100.0) * (PI*2); - } - for(int x = 0; xdrawLine(x1, y1, x2, y2, matrix->color565(16, 16, 16)); - //matrix->drawLine(x2, y2, x3, y3, matrix->color565(16, 16, 16)); - - for (float percent = 0; percent < 1; percent += 0.01) { - int xa = interpolate(x1, x2, percent); - int ya = interpolate(y1, y2, percent); - int xb = interpolate(x2, x3, percent); - int yb = interpolate(y2, y3, percent); - //matrix->drawLine(xa, ya, xb, yb, matrix->color565(0, 128, 0)); - - int x = interpolate(xa, xb, percent); - int y = interpolate(ya, yb, percent); - - matrix->drawPixel(x, y, matrix->color565(106, 95, 219)); - } -} - - bool is_in_bounds(int x, int y) { return (x < PANEL_WIDTH) and (y < PANEL_HEIGHT) and (x >= 0) and (y >= 0); } +void draw_bg() { + int h_lines = round(PANEL_HEIGHT / 7); + int v_lines = round(PANEL_WIDTH / 7); + for(int v = 0; v <= v_lines; v++) { + matrix->drawFastVLine(v*7+2, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); + } + for(int h = 0; h <= h_lines; h++) { + matrix->drawFastHLine(0, 7*h + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); + } +} + +void draw_attractant() { + for(int x = 0; x 20) { + matrix->drawPixel(x, y, matrix->color565( + int((255.0 / 255.0) * attractant[x][y]), + int((80.0 / 255.0) * attractant[x][y]), + int((83.0 / 255.0) * attractant[x][y]) + ) + ); + } + } + } +} + void loop() { matrix ->flipDMABuffer(); //matrix->clearScreen(); matrix->fillScreenRGB888(15, 0, 10); - // draw grid - int h_lines = PANEL_HEIGHT / 7; - int v_lines = PANEL_WIDTH / 7; - for(int i = 0; i < PANEL_WIDTH; i++) { - if(i % 7 == 2) { - matrix->drawFastVLine(i, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); - } - } - for(int i = 0; i <= h_lines; i++) { - matrix->drawFastHLine(0, 7*i + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); - } - - for(int x = 0; xdrawPixel(x, y, attractant[x][y]); - } - } + // draw background and organism + draw_bg(); + draw_attractant(); for(int a = 0; a < NUM_AGENTS; a++) { - matrix->drawPixel(agents[a].x_position, agents[a].y_position, attractant[agents[a].x_position][agents[a].y_position]); + //matrix->drawPixel(agents[a].x_position, agents[a].y_position, matrix->color565(0, 0, attractant[agents[a].x_position][agents[a].y_position])); // motor step // check if agent can move forward float target_x = agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE; @@ -168,57 +150,39 @@ void loop() { if (is_in_bounds(move_x, move_y)) { agents[a].x_position = move_x; agents[a].y_position = move_y; - attractant[move_x][move_y] += AGENT_DROP_AMOUNT; + if (attractant[move_x][move_y] != 255) { + attractant[move_x][move_y] += AGENT_DROP_AMOUNT; + } } else { - agents[a].heading += (random(0,2) *2 -1 ) * (random(0, 30) / 100.0) * PI*2; + agents[a].heading += (random(-1,2) *2 - 1 ) * 30 / 100.0 * PI*2; } // sample step int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE); int front_y = round(agents[a].y_position + sin(agents[a].heading) * AGENT_MOVE_DISTANCE); - int left_x = round(agents[a].x_position + cos(agents[a].heading - ((random(0,30) / 100.0) * (PI * 2)))); - int left_y = round(agents[a].y_position + cos(agents[a].heading - ((random(0,30) / 100.0) * (PI * 2)))); - int right_x = round(agents[a].x_position + cos(agents[a].heading + ((random(0,30) / 100.0) * (PI * 2)))); - int right_y = round(agents[a].y_position + cos(agents[a].heading + ((random(0,30) / 100.0) * (PI * 2)))); + int left_x = round(agents[a].x_position + cos(agents[a].heading - (AGENT_ANGLE * (PI * 2)))); + int left_y = round(agents[a].y_position + sin(agents[a].heading - (AGENT_ANGLE * (PI * 2)))); + int right_x = round(agents[a].x_position + cos(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); + int right_y = round(agents[a].y_position + sin(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); int front_value = attractant[front_x][front_y]; int left_value = attractant[left_x][left_y]; int right_value = attractant[right_x][right_y]; if (front_value > right_value and front_value > left_value) { ; } else if (front_value < right_value and front_value < left_value) { - agents[a].heading += (random(0, 2) * 2 - 1) * (random(0, 30) / 100.0) * (PI*2) ; + agents[a].heading += (random(0, 2) * 2 - 1) * (AGENT_ANGLE / 100.0) * (PI*2) ; } else if (left_value > right_value) { - agents[a].heading -= ((random(0,30) / 100.0) * (PI * 2)); + agents[a].heading -= AGENT_ANGLE * (PI * 2); } else { - agents[a].heading += ((random(0,30) / 100.0) * (PI * 2)); + agents[a].heading += AGENT_ANGLE * (PI * 2); } } - - //for(int i = 0; i < BLOB_POINTS; i+=2) { - // int end_offset = i + 2; - // if ( end_offset >= BLOB_POINTS) { - // end_offset = 0; - // } - // draw_bezier(blob.x_coords[i], - // blob.y_coords[i], - // blob.x_coords[i+1], - // blob.y_coords[i+1], - // blob.x_coords[end_offset], - // blob.y_coords[end_offset] - // ); - // matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(128, 128, 128)); - // blob.x_coords[i+1] += random(-1, 2); - // if (blob.x_coords[i+1] >= PANEL_WIDTH) { - // blob.x_coords[i+1] = PANEL_WIDTH - 1; - // } - // if (blob.x_coords[i+1] < 0) { - // blob.x_coords[i+1] = 0; - // } - // //blob.y_coords[i+1] += random(-1, 2); - // //matrix->drawPixel(blob.x_coords[i], blob.y_coords[i], matrix->color565(0, 0, 128)); - // //matrix->drawPixel(blob.x_coords[i+1], blob.y_coords[i+1], matrix->color565(128, 0, 0)); - // //matrix->drawPixel(blob.x_coords[end_offset], blob.y_coords[end_offset], matrix->color565(0, 0, 128)); - //} - delay(100); + delay(10); + iterations++; + if (iterations >= NUM_ITERATIONS) { + init_attractant(); + init_agents(); + iterations = 0; + } } From bdde96e5ed03310dacc0d7c0f7453907e8a38702 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Tue, 10 Dec 2024 16:17:24 +0100 Subject: [PATCH 07/17] sorta working box blur --- organism/src/main.cpp | 109 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 2 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index b219f0f..57f03a3 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -118,7 +118,7 @@ void draw_bg() { void draw_attractant() { for(int x = 0; x 20) { + if (attractant[x][y] > 0) { matrix->drawPixel(x, y, matrix->color565( int((255.0 / 255.0) * attractant[x][y]), int((80.0 / 255.0) * attractant[x][y]), @@ -130,6 +130,108 @@ void draw_attractant() { } } +void setupGaussianKernel(float* kernel, int width, float sigma) { + float sum = 0.0; + for(int i = 0; i < width; i++) { + //kernel[width+i] = exp( -(i*i) / (2 * sigma * sigma)) / (PI * 2 * sigma * sigma); + kernel[i] = exp(-0.5f * (i * i) / (sigma * sigma)); + sum += kernel[width]; + } + for(int i; i < width; i++) { + kernel[i] = sum/width; + } + Serial.printf("%f %f %f\n", kernel[0], kernel[1], kernel[2]); +} + +#define GAUSS_WIDTH 5 +#define GAUSS_SIGMA 1.0 +#define DECAY_FACTOR 0.9 +void gaussian_blur() { + float kernel[GAUSS_WIDTH]; + uint8_t first_pass[PANEL_WIDTH][PANEL_HEIGHT]; + memset(first_pass, (uint8_t) 0, sizeof first_pass); + setupGaussianKernel(kernel, GAUSS_WIDTH, GAUSS_SIGMA); + // horizontal pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + float sum = attractant[x][y] * kernel[0]; //0.0; + int additions = 1; + for (int x_offset = 1; x_offset < GAUSS_WIDTH; x_offset++) { + if (is_in_bounds(x+x_offset, y)) { + sum += attractant[x + x_offset][y] * kernel[x_offset]; + additions++; + } + if (is_in_bounds(x-x_offset, y)) { + sum += attractant[x - x_offset][y] * kernel[x_offset]; + additions++; + } + } + first_pass[x][y] = (int) round(sum/GAUSS_WIDTH * DECAY_FACTOR); + } + } + // vertical pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + float sum = first_pass[x][y] * kernel[0]; //0.0; + int additions = 1; + for (int y_offset = 1; y_offset < GAUSS_WIDTH; y_offset++) { + if (is_in_bounds(x, y + y_offset)) { + sum += first_pass[x][y + y_offset] * kernel[y_offset]; + additions++; + } + if (is_in_bounds(x, y - y_offset)) { + sum += first_pass[x][y - y_offset] * kernel[y_offset]; + additions++; + } + } + attractant[x][y] = (int) round((sum/GAUSS_WIDTH) * DECAY_FACTOR); + } + } +} + +#define BLUR_KERNEL_SIZE 3 +void box_blur() { + uint8_t first_pass[PANEL_WIDTH][PANEL_HEIGHT]; + memset(first_pass, (uint8_t) 0, sizeof first_pass); + + // horizontal pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + int sum = attractant[x][y]; //0.0; + int additions = 1; + for (int x_offset = 1; x_offset < BLUR_KERNEL_SIZE; x_offset++) { + if (is_in_bounds(x+x_offset, y)) { + sum += attractant[x + x_offset][y]; + additions++; + } + if (is_in_bounds(x-x_offset, y)) { + sum += attractant[x - x_offset][y]; + additions++; + } + } + first_pass[x][y] = (int) round((sum/additions) * DECAY_FACTOR); + } + } + // vertical pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + float sum = first_pass[x][y]; //0.0; + int additions = 1; + for (int y_offset = 1; y_offset < BLUR_KERNEL_SIZE; y_offset++) { + if (is_in_bounds(x, y + y_offset)) { + sum += first_pass[x][y + y_offset]; + additions++; + } + if (is_in_bounds(x, y - y_offset)) { + sum += first_pass[x][y - y_offset]; + additions++; + } + } + attractant[x][y] = (int) round((sum/additions) * DECAY_FACTOR); + } + } +} + void loop() { matrix ->flipDMABuffer(); //matrix->clearScreen(); @@ -176,9 +278,12 @@ void loop() { agents[a].heading += AGENT_ANGLE * (PI * 2); } } - delay(10); iterations++; + if (iterations % 64 == 0) { + //gaussian_blur(); + box_blur(); + } if (iterations >= NUM_ITERATIONS) { init_attractant(); init_agents(); From 79586fbc660758642151940dd47fb6b69725cac8 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Tue, 10 Dec 2024 19:17:51 +0100 Subject: [PATCH 08/17] ignore the blurring for now... --- organism/src/main.cpp | 60 ++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 24 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index 57f03a3..8bd7c2e 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -33,7 +33,7 @@ MatrixPanel_I2S_DMA *matrix = nullptr; -#define NUM_AGENTS 64 +#define NUM_AGENTS 128 #define AGENT_MOVE_DISTANCE 1 #define AGENT_DROP_AMOUNT 1 #define AGENT_ANGLE 0.175 @@ -44,18 +44,18 @@ typedef struct { float heading; } SlimeAgent; -uint8_t attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; +float attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; int iterations = 0; SlimeAgent agents[NUM_AGENTS]; void init_attractant() { - memset(attractant, (uint8_t) 0, sizeof attractant); + memset(attractant, 0.0, sizeof attractant); // draw a circle out of attractant //for (int p = 0; p < 64; p++) { // float angle = ((PI * 2) / 64) * p; // int x = 31 + round(10 * sin(angle)); // int y = 15 + round(10 * cos(angle)); - // attractant[x][y] = 15; + // attractant[x][y] = 15.0; //} } @@ -66,8 +66,10 @@ void init_agents() { //agents[a].y_position = 15 + round(10*cos(angle)); // agents[a].heading = ((PI * 2) / NUM_AGENTS) * ); - agents[a].x_position = random(12, 52); - agents[a].y_position = random(12, 20); + //agents[a].x_position = random(12, 52); + //agents[a].y_position = random(12, 20); + agents[a].x_position = random(0, 64); + agents[a].y_position = random(0, 32); agents[a].heading = (random(0, 100) / 100.0) * (PI*2); } } @@ -76,6 +78,9 @@ void init_agents() { void setup(){ Serial.begin(BAUD_RATE); + //while (!Serial) { + // ; // wait for serial port to connect. Needed for native USB + //} pinMode(ONBOARD_LED, OUTPUT); // redefine pins if required @@ -118,11 +123,11 @@ void draw_bg() { void draw_attractant() { for(int x = 0; x 0) { + if (attractant[x][y] > 20.0) { matrix->drawPixel(x, y, matrix->color565( - int((255.0 / 255.0) * attractant[x][y]), - int((80.0 / 255.0) * attractant[x][y]), - int((83.0 / 255.0) * attractant[x][y]) + int((255.0 / 255.0) * round(attractant[x][y])), + int((80.0 / 255.0) * round(attractant[x][y])), + int((83.0 / 255.0) * round(attractant[x][y])) ) ); } @@ -145,7 +150,7 @@ void setupGaussianKernel(float* kernel, int width, float sigma) { #define GAUSS_WIDTH 5 #define GAUSS_SIGMA 1.0 -#define DECAY_FACTOR 0.9 +#define DECAY_FACTOR 0.95 void gaussian_blur() { float kernel[GAUSS_WIDTH]; uint8_t first_pass[PANEL_WIDTH][PANEL_HEIGHT]; @@ -184,20 +189,22 @@ void gaussian_blur() { additions++; } } - attractant[x][y] = (int) round((sum/GAUSS_WIDTH) * DECAY_FACTOR); + attractant[x][y] = (sum/GAUSS_WIDTH) * DECAY_FACTOR; } } } #define BLUR_KERNEL_SIZE 3 +float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; void box_blur() { - uint8_t first_pass[PANEL_WIDTH][PANEL_HEIGHT]; - memset(first_pass, (uint8_t) 0, sizeof first_pass); - + //Serial.println("memset: starting"); + memset(first_pass, 0.0, sizeof first_pass); + //Serial.println("memset: passed"); // horizontal pass for (int x = 0; x < PANEL_WIDTH; x++) { for(int y = 0; y < PANEL_HEIGHT; y++) { - int sum = attractant[x][y]; //0.0; + float sum; + sum = attractant[x][y]; //0.0; int additions = 1; for (int x_offset = 1; x_offset < BLUR_KERNEL_SIZE; x_offset++) { if (is_in_bounds(x+x_offset, y)) { @@ -209,7 +216,7 @@ void box_blur() { additions++; } } - first_pass[x][y] = (int) round((sum/additions) * DECAY_FACTOR); + first_pass[x][y] = (sum/additions); } } // vertical pass @@ -227,7 +234,11 @@ void box_blur() { additions++; } } - attractant[x][y] = (int) round((sum/additions) * DECAY_FACTOR); + + float result = (sum/additions); // * DECAY_FACTOR; + //Serial.printf("result: %f", result); //additions: %d\n", sum, additions); + attractant[x][y] = (((8.0*attractant[x][y]) + result) / 9.0); + attractant[x][y] = attractant[x][y] * DECAY_FACTOR; } } } @@ -252,7 +263,7 @@ void loop() { if (is_in_bounds(move_x, move_y)) { agents[a].x_position = move_x; agents[a].y_position = move_y; - if (attractant[move_x][move_y] != 255) { + if (attractant[move_x][move_y] < 254.0) { attractant[move_x][move_y] += AGENT_DROP_AMOUNT; } } else { @@ -265,9 +276,9 @@ void loop() { int left_y = round(agents[a].y_position + sin(agents[a].heading - (AGENT_ANGLE * (PI * 2)))); int right_x = round(agents[a].x_position + cos(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); int right_y = round(agents[a].y_position + sin(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); - int front_value = attractant[front_x][front_y]; - int left_value = attractant[left_x][left_y]; - int right_value = attractant[right_x][right_y]; + float front_value = attractant[front_x][front_y]; + float left_value = attractant[left_x][left_y]; + float right_value = attractant[right_x][right_y]; if (front_value > right_value and front_value > left_value) { ; } else if (front_value < right_value and front_value < left_value) { @@ -280,9 +291,10 @@ void loop() { } delay(10); iterations++; - if (iterations % 64 == 0) { + if (iterations > 64 && iterations % 64 == 0) { // (( == 0) { //gaussian_blur(); - box_blur(); + //box_blur(); + ; } if (iterations >= NUM_ITERATIONS) { init_attractant(); From d5879e10b31c0d665479606d2a44ce4ec396439a Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Tue, 10 Dec 2024 20:05:32 +0100 Subject: [PATCH 09/17] add overlay --- organism/src/main.cpp | 30 ++++++++++++++++++++---------- organism/src/overlay.h | 19 +++++++++++++++++++ 2 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 organism/src/overlay.h diff --git a/organism/src/main.cpp b/organism/src/main.cpp index 8bd7c2e..ee05d84 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -3,6 +3,7 @@ #include #include "main.h" +#include "overlay.h" #define R1 42 #define G1 40 @@ -57,6 +58,16 @@ void init_attractant() { // int y = 15 + round(10 * cos(angle)); // attractant[x][y] = 15.0; //} + + // draw a bitmap + //for(int x = 0; x < PANEL_WIDTH; x++) { + // for(int y = 0; y < PANEL_HEIGHT; y++) { + // int pixel_num = (y * PANEL_WIDTH) + x; + // if(overlay[ pixel_num / 8 ] & (1 << (7 - (pixel_num % 8)) ) ){ + // attractant[x][y] = 15.0; + // } + // } + //} } void init_agents() { @@ -150,16 +161,17 @@ void setupGaussianKernel(float* kernel, int width, float sigma) { #define GAUSS_WIDTH 5 #define GAUSS_SIGMA 1.0 -#define DECAY_FACTOR 0.95 +#define DECAY_FACTOR 0.9 +float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; void gaussian_blur() { float kernel[GAUSS_WIDTH]; - uint8_t first_pass[PANEL_WIDTH][PANEL_HEIGHT]; - memset(first_pass, (uint8_t) 0, sizeof first_pass); + // first_pass[PANEL_WIDTH][PANEL_HEIGHT]; + memset(first_pass, 0.0, sizeof first_pass); setupGaussianKernel(kernel, GAUSS_WIDTH, GAUSS_SIGMA); // horizontal pass for (int x = 0; x < PANEL_WIDTH; x++) { for(int y = 0; y < PANEL_HEIGHT; y++) { - float sum = attractant[x][y] * kernel[0]; //0.0; + float sum = attractant[x][y] * DECAY_FACTOR * kernel[0]; //0.0; int additions = 1; for (int x_offset = 1; x_offset < GAUSS_WIDTH; x_offset++) { if (is_in_bounds(x+x_offset, y)) { @@ -171,7 +183,7 @@ void gaussian_blur() { additions++; } } - first_pass[x][y] = (int) round(sum/GAUSS_WIDTH * DECAY_FACTOR); + first_pass[x][y] = sum/GAUSS_WIDTH; } } // vertical pass @@ -189,13 +201,12 @@ void gaussian_blur() { additions++; } } - attractant[x][y] = (sum/GAUSS_WIDTH) * DECAY_FACTOR; + attractant[x][y] = sum/GAUSS_WIDTH; } } } #define BLUR_KERNEL_SIZE 3 -float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; void box_blur() { //Serial.println("memset: starting"); memset(first_pass, 0.0, sizeof first_pass); @@ -204,7 +215,7 @@ void box_blur() { for (int x = 0; x < PANEL_WIDTH; x++) { for(int y = 0; y < PANEL_HEIGHT; y++) { float sum; - sum = attractant[x][y]; //0.0; + sum = attractant[x][y] * DECAY_FACTOR; //0.0; int additions = 1; for (int x_offset = 1; x_offset < BLUR_KERNEL_SIZE; x_offset++) { if (is_in_bounds(x+x_offset, y)) { @@ -238,13 +249,13 @@ void box_blur() { float result = (sum/additions); // * DECAY_FACTOR; //Serial.printf("result: %f", result); //additions: %d\n", sum, additions); attractant[x][y] = (((8.0*attractant[x][y]) + result) / 9.0); - attractant[x][y] = attractant[x][y] * DECAY_FACTOR; } } } void loop() { matrix ->flipDMABuffer(); + delay(10); //matrix->clearScreen(); matrix->fillScreenRGB888(15, 0, 10); @@ -289,7 +300,6 @@ void loop() { agents[a].heading += AGENT_ANGLE * (PI * 2); } } - delay(10); iterations++; if (iterations > 64 && iterations % 64 == 0) { // (( == 0) { //gaussian_blur(); diff --git a/organism/src/overlay.h b/organism/src/overlay.h new file mode 100644 index 0000000..f87ab77 --- /dev/null +++ b/organism/src/overlay.h @@ -0,0 +1,19 @@ +const unsigned char overlay [] PROGMEM = { + // 'bw2, 64x32px + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, + 0x01, 0xf8, 0x00, 0x00, 0x00, 0x1c, 0x03, 0x80, 0x01, 0xfe, 0x00, 0x00, 0x00, 0x1c, 0x03, 0x80, + 0x01, 0xff, 0x00, 0x00, 0x00, 0x1c, 0x03, 0x80, 0x01, 0xc7, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x00, + 0x01, 0xc3, 0x80, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x01, 0xc3, 0x8f, 0xe1, 0xbe, 0x1c, 0x7b, 0x80, + 0x01, 0xc3, 0x8f, 0xe1, 0xff, 0x1c, 0x73, 0x80, 0x01, 0xc3, 0x88, 0x71, 0xe7, 0x1c, 0xe3, 0x80, + 0x01, 0xc3, 0x80, 0x71, 0xc3, 0x9d, 0xe3, 0x80, 0x01, 0xff, 0x00, 0x71, 0xc3, 0x9d, 0xc3, 0x80, + 0x01, 0xff, 0x03, 0xf1, 0xc3, 0x9f, 0x83, 0x80, 0x01, 0xfc, 0x0f, 0xf1, 0xc3, 0x9f, 0xc3, 0x80, + 0x01, 0xc0, 0x1f, 0x71, 0xc3, 0x9f, 0xc3, 0x80, 0x01, 0xc0, 0x3c, 0x71, 0xc3, 0x9d, 0xe3, 0x80, + 0x01, 0xc0, 0x38, 0x71, 0xc3, 0x9c, 0xe3, 0x80, 0x01, 0xc0, 0x38, 0x71, 0xc3, 0x9c, 0xf3, 0x80, + 0x01, 0xc0, 0x1c, 0xf1, 0xc3, 0x9c, 0x73, 0x80, 0x01, 0xc0, 0x1f, 0xf1, 0xc3, 0x9c, 0x7b, 0x80, + 0x01, 0xc0, 0x0f, 0xb1, 0x83, 0x9c, 0x3b, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; From b5a5c9b146d0da3b6da7bb925e4c9cec648165c0 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Tue, 10 Dec 2024 21:09:00 +0100 Subject: [PATCH 10/17] add random params --- organism/src/main.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index ee05d84..d3bcf81 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -35,9 +35,10 @@ MatrixPanel_I2S_DMA *matrix = nullptr; #define NUM_AGENTS 128 -#define AGENT_MOVE_DISTANCE 1 + +//#define AGENT_MOVE_DISTANCE 1 #define AGENT_DROP_AMOUNT 1 -#define AGENT_ANGLE 0.175 +//#define AGENT_ANGLE 0.175 #define NUM_ITERATIONS 1000 typedef struct { int x_position; @@ -45,6 +46,11 @@ typedef struct { float heading; } SlimeAgent; +int AGENT_MOVE_DISTANCE; +float AGENT_SENSOR_DISTANCE; +float AGENT_MOVE_ANGLE; +float AGENT_SENSOR_ANGLE; + float attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; int iterations = 0; SlimeAgent agents[NUM_AGENTS]; @@ -71,6 +77,10 @@ void init_attractant() { } void init_agents() { + AGENT_MOVE_DISTANCE = 1; //random(1, 3); + AGENT_MOVE_ANGLE = random(0, 334) / 1000.0; + AGENT_SENSOR_ANGLE = random(0, 334) / 1000.0; + AGENT_SENSOR_DISTANCE = random(100, 400) / 1000.0; for(int a = 0; a < NUM_AGENTS; a++) { float angle = ((PI * 2) / NUM_AGENTS) * a; //agents[a].x_position = 31 + round(10*sin(angle)); @@ -281,23 +291,23 @@ void loop() { agents[a].heading += (random(-1,2) *2 - 1 ) * 30 / 100.0 * PI*2; } // sample step - int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE); - int front_y = round(agents[a].y_position + sin(agents[a].heading) * AGENT_MOVE_DISTANCE); - int left_x = round(agents[a].x_position + cos(agents[a].heading - (AGENT_ANGLE * (PI * 2)))); - int left_y = round(agents[a].y_position + sin(agents[a].heading - (AGENT_ANGLE * (PI * 2)))); - int right_x = round(agents[a].x_position + cos(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); - int right_y = round(agents[a].y_position + sin(agents[a].heading + (AGENT_ANGLE * (PI * 2)))); + int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_SENSOR_DISTANCE); + int front_y = round(agents[a].y_position + sin(agents[a].heading) * AGENT_SENSOR_DISTANCE); + int left_x = round(agents[a].x_position + cos(agents[a].heading - (AGENT_SENSOR_ANGLE * (PI * 2))) * AGENT_SENSOR_DISTANCE); + int left_y = round(agents[a].y_position + sin(agents[a].heading - (AGENT_SENSOR_ANGLE * (PI * 2))) * AGENT_SENSOR_DISTANCE); + int right_x = round(agents[a].x_position + cos(agents[a].heading + (AGENT_SENSOR_ANGLE * (PI * 2))) * AGENT_SENSOR_DISTANCE); + int right_y = round(agents[a].y_position + sin(agents[a].heading + (AGENT_SENSOR_ANGLE * (PI * 2))) * AGENT_SENSOR_DISTANCE); float front_value = attractant[front_x][front_y]; float left_value = attractant[left_x][left_y]; float right_value = attractant[right_x][right_y]; if (front_value > right_value and front_value > left_value) { ; } else if (front_value < right_value and front_value < left_value) { - agents[a].heading += (random(0, 2) * 2 - 1) * (AGENT_ANGLE / 100.0) * (PI*2) ; + agents[a].heading += (random(0, 2) * 2 - 1) * (AGENT_MOVE_ANGLE / 100.0) * (PI*2) ; } else if (left_value > right_value) { - agents[a].heading -= AGENT_ANGLE * (PI * 2); + agents[a].heading -= AGENT_MOVE_ANGLE * (PI * 2); } else { - agents[a].heading += AGENT_ANGLE * (PI * 2); + agents[a].heading += AGENT_MOVE_ANGLE * (PI * 2); } } iterations++; From 494d0d128352300bef98509db4caf37a1a744f44 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Fri, 13 Dec 2024 19:50:48 +0100 Subject: [PATCH 11/17] increase sensor distance --- organism/src/main.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index d3bcf81..107f61b 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -80,7 +80,8 @@ void init_agents() { AGENT_MOVE_DISTANCE = 1; //random(1, 3); AGENT_MOVE_ANGLE = random(0, 334) / 1000.0; AGENT_SENSOR_ANGLE = random(0, 334) / 1000.0; - AGENT_SENSOR_DISTANCE = random(100, 400) / 1000.0; + //AGENT_SENSOR_DISTANCE = random(100, 400) / 1000.0; + AGENT_SENSOR_DISTANCE = random(3000, 5000) / 1000.0; for(int a = 0; a < NUM_AGENTS; a++) { float angle = ((PI * 2) / NUM_AGENTS) * a; //agents[a].x_position = 31 + round(10*sin(angle)); @@ -290,7 +291,10 @@ void loop() { } else { agents[a].heading += (random(-1,2) *2 - 1 ) * 30 / 100.0 * PI*2; } - // sample step + } + // sample step + for(int a = 0; a < NUM_AGENTS; a++) { + //matrix->drawPixel(agents[a].x_position, agents[a].y_position, matrix->color565(0, 0, attractant[agents[a].x_position][agents[a].y_position])); int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_SENSOR_DISTANCE); int front_y = round(agents[a].y_position + sin(agents[a].heading) * AGENT_SENSOR_DISTANCE); int left_x = round(agents[a].x_position + cos(agents[a].heading - (AGENT_SENSOR_ANGLE * (PI * 2))) * AGENT_SENSOR_DISTANCE); From b9bd58f34bc19dfafecb5f5e86fd8d2598709e48 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Fri, 13 Dec 2024 21:59:56 +0100 Subject: [PATCH 12/17] playing around, agents are now stored in a vector --- organism/src/main.cpp | 61 +++++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index 107f61b..037f253 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -5,6 +5,8 @@ #include "main.h" #include "overlay.h" +#include + #define R1 42 #define G1 40 #define BL1 41 @@ -34,18 +36,20 @@ MatrixPanel_I2S_DMA *matrix = nullptr; -#define NUM_AGENTS 128 +//#define NUM_AGENTS 300 //#define AGENT_MOVE_DISTANCE 1 -#define AGENT_DROP_AMOUNT 1 +#define AGENT_DROP_AMOUNT 1 //5 //#define AGENT_ANGLE 0.175 #define NUM_ITERATIONS 1000 -typedef struct { +struct SlimeAgent { int x_position; int y_position; float heading; -} SlimeAgent; +}; + +int NUM_AGENTS; int AGENT_MOVE_DISTANCE; float AGENT_SENSOR_DISTANCE; float AGENT_MOVE_ANGLE; @@ -53,7 +57,8 @@ float AGENT_SENSOR_ANGLE; float attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; int iterations = 0; -SlimeAgent agents[NUM_AGENTS]; +//SlimeAgent agents[NUM_AGENTS]; +std::vector agents; void init_attractant() { memset(attractant, 0.0, sizeof attractant); @@ -70,7 +75,7 @@ void init_attractant() { // for(int y = 0; y < PANEL_HEIGHT; y++) { // int pixel_num = (y * PANEL_WIDTH) + x; // if(overlay[ pixel_num / 8 ] & (1 << (7 - (pixel_num % 8)) ) ){ - // attractant[x][y] = 15.0; + // attractant[x][y] = 255.0; // } // } //} @@ -78,10 +83,21 @@ void init_attractant() { void init_agents() { AGENT_MOVE_DISTANCE = 1; //random(1, 3); - AGENT_MOVE_ANGLE = random(0, 334) / 1000.0; - AGENT_SENSOR_ANGLE = random(0, 334) / 1000.0; + //AGENT_MOVE_ANGLE = random(0, 334) / 1000.0; + AGENT_MOVE_ANGLE = 0.175;//random(0, 334) / 1000.0; + //AGENT_SENSOR_ANGLE = random(0, 334) / 1000.0; + if (random(0, 2) > 0) { + AGENT_SENSOR_ANGLE = 0.175; + } else { + AGENT_SENSOR_ANGLE = 0.0875; + } + //AGENT_SENSOR_DISTANCE = random(100, 400) / 1000.0; - AGENT_SENSOR_DISTANCE = random(3000, 5000) / 1000.0; + //AGENT_SENSOR_DISTANCE = random(3000, 5000) / 1000.0; + AGENT_SENSOR_DISTANCE = random(2000, 3500) / 1000.0; + + NUM_AGENTS = random(64, 301); + agents.clear(); for(int a = 0; a < NUM_AGENTS; a++) { float angle = ((PI * 2) / NUM_AGENTS) * a; //agents[a].x_position = 31 + round(10*sin(angle)); @@ -90,9 +106,14 @@ void init_agents() { //agents[a].x_position = random(12, 52); //agents[a].y_position = random(12, 20); - agents[a].x_position = random(0, 64); - agents[a].y_position = random(0, 32); - agents[a].heading = (random(0, 100) / 100.0) * (PI*2); + agents.push_back({ + random(0,64), + random(0,32), + (random(0, 100) / 100.0) * (PI*2) + }); + //agents[a].x_position = random(0, 64); + //agents[a].y_position = random(0, 32); + //agents[a].heading = (random(0, 100) / 100.0) * (PI*2); } } @@ -170,7 +191,7 @@ void setupGaussianKernel(float* kernel, int width, float sigma) { Serial.printf("%f %f %f\n", kernel[0], kernel[1], kernel[2]); } -#define GAUSS_WIDTH 5 +#define GAUSS_WIDTH 1 #define GAUSS_SIGMA 1.0 #define DECAY_FACTOR 0.9 float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; @@ -217,7 +238,7 @@ void gaussian_blur() { } } -#define BLUR_KERNEL_SIZE 3 +#define BLUR_KERNEL_SIZE 1 void box_blur() { //Serial.println("memset: starting"); memset(first_pass, 0.0, sizeof first_pass); @@ -259,7 +280,8 @@ void box_blur() { float result = (sum/additions); // * DECAY_FACTOR; //Serial.printf("result: %f", result); //additions: %d\n", sum, additions); - attractant[x][y] = (((8.0*attractant[x][y]) + result) / 9.0); + //attractant[x][y] = (((8.0*attractant[x][y]) + result) / 9.0); + attractant[x][y] = result; } } } @@ -285,11 +307,12 @@ void loop() { if (is_in_bounds(move_x, move_y)) { agents[a].x_position = move_x; agents[a].y_position = move_y; - if (attractant[move_x][move_y] < 254.0) { + if (attractant[move_x][move_y] < 255.0 - AGENT_DROP_AMOUNT) { attractant[move_x][move_y] += AGENT_DROP_AMOUNT; } } else { - agents[a].heading += (random(-1,2) *2 - 1 ) * 30 / 100.0 * PI*2; + agents[a].heading = (random(0, 100)/100.0) * (PI*2); + // agents[a].heading = (2*PI) - agents[a].heading;//(random(0, 100)/100.0) * (PI*2); } } // sample step @@ -315,9 +338,9 @@ void loop() { } } iterations++; - if (iterations > 64 && iterations % 64 == 0) { // (( == 0) { - //gaussian_blur(); + if (iterations % 4 == 0) { //64 && iterations % 64 == 0) { // (( == 0) { //box_blur(); + //gaussian_blur(); ; } if (iterations >= NUM_ITERATIONS) { From e71df69612e1b1043c7f09f33a138123ed71569a Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 14 Dec 2024 13:17:12 +0100 Subject: [PATCH 13/17] =?UTF-8?q?=F0=9F=A7=B9=20add=20cleanup=20routine?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- organism/src/main.cpp | 64 ++++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index 037f253..691a32e 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -36,12 +36,9 @@ MatrixPanel_I2S_DMA *matrix = nullptr; -//#define NUM_AGENTS 300 -//#define AGENT_MOVE_DISTANCE 1 -#define AGENT_DROP_AMOUNT 1 //5 -//#define AGENT_ANGLE 0.175 -#define NUM_ITERATIONS 1000 +#define AGENT_DROP_AMOUNT 10 +#define NUM_ITERATIONS 500 struct SlimeAgent { int x_position; int y_position; @@ -57,7 +54,6 @@ float AGENT_SENSOR_ANGLE; float attractant[PANEL_WIDTH][PANEL_HEIGHT] = {}; int iterations = 0; -//SlimeAgent agents[NUM_AGENTS]; std::vector agents; void init_attractant() { @@ -107,10 +103,15 @@ void init_agents() { //agents[a].x_position = random(12, 52); //agents[a].y_position = random(12, 20); agents.push_back({ - random(0,64), - random(0,32), + random(2,63), + random(2,31), (random(0, 100) / 100.0) * (PI*2) }); + //agents.push_back({ + // random(6,58), + // random(4,28), + // (random(0, 100) / 100.0) * (PI*2) + //}); //agents[a].x_position = random(0, 64); //agents[a].y_position = random(0, 32); //agents[a].heading = (random(0, 100) / 100.0) * (PI*2); @@ -166,7 +167,7 @@ void draw_bg() { void draw_attractant() { for(int x = 0; x 20.0) { + if (attractant[x][y] > 17.0) { matrix->drawPixel(x, y, matrix->color565( int((255.0 / 255.0) * round(attractant[x][y])), int((80.0 / 255.0) * round(attractant[x][y])), @@ -188,7 +189,6 @@ void setupGaussianKernel(float* kernel, int width, float sigma) { for(int i; i < width; i++) { kernel[i] = sum/width; } - Serial.printf("%f %f %f\n", kernel[0], kernel[1], kernel[2]); } #define GAUSS_WIDTH 1 @@ -197,7 +197,6 @@ void setupGaussianKernel(float* kernel, int width, float sigma) { float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; void gaussian_blur() { float kernel[GAUSS_WIDTH]; - // first_pass[PANEL_WIDTH][PANEL_HEIGHT]; memset(first_pass, 0.0, sizeof first_pass); setupGaussianKernel(kernel, GAUSS_WIDTH, GAUSS_SIGMA); // horizontal pass @@ -279,17 +278,41 @@ void box_blur() { } float result = (sum/additions); // * DECAY_FACTOR; - //Serial.printf("result: %f", result); //additions: %d\n", sum, additions); //attractant[x][y] = (((8.0*attractant[x][y]) + result) / 9.0); attractant[x][y] = result; } } } +int cleanup_x = 0; +void cleanup() { + int progress = iterations - NUM_ITERATIONS; + matrix->drawFastVLine(cleanup_x, 0, PANEL_HEIGHT, matrix->color565(254, 242, 255)); + if (cleanup_x > 0) { + matrix->fillRect(0, 0, cleanup_x, PANEL_HEIGHT, matrix->color565(16, 0, 16)); + } + int h_lines = round(PANEL_HEIGHT / 7); + int v_lines = round(cleanup_x / 7); + for(int v = 0; v < cleanup_x; v++) { + if (v%7 == 2) { + matrix->drawFastVLine(v, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); + } + } + for(int h = 0; h <= h_lines; h++) { + matrix->drawFastHLine(0, 7*h + 1, cleanup_x-1, matrix->color565(41, 17, 76)); + } + cleanup_x++; + if (cleanup_x > PANEL_WIDTH) { + iterations = 0; + cleanup_x = 0; + init_attractant(); + init_agents(); + } +} + void loop() { matrix ->flipDMABuffer(); delay(10); - //matrix->clearScreen(); matrix->fillScreenRGB888(15, 0, 10); // draw background and organism @@ -298,8 +321,8 @@ void loop() { for(int a = 0; a < NUM_AGENTS; a++) { //matrix->drawPixel(agents[a].x_position, agents[a].y_position, matrix->color565(0, 0, attractant[agents[a].x_position][agents[a].y_position])); - // motor step - // check if agent can move forward + // motor step: check if agent can move forward + // if yes, do so, if not, turn randomly float target_x = agents[a].x_position + cos(agents[a].heading) * AGENT_MOVE_DISTANCE; float target_y = agents[a].y_position + sin(agents[a].heading) * AGENT_MOVE_DISTANCE; int move_x = round(target_x); @@ -312,10 +335,9 @@ void loop() { } } else { agents[a].heading = (random(0, 100)/100.0) * (PI*2); - // agents[a].heading = (2*PI) - agents[a].heading;//(random(0, 100)/100.0) * (PI*2); } } - // sample step + // sample step - check the 3 positions for(int a = 0; a < NUM_AGENTS; a++) { //matrix->drawPixel(agents[a].x_position, agents[a].y_position, matrix->color565(0, 0, attractant[agents[a].x_position][agents[a].y_position])); int front_x = round(agents[a].x_position + cos(agents[a].heading) * AGENT_SENSOR_DISTANCE); @@ -338,15 +360,13 @@ void loop() { } } iterations++; - if (iterations % 4 == 0) { //64 && iterations % 64 == 0) { // (( == 0) { - //box_blur(); + if (iterations % 2 == 0) { //64 && iterations % 64 == 0) { // (( == 0) { + box_blur(); //gaussian_blur(); ; } if (iterations >= NUM_ITERATIONS) { - init_attractant(); - init_agents(); - iterations = 0; + cleanup(); } } From 95fb000f95167fb22636b2fdcd412ac14586d07b Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sat, 14 Dec 2024 13:19:42 +0100 Subject: [PATCH 14/17] refactor constants to own file --- organism/src/constants.h | 26 ++++++++++++++++++++++++++ organism/src/main.cpp | 27 +-------------------------- 2 files changed, 27 insertions(+), 26 deletions(-) create mode 100644 organism/src/constants.h diff --git a/organism/src/constants.h b/organism/src/constants.h new file mode 100644 index 0000000..0561782 --- /dev/null +++ b/organism/src/constants.h @@ -0,0 +1,26 @@ +#define R1 42 +#define G1 40 +#define BL1 41 +#define R2 38 +#define G2 37 +#define BL2 39 +#define CH_A 45 +#define CH_B 36 +#define CH_C 48 +#define CH_D 35 +#define CH_E 21 +#define CLK 2 +#define LAT 47 +#define OE 14 + +#define PIN_E 21 +#define PANEL_WIDTH 64 +#define PANEL_HEIGHT 32 // Panel height of 64 will required PIN_E to be defined. + +#define PANELS_NUMBER 1 + +#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER +#define PANE_HEIGHT PANEL_HEIGHT +#define NUM_LEDS PANE_WIDTH*PANE_HEIGHT + +#define ONBOARD_LED 13 diff --git a/organism/src/main.cpp b/organism/src/main.cpp index 691a32e..b6f6b15 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -3,36 +3,11 @@ #include #include "main.h" +#include "constants.h" #include "overlay.h" #include -#define R1 42 -#define G1 40 -#define BL1 41 -#define R2 38 -#define G2 37 -#define BL2 39 -#define CH_A 45 -#define CH_B 36 -#define CH_C 48 -#define CH_D 35 -#define CH_E 21 -#define CLK 2 -#define LAT 47 -#define OE 14 - -#define PIN_E 21 -#define PANEL_WIDTH 64 -#define PANEL_HEIGHT 32 // Panel height of 64 will required PIN_E to be defined. - -#define PANELS_NUMBER 1 - -#define PANE_WIDTH PANEL_WIDTH * PANELS_NUMBER -#define PANE_HEIGHT PANEL_HEIGHT -#define NUM_LEDS PANE_WIDTH*PANE_HEIGHT - -#define ONBOARD_LED 13 MatrixPanel_I2S_DMA *matrix = nullptr; From 8cc53c8bb2360e5794374b83cdc25ab146e80d95 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sun, 15 Dec 2024 14:22:16 +0100 Subject: [PATCH 15/17] =?UTF-8?q?=F0=9F=91=BD=20organism=20refactor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- organism/src/blur.cpp | 105 +++++++++++++++++ organism/src/blur.h | 3 + organism/src/config.h | 18 +++ organism/src/main.cpp | 252 +++++++++++----------------------------- organism/src/util.cpp | 5 + organism/src/util.h | 2 + organism/src/visual.cpp | 54 +++++++++ organism/src/visual.h | 6 + 8 files changed, 262 insertions(+), 183 deletions(-) create mode 100644 organism/src/blur.cpp create mode 100644 organism/src/blur.h create mode 100644 organism/src/config.h create mode 100644 organism/src/util.cpp create mode 100644 organism/src/util.h create mode 100644 organism/src/visual.cpp create mode 100644 organism/src/visual.h diff --git a/organism/src/blur.cpp b/organism/src/blur.cpp new file mode 100644 index 0000000..e6f5f56 --- /dev/null +++ b/organism/src/blur.cpp @@ -0,0 +1,105 @@ +#include +#include "constants.h" +#include "config.h" +#include "util.h" + +void setupGaussianKernel(float* kernel, int width, float sigma) { + float sum = 0.0; + for(int i = 0; i < width; i++) { + //kernel[width+i] = exp( -(i*i) / (2 * sigma * sigma)) / (PI * 2 * sigma * sigma); + kernel[i] = exp(-0.5f * (i * i) / (sigma * sigma)); + sum += kernel[width]; + } + for(int i; i < width; i++) { + kernel[i] = sum/width; + } +} + +//float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; +void gaussian_blur(float *field[PANEL_WIDTH][PANEL_HEIGHT]) { + float kernel[GAUSS_WIDTH]; + float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; + memset(first_pass, 0.0, sizeof first_pass); + setupGaussianKernel(kernel, GAUSS_WIDTH, GAUSS_SIGMA); + // horizontal pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + float sum = *field[x][y] * DECAY_FACTOR * kernel[0]; //0.0; + int additions = 1; + for (int x_offset = 1; x_offset < GAUSS_WIDTH; x_offset++) { + if (is_in_bounds(x+x_offset, y)) { + sum += *field[x + x_offset][y] * kernel[x_offset]; + additions++; + } + if (is_in_bounds(x-x_offset, y)) { + sum += *field[x - x_offset][y] * kernel[x_offset]; + additions++; + } + } + first_pass[x][y] = sum/GAUSS_WIDTH; + } + } + // vertical pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + float sum = first_pass[x][y] * kernel[0]; //0.0; + int additions = 1; + for (int y_offset = 1; y_offset < GAUSS_WIDTH; y_offset++) { + if (is_in_bounds(x, y + y_offset)) { + sum += first_pass[x][y + y_offset] * kernel[y_offset]; + additions++; + } + if (is_in_bounds(x, y - y_offset)) { + sum += first_pass[x][y - y_offset] * kernel[y_offset]; + additions++; + } + } + *field[x][y] = sum/GAUSS_WIDTH; + } + } +} + +void box_blur(float field[PANEL_WIDTH][PANEL_HEIGHT]) { + auto first_pass = new float[PANEL_WIDTH][PANEL_HEIGHT](); + // horizontal pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + float sum; + sum = field[x][y] * DECAY_FACTOR; //0.0; + int additions = 1; + for (int x_offset = 1; x_offset < BLUR_KERNEL_SIZE; x_offset++) { + if (is_in_bounds(x+x_offset, y)) { + sum += field[x + x_offset][y]; + additions++; + } + if (is_in_bounds(x-x_offset, y)) { + sum += field[x - x_offset][y]; + additions++; + } + } + first_pass[x][y] = (sum/additions); + } + } + // vertical pass + for (int x = 0; x < PANEL_WIDTH; x++) { + for(int y = 0; y < PANEL_HEIGHT; y++) { + float sum = first_pass[x][y]; //0.0; + int additions = 1; + for (int y_offset = 1; y_offset < BLUR_KERNEL_SIZE; y_offset++) { + if (is_in_bounds(x, y + y_offset)) { + sum += first_pass[x][y + y_offset]; + additions++; + } + if (is_in_bounds(x, y - y_offset)) { + sum += first_pass[x][y - y_offset]; + additions++; + } + } + + float result = (sum/additions); // * DECAY_FACTOR; + //attractant[x][y] = (((8.0*attractant[x][y]) + result) / 9.0); + field[x][y] = result; + } + } + delete[] first_pass; +} diff --git a/organism/src/blur.h b/organism/src/blur.h new file mode 100644 index 0000000..3ca9090 --- /dev/null +++ b/organism/src/blur.h @@ -0,0 +1,3 @@ +#include "constants.h" +void gaussian_blur(float *field[PANEL_WIDTH][PANEL_HEIGHT]); +void box_blur(float field[PANEL_WIDTH][PANEL_HEIGHT]); diff --git a/organism/src/config.h b/organism/src/config.h new file mode 100644 index 0000000..f9ad7f1 --- /dev/null +++ b/organism/src/config.h @@ -0,0 +1,18 @@ +// gaussian blur +#define GAUSS_WIDTH 1 +#define GAUSS_SIGMA 1.0 +#define DECAY_FACTOR 0.9 +// box blur +#define BLUR_KERNEL_SIZE 1 +// agent params +#define NUM_AGENTS_MIN 64 +#define NUM_AGENTS_MAX 301 +#define AGENT_DROP_AMOUNT 10 +#define AGENT_SENSOR_DISTANCE_MIN 2.0 +#define AGENT_SENSOR_DISTANCE_MAX 3.5 +// general params +#define NUM_ITERATIONS 500 +#define SPAWN_MIN_X 2 +#define SPAWN_MAX_X 63 +#define SPAWN_MIN_Y 2 +#define SPAWN_MAX_Y 31 diff --git a/organism/src/main.cpp b/organism/src/main.cpp index b6f6b15..a84dd08 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -4,7 +4,12 @@ #include "main.h" #include "constants.h" +#include "config.h" #include "overlay.h" +#include "util.h" + +#include "visual.h" +#include "blur.h" #include @@ -12,8 +17,8 @@ MatrixPanel_I2S_DMA *matrix = nullptr; -#define AGENT_DROP_AMOUNT 10 -#define NUM_ITERATIONS 500 +//#define AGENT_DROP_AMOUNT 10 +//#define NUM_ITERATIONS 500 struct SlimeAgent { int x_position; int y_position; @@ -63,33 +68,19 @@ void init_agents() { AGENT_SENSOR_ANGLE = 0.0875; } - //AGENT_SENSOR_DISTANCE = random(100, 400) / 1000.0; - //AGENT_SENSOR_DISTANCE = random(3000, 5000) / 1000.0; - AGENT_SENSOR_DISTANCE = random(2000, 3500) / 1000.0; - - NUM_AGENTS = random(64, 301); + AGENT_SENSOR_DISTANCE = random(AGENT_SENSOR_DISTANCE_MIN * 1000.0, AGENT_SENSOR_DISTANCE_MAX * 1000.0) / 1000.0; + NUM_AGENTS = random(NUM_AGENTS_MIN, NUM_AGENTS_MAX); agents.clear(); for(int a = 0; a < NUM_AGENTS; a++) { float angle = ((PI * 2) / NUM_AGENTS) * a; //agents[a].x_position = 31 + round(10*sin(angle)); //agents[a].y_position = 15 + round(10*cos(angle)); // agents[a].heading = ((PI * 2) / NUM_AGENTS) * ); - - //agents[a].x_position = random(12, 52); - //agents[a].y_position = random(12, 20); agents.push_back({ - random(2,63), - random(2,31), + random(SPAWN_MIN_X, SPAWN_MAX_X), + random(SPAWN_MIN_Y, SPAWN_MAX_Y), (random(0, 100) / 100.0) * (PI*2) }); - //agents.push_back({ - // random(6,58), - // random(4,28), - // (random(0, 100) / 100.0) * (PI*2) - //}); - //agents[a].x_position = random(0, 64); - //agents[a].y_position = random(0, 32); - //agents[a].heading = (random(0, 100) / 100.0) * (PI*2); } } @@ -124,166 +115,57 @@ void setup(){ init_attractant(); } -bool is_in_bounds(int x, int y) { - return (x < PANEL_WIDTH) and (y < PANEL_HEIGHT) and (x >= 0) and (y >= 0); -} +//void draw_bg() { +// int h_lines = round(PANEL_HEIGHT / 7); +// int v_lines = round(PANEL_WIDTH / 7); +// for(int v = 0; v <= v_lines; v++) { +// matrix->drawFastVLine(v*7+2, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); +// } +// for(int h = 0; h <= h_lines; h++) { +// matrix->drawFastHLine(0, 7*h + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); +// } +//} +// +//void draw_attractant() { +// for(int x = 0; x 17.0) { +// matrix->drawPixel(x, y, matrix->color565( +// int((255.0 / 255.0) * round(attractant[x][y])), +// int((80.0 / 255.0) * round(attractant[x][y])), +// int((83.0 / 255.0) * round(attractant[x][y])) +// ) +// ); +// } +// } +// } +//} -void draw_bg() { - int h_lines = round(PANEL_HEIGHT / 7); - int v_lines = round(PANEL_WIDTH / 7); - for(int v = 0; v <= v_lines; v++) { - matrix->drawFastVLine(v*7+2, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); - } - for(int h = 0; h <= h_lines; h++) { - matrix->drawFastHLine(0, 7*h + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); - } -} - -void draw_attractant() { - for(int x = 0; x 17.0) { - matrix->drawPixel(x, y, matrix->color565( - int((255.0 / 255.0) * round(attractant[x][y])), - int((80.0 / 255.0) * round(attractant[x][y])), - int((83.0 / 255.0) * round(attractant[x][y])) - ) - ); - } - } - } -} - -void setupGaussianKernel(float* kernel, int width, float sigma) { - float sum = 0.0; - for(int i = 0; i < width; i++) { - //kernel[width+i] = exp( -(i*i) / (2 * sigma * sigma)) / (PI * 2 * sigma * sigma); - kernel[i] = exp(-0.5f * (i * i) / (sigma * sigma)); - sum += kernel[width]; - } - for(int i; i < width; i++) { - kernel[i] = sum/width; - } -} - -#define GAUSS_WIDTH 1 -#define GAUSS_SIGMA 1.0 -#define DECAY_FACTOR 0.9 -float first_pass[PANEL_WIDTH][PANEL_HEIGHT]; -void gaussian_blur() { - float kernel[GAUSS_WIDTH]; - memset(first_pass, 0.0, sizeof first_pass); - setupGaussianKernel(kernel, GAUSS_WIDTH, GAUSS_SIGMA); - // horizontal pass - for (int x = 0; x < PANEL_WIDTH; x++) { - for(int y = 0; y < PANEL_HEIGHT; y++) { - float sum = attractant[x][y] * DECAY_FACTOR * kernel[0]; //0.0; - int additions = 1; - for (int x_offset = 1; x_offset < GAUSS_WIDTH; x_offset++) { - if (is_in_bounds(x+x_offset, y)) { - sum += attractant[x + x_offset][y] * kernel[x_offset]; - additions++; - } - if (is_in_bounds(x-x_offset, y)) { - sum += attractant[x - x_offset][y] * kernel[x_offset]; - additions++; - } - } - first_pass[x][y] = sum/GAUSS_WIDTH; - } - } - // vertical pass - for (int x = 0; x < PANEL_WIDTH; x++) { - for(int y = 0; y < PANEL_HEIGHT; y++) { - float sum = first_pass[x][y] * kernel[0]; //0.0; - int additions = 1; - for (int y_offset = 1; y_offset < GAUSS_WIDTH; y_offset++) { - if (is_in_bounds(x, y + y_offset)) { - sum += first_pass[x][y + y_offset] * kernel[y_offset]; - additions++; - } - if (is_in_bounds(x, y - y_offset)) { - sum += first_pass[x][y - y_offset] * kernel[y_offset]; - additions++; - } - } - attractant[x][y] = sum/GAUSS_WIDTH; - } - } -} - -#define BLUR_KERNEL_SIZE 1 -void box_blur() { - //Serial.println("memset: starting"); - memset(first_pass, 0.0, sizeof first_pass); - //Serial.println("memset: passed"); - // horizontal pass - for (int x = 0; x < PANEL_WIDTH; x++) { - for(int y = 0; y < PANEL_HEIGHT; y++) { - float sum; - sum = attractant[x][y] * DECAY_FACTOR; //0.0; - int additions = 1; - for (int x_offset = 1; x_offset < BLUR_KERNEL_SIZE; x_offset++) { - if (is_in_bounds(x+x_offset, y)) { - sum += attractant[x + x_offset][y]; - additions++; - } - if (is_in_bounds(x-x_offset, y)) { - sum += attractant[x - x_offset][y]; - additions++; - } - } - first_pass[x][y] = (sum/additions); - } - } - // vertical pass - for (int x = 0; x < PANEL_WIDTH; x++) { - for(int y = 0; y < PANEL_HEIGHT; y++) { - float sum = first_pass[x][y]; //0.0; - int additions = 1; - for (int y_offset = 1; y_offset < BLUR_KERNEL_SIZE; y_offset++) { - if (is_in_bounds(x, y + y_offset)) { - sum += first_pass[x][y + y_offset]; - additions++; - } - if (is_in_bounds(x, y - y_offset)) { - sum += first_pass[x][y - y_offset]; - additions++; - } - } - - float result = (sum/additions); // * DECAY_FACTOR; - //attractant[x][y] = (((8.0*attractant[x][y]) + result) / 9.0); - attractant[x][y] = result; - } - } -} - -int cleanup_x = 0; -void cleanup() { - int progress = iterations - NUM_ITERATIONS; - matrix->drawFastVLine(cleanup_x, 0, PANEL_HEIGHT, matrix->color565(254, 242, 255)); - if (cleanup_x > 0) { - matrix->fillRect(0, 0, cleanup_x, PANEL_HEIGHT, matrix->color565(16, 0, 16)); - } - int h_lines = round(PANEL_HEIGHT / 7); - int v_lines = round(cleanup_x / 7); - for(int v = 0; v < cleanup_x; v++) { - if (v%7 == 2) { - matrix->drawFastVLine(v, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); - } - } - for(int h = 0; h <= h_lines; h++) { - matrix->drawFastHLine(0, 7*h + 1, cleanup_x-1, matrix->color565(41, 17, 76)); - } - cleanup_x++; - if (cleanup_x > PANEL_WIDTH) { - iterations = 0; - cleanup_x = 0; - init_attractant(); - init_agents(); - } -} +//int cleanup_x = 0; +//void cleanup() { +// int progress = iterations - NUM_ITERATIONS; +// matrix->drawFastVLine(cleanup_x, 0, PANEL_HEIGHT, matrix->color565(254, 242, 255)); +// if (cleanup_x > 0) { +// matrix->fillRect(0, 0, cleanup_x, PANEL_HEIGHT, matrix->color565(16, 0, 16)); +// } +// int h_lines = round(PANEL_HEIGHT / 7); +// int v_lines = round(cleanup_x / 7); +// for(int v = 0; v < cleanup_x; v++) { +// if (v%7 == 2) { +// matrix->drawFastVLine(v, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); +// } +// } +// for(int h = 0; h <= h_lines; h++) { +// matrix->drawFastHLine(0, 7*h + 1, cleanup_x-1, matrix->color565(41, 17, 76)); +// } +// cleanup_x++; +// if (cleanup_x > PANEL_WIDTH) { +// iterations = 0; +// cleanup_x = 0; +// init_attractant(); +// init_agents(); +// } +//} void loop() { matrix ->flipDMABuffer(); @@ -291,8 +173,8 @@ void loop() { matrix->fillScreenRGB888(15, 0, 10); // draw background and organism - draw_bg(); - draw_attractant(); + draw_bg(matrix); + draw_attractant(matrix, attractant); for(int a = 0; a < NUM_AGENTS; a++) { //matrix->drawPixel(agents[a].x_position, agents[a].y_position, matrix->color565(0, 0, attractant[agents[a].x_position][agents[a].y_position])); @@ -336,12 +218,16 @@ void loop() { } iterations++; if (iterations % 2 == 0) { //64 && iterations % 64 == 0) { // (( == 0) { - box_blur(); + box_blur(attractant); //gaussian_blur(); ; } if (iterations >= NUM_ITERATIONS) { - cleanup(); + //cleanup(); + if (cleanup(matrix, &iterations)) { + init_attractant(); + init_agents(); + } } } diff --git a/organism/src/util.cpp b/organism/src/util.cpp new file mode 100644 index 0000000..e445ef5 --- /dev/null +++ b/organism/src/util.cpp @@ -0,0 +1,5 @@ +#include "constants.h" + +bool is_in_bounds(int x, int y) { + return (x < PANEL_WIDTH) and (y < PANEL_HEIGHT) and (x >= 0) and (y >= 0); +} diff --git a/organism/src/util.h b/organism/src/util.h new file mode 100644 index 0000000..3289174 --- /dev/null +++ b/organism/src/util.h @@ -0,0 +1,2 @@ +bool is_in_bounds(int x, int y); + diff --git a/organism/src/visual.cpp b/organism/src/visual.cpp new file mode 100644 index 0000000..9a96ed4 --- /dev/null +++ b/organism/src/visual.cpp @@ -0,0 +1,54 @@ +#include "constants.h" +#include "visual.h" + +void draw_bg(MatrixPanel_I2S_DMA *matrix) { + int h_lines = round(PANEL_HEIGHT / 7); + int v_lines = round(PANEL_WIDTH / 7); + for(int v = 0; v <= v_lines; v++) { + matrix->drawFastVLine(v*7+2, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); + } + for(int h = 0; h <= h_lines; h++) { + matrix->drawFastHLine(0, 7*h + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); + } +} + +void draw_attractant(MatrixPanel_I2S_DMA *matrix, float attractant[PANEL_WIDTH][PANEL_HEIGHT]) { + for(int x = 0; x 17.0) { + matrix->drawPixel(x, y, matrix->color565( + int((255.0 / 255.0) * round(attractant[x][y])), + int((80.0 / 255.0) * round(attractant[x][y])), + int((83.0 / 255.0) * round(attractant[x][y])) + ) + ); + } + } + } +} + +int cleanup_x = 0; +bool cleanup(MatrixPanel_I2S_DMA *matrix, int* iterations) { + int progress = *iterations - NUM_ITERATIONS; + matrix->drawFastVLine(cleanup_x, 0, PANEL_HEIGHT, matrix->color565(254, 242, 255)); + if (cleanup_x > 0) { + matrix->fillRect(0, 0, cleanup_x, PANEL_HEIGHT, matrix->color565(16, 0, 16)); + } + int h_lines = round(PANEL_HEIGHT / 7); + int v_lines = round(cleanup_x / 7); + for(int v = 0; v < cleanup_x; v++) { + if (v%7 == 2) { + matrix->drawFastVLine(v, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); + } + } + for(int h = 0; h <= h_lines; h++) { + matrix->drawFastHLine(0, 7*h + 1, cleanup_x-1, matrix->color565(41, 17, 76)); + } + cleanup_x++; + if (cleanup_x > PANEL_WIDTH) { + *iterations = 0; + cleanup_x = 0; + return true; + } + return false; +} diff --git a/organism/src/visual.h b/organism/src/visual.h new file mode 100644 index 0000000..04659d1 --- /dev/null +++ b/organism/src/visual.h @@ -0,0 +1,6 @@ +#include +#include "constants.h" +#include "config.h" +void draw_bg(MatrixPanel_I2S_DMA *matrix); +void draw_attractant(MatrixPanel_I2S_DMA *matrix, float attractant[PANEL_WIDTH][PANEL_HEIGHT]); +bool cleanup(MatrixPanel_I2S_DMA *matrix, int* iterations); From a0bca54bb1c307a18f82232ad465d45d9f88ce29 Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sun, 15 Dec 2024 14:49:48 +0100 Subject: [PATCH 16/17] =?UTF-8?q?=F0=9F=A7=B9=20cleanup,=20minor=20param?= =?UTF-8?q?=20changes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- organism/src/main.cpp | 66 ++++------------------------------------- organism/src/visual.cpp | 2 +- 2 files changed, 6 insertions(+), 62 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index a84dd08..40a7b25 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -17,8 +17,6 @@ MatrixPanel_I2S_DMA *matrix = nullptr; -//#define AGENT_DROP_AMOUNT 10 -//#define NUM_ITERATIONS 500 struct SlimeAgent { int x_position; int y_position; @@ -59,14 +57,12 @@ void init_attractant() { void init_agents() { AGENT_MOVE_DISTANCE = 1; //random(1, 3); - //AGENT_MOVE_ANGLE = random(0, 334) / 1000.0; AGENT_MOVE_ANGLE = 0.175;//random(0, 334) / 1000.0; - //AGENT_SENSOR_ANGLE = random(0, 334) / 1000.0; - if (random(0, 2) > 0) { - AGENT_SENSOR_ANGLE = 0.175; - } else { - AGENT_SENSOR_ANGLE = 0.0875; - } + //if (random(0, 2) > 0) { + // AGENT_SENSOR_ANGLE = 0.175; + //} else { + AGENT_SENSOR_ANGLE = 0.0875; + //} AGENT_SENSOR_DISTANCE = random(AGENT_SENSOR_DISTANCE_MIN * 1000.0, AGENT_SENSOR_DISTANCE_MAX * 1000.0) / 1000.0; NUM_AGENTS = random(NUM_AGENTS_MIN, NUM_AGENTS_MAX); @@ -115,58 +111,6 @@ void setup(){ init_attractant(); } -//void draw_bg() { -// int h_lines = round(PANEL_HEIGHT / 7); -// int v_lines = round(PANEL_WIDTH / 7); -// for(int v = 0; v <= v_lines; v++) { -// matrix->drawFastVLine(v*7+2, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); -// } -// for(int h = 0; h <= h_lines; h++) { -// matrix->drawFastHLine(0, 7*h + 1, PANEL_WIDTH, matrix->color565(41, 17, 76)); -// } -//} -// -//void draw_attractant() { -// for(int x = 0; x 17.0) { -// matrix->drawPixel(x, y, matrix->color565( -// int((255.0 / 255.0) * round(attractant[x][y])), -// int((80.0 / 255.0) * round(attractant[x][y])), -// int((83.0 / 255.0) * round(attractant[x][y])) -// ) -// ); -// } -// } -// } -//} - -//int cleanup_x = 0; -//void cleanup() { -// int progress = iterations - NUM_ITERATIONS; -// matrix->drawFastVLine(cleanup_x, 0, PANEL_HEIGHT, matrix->color565(254, 242, 255)); -// if (cleanup_x > 0) { -// matrix->fillRect(0, 0, cleanup_x, PANEL_HEIGHT, matrix->color565(16, 0, 16)); -// } -// int h_lines = round(PANEL_HEIGHT / 7); -// int v_lines = round(cleanup_x / 7); -// for(int v = 0; v < cleanup_x; v++) { -// if (v%7 == 2) { -// matrix->drawFastVLine(v, 0, PANEL_HEIGHT, matrix->color565(41, 17, 76)); -// } -// } -// for(int h = 0; h <= h_lines; h++) { -// matrix->drawFastHLine(0, 7*h + 1, cleanup_x-1, matrix->color565(41, 17, 76)); -// } -// cleanup_x++; -// if (cleanup_x > PANEL_WIDTH) { -// iterations = 0; -// cleanup_x = 0; -// init_attractant(); -// init_agents(); -// } -//} - void loop() { matrix ->flipDMABuffer(); delay(10); diff --git a/organism/src/visual.cpp b/organism/src/visual.cpp index 9a96ed4..4f50b49 100644 --- a/organism/src/visual.cpp +++ b/organism/src/visual.cpp @@ -15,7 +15,7 @@ void draw_bg(MatrixPanel_I2S_DMA *matrix) { void draw_attractant(MatrixPanel_I2S_DMA *matrix, float attractant[PANEL_WIDTH][PANEL_HEIGHT]) { for(int x = 0; x 17.0) { + if (attractant[x][y] > 15.0) { matrix->drawPixel(x, y, matrix->color565( int((255.0 / 255.0) * round(attractant[x][y])), int((80.0 / 255.0) * round(attractant[x][y])), From de5c0a5e1c6bdae186a81e9795e9b0d221e3f65e Mon Sep 17 00:00:00 2001 From: Felix Pankratz Date: Sun, 15 Dec 2024 14:53:30 +0100 Subject: [PATCH 17/17] =?UTF-8?q?=F0=9F=98=8C=20make=20sure=20to=20use=20c?= =?UTF-8?q?onstants...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- organism/src/main.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/organism/src/main.cpp b/organism/src/main.cpp index 40a7b25..01bc40e 100644 --- a/organism/src/main.cpp +++ b/organism/src/main.cpp @@ -37,10 +37,10 @@ std::vector agents; void init_attractant() { memset(attractant, 0.0, sizeof attractant); // draw a circle out of attractant - //for (int p = 0; p < 64; p++) { - // float angle = ((PI * 2) / 64) * p; - // int x = 31 + round(10 * sin(angle)); - // int y = 15 + round(10 * cos(angle)); + //for (int p = 0; p < PANEL_WIDTH; p++) { + // float angle = ((PI * 2) / PANEL_WIDTH) * p; + // int x = PANEL_WIDTH/2 + round(10 * sin(angle)); + // int y = PANEL_WIDTH/2 + round(10 * cos(angle)); // attractant[x][y] = 15.0; //} @@ -56,16 +56,16 @@ void init_attractant() { } void init_agents() { - AGENT_MOVE_DISTANCE = 1; //random(1, 3); + AGENT_MOVE_DISTANCE = 1; AGENT_MOVE_ANGLE = 0.175;//random(0, 334) / 1000.0; //if (random(0, 2) > 0) { // AGENT_SENSOR_ANGLE = 0.175; //} else { AGENT_SENSOR_ANGLE = 0.0875; //} - AGENT_SENSOR_DISTANCE = random(AGENT_SENSOR_DISTANCE_MIN * 1000.0, AGENT_SENSOR_DISTANCE_MAX * 1000.0) / 1000.0; NUM_AGENTS = random(NUM_AGENTS_MIN, NUM_AGENTS_MAX); + agents.clear(); for(int a = 0; a < NUM_AGENTS; a++) { float angle = ((PI * 2) / NUM_AGENTS) * a;