Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
LEDCircle non-contiguous rings?
#1
I have an octagonal room with exposed rafters running from near the center (think of a hub and spokes) and intend to run LED strips along the rafters. I'd love to be able to use LEDCircle because polar coordinates make a lot of sense in this context.

Is it possible to specify the rings as lists of pixels rather than a start and end pixel? Physically, the strips will follow the radii, not the rings. So, for a simplified example with a square in the middle and four spokes, I would want to be able to do something like:

rings = [       #ok maybe it should be called something else or how will it distinguish a list of two from start&end
   [0,1,2,8,9,10,16,17,18,24,25,26],  #0 - Center hub
   [3,11,19,27],  #1
   [4,12,20,28],  #2
   [5,13,21,29],  #3
   [6,14,22,30],  #4
   [7,15,23,31],  #5
]

Already doable? About to be implemented any moment now? Something I should code up myself?
#2
@landgrvi Great point! So, basically, you have fixed angles AND rings if I understand correctly. As you can imagine, LEDCircle is based off of what I had on hand, which had fixed rings but variable angles on each ring. Honestly, your setup makes more sense in most cases.

So, the quick answer is no, LEDCircle is not designed for that currently but it's totally doable. Fortunately, no one really uses it yet so I could probably make a breaking change if I had to Smile I think that what I would do is provide the option to pass in the concentric ring coords like I have now OR radii coords where it's assumed that each radius is equally distributed around the circle. Something like this:

radii = [ [0,9], [10,19], [20,29], [30,39] ]

This would represent basically radii at 0,90,180, and 270 degrees, each with 10 pixels. It's just a little easier to give first and last then specify every pixel. I could even support variable number of pixels per radii and maybe just assume they are still all the same length. So the given angle would be rounded to the nearest radii for that angle and the given ring would also be rounded to the nearest.

Shouldn't take me long to code something like that up. I can certainly keep it as part of LEDCircle so it's flexible. So, now that you've said it this falls into the category of "any moment now". Probably this weekend Smile I have other changes for v1.2.2 ready anyways.

If you feel like taking a stab at it or have any suggestions/requirements, feel free to pass along. I do my best to make things as versatile as possible but, as you can see, sometimes it just depends on the hardware I actually have.
#3
Oh yeah, radii would be a great way to specify it!

I've attached a picture of the ceiling for clarity. Imagine leds running around the edge of that central block and also out along the rafters. My current thinking about how to wire it physically is edge-segment -> rafter -> edge-segment -> rafter... but depending on aesthetic and practical considerations it might be closer to serpentine, i.e. edge-segment -> rafter -> rafter -> edge-segment -> edge-segment... or even all the edges and then all the rafters, or some other option that I haven't thought of yet.

Possible complexifications as I think about this (and stare at the ceiling):

Conceptually it has both a central ring *and* radii, and it would be nice to be able to specify them both. Obviously in a pure-spokes case the central ring might just be a point, or nonexistent.

In my particular case, the room is not symmetrical and thus the rafters are not all the same length. However, the led spacing will be the same (or close enough) throughout. Thus there are varying numbers of pixels per radius but we don't get to treat the radii as all the same length, so maybe an ability to specify the length of a radius (as percentage of unit circle? but it doesn't necessarily start at the middle, so percentage of unit circle for start and end?) is needed as well.  

This is departing pretty far from LEDCircle.  

Idea Generalising, I'm considering it now as a spiderweb, with multiple rings (for which we want to be able specify the radial coordinate, start and end angular coordinate, and pixels which might be physically non-contiguous) and multiple radii (for which we want to be able to specify the angular coordinate, start and end radial coordinate, and pixels which might be physically non-contiguous). Rings and radii could thus be anywhere and even have missing segments. Defaults would be that the rings are evenly spaced outwards and run all the way around, and that the radii are evenly spaced around the circle and run from the center to the edge; assumption would be that within a ring or radius the leds are evenly spaced. The disc for which you wrote LEDCircle is then a rings-only spiderweb with all the defaults.

If you don't want this to eat your weekend I totally understand! I'm pretty comfy in python and feel confident that I would be able to put this together in a way that would be fairly consistent with the existing classes. On the other hand, I do not have strips & power supplies in hand yet (first led project) and am likely to encounter unexpected hitches on the hardware side, so testing will be a while; and of course you already know your code. So, if you want to do it that would be awesome, but if not, let me know and I'll get on it.

Thanks!


Attached Files Thumbnail(s)
   
#4
Hmmm... rings in part and and spokes in the rest would be a bit weird. I'd have to think about how best to do that. The ring index would always be the same. Just have to determine how best to map everything.

I've gotten a bit sidetracked but will try to look at it shortly. Either way, I'm sure we can come up with *something* that will work for you. I promise that. So, build the display without fear. We'll make it work Smile

If you do feel like taking a stab at it, I'm not going to turn that down Smile But I'll certainly let you know if I make any progress. Gonna have to let my brain mull over it for a bit first... then I'll have a eureka moment at some point Tongue
#5
Great, I'll continue thinking along the spiderweb lines and see where that gets me!
#6
Just a quick update so as not to duplicate effort: added a --rings argument to visualizerUI to be able to display rings. Code still too messy to post and not integrated with the visualizer driver yet but anyway that's where I'm at.

e.g.
python visualizerUI.py --pixelsize 20 --rings "1,6,12,20,24,28,32,40,44,48"  #for a dotstar disk
python visualizerUI.py --pixelsize 10 --rings "64,8,8,8,8,8,8,8,8,8"                 #for a hub and spokes

See attached screenshots.

I think I see what you mean about how it's primarily going to be a mapping problem. I'm sure it will get murkier before it gets clearer...


Attached Files Thumbnail(s)
       
#7
(06-01-2015, 10:10 PM)landgrvi Wrote: Just a quick update so as not to duplicate effort: added a --rings argument to visualizerUI to be able to display rings. Code still too messy to post and not integrated with the visualizer driver yet but anyway that's where I'm at.

e.g.
python visualizerUI.py --pixelsize 20 --rings "1,6,12,20,24,28,32,40,44,48"  #for a dotstar disk
python visualizerUI.py --pixelsize 10 --rings "64,8,8,8,8,8,8,8,8,8"                 #for a hub and spokes

See attached screenshots.

I think I see what you mean about how it's primarily going to be a mapping problem. I'm sure it will get murkier before it gets clearer...

Whoa! That's epic Smile Mad respect for being able to stomach looking at the Visualizer UI code... it's certainly not anything I'm proud of, but it works Tongue Honestly didn't even think about adding anything to the visualizer just yet... but it makes sense. The spoke and ring layout screenshot you added certainly helps cement in my brain how you want it to work. 


I think the best thing for LEDCircle is going to define things per ring since that is the only real fixed item. You could then specify if each ring is an arc or a radius line... granted, your variable length spokes certainly throws a minor kink in things. But! There's a basically undocumented "feature" in LEDMatrix for when you do custom mapping... you can provide -1 (anything < 0 really) for any pixel in the coordinate map that doesn't actually exist. Basically just using it as filler and the underlying set() functions just ignore any index out of scope (< 0 or greater than the max).

I think the problem (for your layout) with my current mapping is that it is [first pixel, last pixel] for each ring which makes things a little less complex, but for you we need to be able to specify EACH pixel explicitly.

Ok... I think that just helped me figure it out.

right now I have this:

rings = [
[0,9],
[10,19],
[20,19]
]

I could leave that as default, but provide a new parameter, fullCoordMap = True or something that will tell it that instead of the simplified rings and [first,last] format, we are going to provide a map of EVERY pixel. Like I mentioned above, even in your hub and spoke layout, the rings are still effectively fixed. So, now see the attached image that has the indices. To list the "full" coordinate map we could do:

rings = [

[ 0, 1, 2, 3, 4, 5, 6, 7], #inner circle
[ 8,-1,11,-1,14,-1,17,-1], #1st ring of spokes
[ 9,-1,12,-1,15,-1,18,-1], #2nd ring of spokes
[10,-1,13,-1,16,-1,19,-1]  #3rd ring of spokes
]

So, the -1 values are just place holders for missing "degrees" on each ring. The center hub ring has  8 points (every 45 degrees) but since there's only spokes at 90 degree intervals, we fill in the missing degrees... oh wait... duh, this can be easier:

rings = [

[ 0, 1, 2, 3, 4, 5, 6, 7], #inner circle
[ 8,11,14,17], #1st ring of spokes
[ 9,12,15,18], #2nd ring of spokes
[10,13,16,19]  #3rd ring of spokes
]

Ok... sorry, this is all stream of though, but maybe how I got here will help.

So, basically, here's how I calculate which pixel to choose on each ring, given an angle...
I take the pixel count for that ring and divide 360 by it to get the number of degrees between each pixel on that ring (it's assumed they make a FULL circle). And then I divide the given angle by the degrees between each pixel in that ring (and round it down).

Right now that basically gives me an offset, and then I take the "first pixel" value for that ring and add the offset... but in this case, I would just use that as an index offset in the coordinate array for that ring.

So, yeah... no actual need to use the -1 filler values... though you could if you wanted to filter out the rounding down function. Basically, what I mean by that is that if there are pixels at 0,90,180, and 270 and you specify 120, it will just take the pixel at 90 degrees. This is easier... but maybe you would rather just filter out pixels outside of a certain range away from the given angle. Basically just drop it. This could also be done by allowing an offset limit... for example, only choose the pixel if it's within 5 degrees. I like that... think I'll add it too. But having dummy values would be another way.

Hope that makes sense Tongue Long story short... I think it's actually a bit easier than originally thought Smile We were probably over-thinking it.


Attached Files Thumbnail(s)
   
#8
(06-02-2015, 08:36 AM)Adam Wrote: rings = [

[ 0, 1, 2, 3, 4, 5, 6, 7], #inner circle
[ 8,11,14,17], #1st ring of spokes
[ 9,12,15,18], #2nd ring of spokes
[10,13,16,19]  #3rd ring of spokes
]

Ok... sorry, this is all stream of though, but maybe how I got here will help.

So, basically, here's how I calculate which pixel to choose on each ring, given an angle...
I take the pixel count for that ring and divide 360 by it to get the number of degrees between each pixel on that ring (it's assumed they make a FULL circle). And then I divide the given angle by the degrees between each pixel in that ring (and round it down).

Right now that basically gives me an offset, and then I take the "first pixel" value for that ring and add the offset... but in this case, I would just use that as an index offset in the coordinate array for that ring.

So, yeah... no actual need to use the -1 filler values... though you could if you wanted to filter out the rounding down function. Basically, what I mean by that is that if there are pixels at 0,90,180, and 270 and you specify 120, it will just take the pixel at 90 degrees. This is easier... but maybe you would rather just filter out pixels outside of a certain range away from the given angle. Basically just drop it. This could also be done by allowing an offset limit... for example, only choose the pixel if it's within 5 degrees. I like that... think I'll add it too. But having dummy values would be another way.

Hope that makes sense Tongue Long story short... I think it's actually a bit easier than originally thought Smile We were probably over-thinking it.

Yeah, I think the full coordinate map can solve it. Great to know about the -1 because it sounds useful in situations where physically there's no pixel there (e.g. some spokes shorter than others) but the layout requires a virtual pixel to get them spaced evenly around the ring.

Overthinkers represent!
#9
Hehehe... I always overthink things at first. And then usually have a forehead smacking moment a while later Tongue
I'll see about documenting the -1 thing more clearly... granted, there's so much documentation it'll just get lost anyways. But yeah, it's super powerful for weird layouts. And I would say that a circle is a weird layout!
#10
Thought you might enjoy this:
https://www.dropbox.com/s/qmcp54jxo00sv7e/LEDCircle_visualizer.mp4?dl=0

Also, don't know if in-thread is the right place to post these, but here are my visualizer.py and visualizerUI.py. I don't seem to have broken the text, strip, or matrix demos, but it's certainly possible that there are unintended consequences.


Attached Files
.zip   vis.zip (Size: 4.17 KB / Downloads: 1)


Forum Jump:


Users browsing this thread: 1 Guest(s)