FastLED 3.9.15
Loading...
Searching...
No Matches

◆ advance()

void Ripple::advance ( byte ledColors[40][14][3])
inline

Definition at line 75 of file ripple.h.

75 {
76 unsigned long age = millis() - birthday;
77
78 if (state == dead)
79 return;
80
81 pressure += fmap(float(age), 0.0, float(lifespan), speed, 0.0); // Ripple slows down as it ages
82 // TODO: Motion of ripple is severely affected by loop speed. Make it time invariant
83
85 // Ripple is visible but hasn't moved - render it to avoid flickering
86 renderLed(ledColors, age);
87 }
88
89 while (pressure >= 1) {
90#ifdef DEBUG_ADVANCEMENT
91 Serial.print("Ripple ");
92 Serial.print(rippleId);
93 Serial.println(" advancing:");
94#endif
95
96 switch (state) {
97 case withinNode: {
98 if (justStarted) {
99 justStarted = false;
100 }
101 else {
102#ifdef DEBUG_ADVANCEMENT
103 Serial.print(" Picking direction out of node ");
104 Serial.print(position[0]);
105 Serial.print(" with agr. ");
106 Serial.println(behavior);
107#endif
108
109 int newDirection = -1;
110
111 int sharpLeft = (position[1] + 1) % 6;
112 int wideLeft = (position[1] + 2) % 6;
113 int forward = (position[1] + 3) % 6;
114 int wideRight = (position[1] + 4) % 6;
115 int sharpRight = (position[1] + 5) % 6;
116
117 if (behavior <= 2) { // Semi-random aggressive turn mode
118 // The more aggressive a ripple, the tighter turns it wants to make.
119 // If there aren't any segments it can turn to, we need to adjust its behavior.
120 byte anger = behavior;
121
122 while (newDirection < 0) {
123 if (anger == 0) {
124 int forwardConnection = nodeConnections[position[0]][forward];
125
126 if (forwardConnection < 0) {
127 // We can't go straight ahead - we need to take a more aggressive angle
128#ifdef DEBUG_ADVANCEMENT
129 Serial.println(" Can't go straight - picking more agr. path");
130#endif
131 anger++;
132 }
133 else {
134#ifdef DEBUG_ADVANCEMENT
135 Serial.println(" Going forward");
136#endif
137 newDirection = forward;
138 }
139 }
140
141 if (anger == 1) {
142 int leftConnection = nodeConnections[position[0]][wideLeft];
143 int rightConnection = nodeConnections[position[0]][wideRight];
144
145 if (leftConnection >= 0 && rightConnection >= 0) {
146#ifdef DEBUG_ADVANCEMENT
147 Serial.println(" Turning left or right at random");
148#endif
149 newDirection = random(2) ? wideLeft : wideRight;
150 }
151 else if (leftConnection >= 0) {
152#ifdef DEBUG_ADVANCEMENT
153 Serial.println(" Can only turn left");
154#endif
155 newDirection = wideLeft;
156 }
157 else if (rightConnection >= 0) {
158#ifdef DEBUG_ADVANCEMENT
159 Serial.println(" Can only turn right");
160#endif
161 newDirection = wideRight;
162 }
163 else {
164#ifdef DEBUG_ADVANCEMENT
165 Serial.println(" Can't make wide turn - picking more agr. path");
166#endif
167 anger++; // Can't take shallow turn - must become more aggressive
168 }
169 }
170
171 if (anger == 2) {
172 int leftConnection = nodeConnections[position[0]][sharpLeft];
173 int rightConnection = nodeConnections[position[0]][sharpRight];
174
175 if (leftConnection >= 0 && rightConnection >= 0) {
176#ifdef DEBUG_ADVANCEMENT
177 Serial.println(" Turning left or right at random");
178#endif
179 newDirection = random(2) ? sharpLeft : sharpRight;
180 }
181 else if (leftConnection >= 0) {
182#ifdef DEBUG_ADVANCEMENT
183 Serial.println(" Can only turn left");
184#endif
185 newDirection = sharpLeft;
186 }
187 else if (rightConnection >= 0) {
188#ifdef DEBUG_ADVANCEMENT
189 Serial.println(" Can only turn right");
190#endif
191 newDirection = sharpRight;
192 }
193 else {
194#ifdef DEBUG_ADVANCEMENT
195 Serial.println(" Can't make tight turn - picking less agr. path");
196#endif
197 anger--; // Can't take tight turn - must become less aggressive
198 }
199 }
200
201 // Note that this can't handle some circumstances,
202 // like a node with segments in nothing but the 0 and 3 positions.
203 // Good thing we don't have any of those!
204 }
205 }
206 else if (behavior == alwaysTurnsRight) {
207 for (int i = 1; i < 6; i++) {
208 int possibleDirection = (position[1] + i) % 6;
209
210 if (nodeConnections[position[0]][possibleDirection] >= 0) {
211 newDirection = possibleDirection;
212 break;
213 }
214 }
215
216#ifdef DEBUG_ADVANCEMENT
217 Serial.println(" Turning as rightward as possible");
218#endif
219 }
220 else if (behavior == alwaysTurnsLeft) {
221 for (int i = 5; i >= 1; i--) {
222 int possibleDirection = (position[1] + i) % 6;
223
224 if (nodeConnections[position[0]][possibleDirection] >= 0) {
225 newDirection = possibleDirection;
226 break;
227 }
228 }
229
230#ifdef DEBUG_ADVANCEMENT
231 Serial.println(" Turning as leftward as possible");
232#endif
233 }
234
235#ifdef DEBUG_ADVANCEMENT
236 Serial.print(" Leaving node ");
237 Serial.print(position[0]);
238 Serial.print(" in direction ");
239 Serial.println(newDirection);
240#endif
241
242 position[1] = newDirection;
243 }
244
245 position[0] = nodeConnections[position[0]][position[1]]; // Look up which segment we're on
246
247#ifdef DEBUG_ADVANCEMENT
248 Serial.print(" and entering segment ");
249 Serial.println(position[0]);
250#endif
251
252 if (position[1] == 5 || position[1] == 0 || position[1] == 1) { // Top half of the node
253#ifdef DEBUG_ADVANCEMENT
254 Serial.println(" (starting at bottom)");
255#endif
257 position[1] = 0; // Starting at bottom of segment
258 }
259 else {
260#ifdef DEBUG_ADVANCEMENT
261 Serial.println(" (starting at top)");
262#endif
264 position[1] = 13; // Starting at top of 14-LED-long strip
265 }
266 break;
267 }
268
269 case travelingUpwards: {
270 position[1]++;
271
272 if (position[1] >= 14) {
273 // We've reached the top!
274#ifdef DEBUG_ADVANCEMENT
275 Serial.print(" Reached top of seg. ");
276 Serial.println(position[0]);
277#endif
278 // Enter the new node.
279 int segment = position[0];
281 for (int i = 0; i < 6; i++) {
282 // Figure out from which direction the ripple is entering the node.
283 // Allows us to exit in an appropriately aggressive direction.
284 int incomingConnection = nodeConnections[position[0]][i];
285 if (incomingConnection == segment)
286 position[1] = i;
287 }
288#ifdef DEBUG_ADVANCEMENT
289 Serial.print(" Entering node ");
290 Serial.print(position[0]);
291 Serial.print(" from direction ");
292 Serial.println(position[1]);
293#endif
295 }
296 else {
297#ifdef DEBUG_ADVANCEMENT
298 Serial.print(" Moved up to seg. ");
299 Serial.print(position[0]);
300 Serial.print(" LED ");
301 Serial.println(position[1]);
302#endif
303 }
304 break;
305 }
306
307 case travelingDownwards: {
308 position[1]--;
309 if (position[1] < 0) {
310 // We've reached the bottom!
311#ifdef DEBUG_ADVANCEMENT
312 Serial.print(" Reached bottom of seg. ");
313 Serial.println(position[0]);
314#endif
315 // Enter the new node.
316 int segment = position[0];
318 for (int i = 0; i < 6; i++) {
319 // Figure out from which direction the ripple is entering the node.
320 // Allows us to exit in an appropriately aggressive direction.
321 int incomingConnection = nodeConnections[position[0]][i];
322 if (incomingConnection == segment)
323 position[1] = i;
324 }
325#ifdef DEBUG_ADVANCEMENT
326 Serial.print(" Entering node ");
327 Serial.print(position[0]);
328 Serial.print(" from direction ");
329 Serial.println(position[1]);
330#endif
332 }
333 else {
334#ifdef DEBUG_ADVANCEMENT
335 Serial.print(" Moved down to seg. ");
336 Serial.print(position[0]);
337 Serial.print(" LED ");
338 Serial.println(position[1]);
339#endif
340 }
341 break;
342 }
343
344 default:
345 break;
346 }
347
348 pressure -= 1;
349
351 // Ripple is visible - render it
352 renderLed(ledColors, age);
353 }
354 }
355
356#ifdef DEBUG_ADVANCEMENT
357 Serial.print(" Age is now ");
358 Serial.print(age);
359 Serial.print('/');
360 Serial.println(lifespan);
361#endif
362
363 if (lifespan && age >= lifespan) {
364 // We dead
365#ifdef DEBUG_ADVANCEMENT
366 Serial.println(" Lifespan is up! Ripple is dead.");
367#endif
368 state = dead;
369 position[0] = position[1] = pressure = age = 0;
370 }
371 }
byte ledColors[40][14][3]
int position[2]
Definition ripple.h:49
void renderLed(byte ledColors[40][14][3], unsigned long age)
Definition ripple.h:392
unsigned long birthday
Definition ripple.h:387
bool justStarted
Definition ripple.h:384
rippleState state
Definition ripple.h:42
float speed
Definition ripple.h:374
byte rippleId
Definition ripple.h:390
float pressure
Definition ripple.h:386
unsigned long lifespan
Definition ripple.h:375
byte behavior
Definition ripple.h:382
int segmentConnections[40][2]
Definition mapping.h:49
int nodeConnections[25][6]
Definition mapping.h:15
@ dead
Definition ripple.h:17
@ travelingUpwards
Definition ripple.h:19
@ withinNode
Definition ripple.h:18
@ travelingDownwards
Definition ripple.h:20
@ alwaysTurnsRight
Definition ripple.h:27
@ alwaysTurnsLeft
Definition ripple.h:28
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
Definition ripple.h:31

References alwaysTurnsLeft, alwaysTurnsRight, behavior, birthday, dead, fmap(), justStarted, ledColors, lifespan, nodeConnections, position, pressure, renderLed(), rippleId, segmentConnections, speed, state, travelingDownwards, travelingUpwards, and withinNode.

+ Here is the call graph for this function: