-
Notifications
You must be signed in to change notification settings - Fork 5
Allow defining geometries (including more than 2 color lanes) via Python code #27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I saw this warning on the terminal...
Before, a weird error would be shown because of the blitter thread destructor running.
It's always the lowest numbered lanes. So now you can at least run the first lane of an Active3 with a standard matrix map
.. with 3 64x64 panels.
(however, there's no code yet to generate such schedules)
10/4 planes gives 100fps on the active3 spiral demo on 3 64x64 panels, or 1.2 megapixels/second. And to my eye, there's no brightness shimmer. All the below settings "look good" to my eye, higher FPS ones tend to look better to a camera. In "10/4" mode with my camera at 100FPS it still looks solid but because the beat frequency between the dither pattern and the shutter is pretty pronounced I can see it shift between the sub-frames. There's still some brightness variation between modes, with more planes being a little brighter than fewer planes. 10/0: 50fps 10/2: 72fps 10/4: 100fps 8/0: 92fps 8/2: 109fps 8/4: 134fps 5/0: 135fps 5/2: 153fps 5/4: 210fps
@FoamyGuy I know you don't have a multi-connector board to look at, so what'd be useful is to test that the existing examples still work for you on the adafruit boards & that the API changes & additions make sense. You can also check if temporal dithering is giving good results for your eyes & cameras too. |
if n_planes is not None: | ||
f = click.option("--num-planes", "n_planes", default=n_planes, help="The number of bit planes (color depth. Lower values can improve refresh rate in frames per second")(f) | ||
f = click.option("--num-planes", "n_planes", default=n_planes, help="The number of bit planes (color depth). Lower values can improve refresh rate in frames per second")(f) | ||
if n_temporal_planes is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jepler Does this argument (and/or the others near here) need to be conditional with this not None
check?
If I am understanding correctly this means that the --num-temporal-planes
argument is not valid unless the example code script includes something like:
@piomatter_click.standard_options(n_lanes=2, n_temporal_planes=4)
Is that understanding correct?
In the case where the code provides a value in the click.standard_option declaration, and the user also passes --num-temporal-planes
which would take precedent?
If it's possible have them be just CLI arguments and not need to be declared in the example scripts also I think that would make their usage less complex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. This new argument is only added to click if it's specified as non-None.
My thinking, which may be making more trouble than help: If the new command line argument is added to click by default, then any old code that doesn't have the python function parameter of the same name will suddenly break.
We're in alpha releases in this repo, so it's probably OK to just break things for now. The amount of code outside the repo that is using protomatter_click.standard_options
is essentially zero.
would you rather I change it so it's included by default?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I see. I do think it would be good to have it included by default. Agree there is likely little else using it at the moment so it's okay to have it break.
& add the simple multilane mapper to examples that use click
docs are wrong and this might be part of why .. but not all
There are still some problems & some build warnings but at least the sphinx docs have useful content now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jepler I'm going to merge this one now. I can update the default arguments behavior in a followup PR. I started working from this branch on the new xdisplay mirror example, I can update the existing examples in that one and make the breaking change after they're all updated so they won't break.
I see now there were newer commits that I missed before. Thank you! |
Thanks! If anything's not quite right we'll get it fixed. |
as a part of this, reorganize the code so that the code has package structure, and move the click options handling code into the package as well.
This also adds support for more than 2 color lanes (i.e., 6 lanes in a 3 connector system like the active3). However the C++ coded mappers don't support the additional lanes, so you have to create your own pixel mapper for now.
The new
rainbow_spiral_active3.py
demo drives 3 64x64 matrices using the active3 pinout. Thefbmirror
demo also has rudimentary support for the active3 pinout with 6 lanes.It remains to figure out what "decent support" for more than 2 lanes / 1 connector looks like. Based on internal discussion, we are OK with initially supporting just a basic linear arrangement per connector, which is what those two demos implement. However, it would be good to support this in a way that doesn't lead to people needing to copy & paste the code to calculate the matrix map.
Support for temporal dithering has also been added. This sends out data according to a "schedule sequence". The code supports creating either a simple schedule sequence, identical to the old sequence, in which every bit plane is sent every frame, e.g., with 5 bit depth, the schedule can be written
{9 16} {8 8} {7 4} {6 2} {5 1}
where the first9
is the most significant bit and16
is the relative length of time to illuminate it for.A temporal dither pattern has several schedules. It does each schedule in turn, but a frame switch is possible after any one individual schedule. For example, here are two more schedules for 5 total planes, but 2 or 4 temporal planes:
There are two good effects here: First, each schedule has fewer entries (5 entries became 4 or 2 entries). If each entry takes the same length of time, then frame rate increases by 20% for 2 temporal planes and 60% for 4 temporal planes.
Second, the largest weight number is smaller (here, 8 instead of 16). Because the granularity of control of the OE pin (which illuminates a set of LEDs) is equal to the pixel clock, a large color depth with a "narrow" matrix has to spend extra time illuminating LEDs rather than sending more pixel data. For example the biggest value in a "10/0" schedule is 512, while the biggest value in a "10/4" schedule is 128. So for a LED panel with fewer than 512 pixels across, this reduces the extra delays just to achive the needed LED "on" time for the highest bitplane.
In practice on a 64x64 panel, 10/0 runs at 50fps and 10/4 runs at 100fps, or 2x as fast. 8/0 runs at 92fps while 8/4 gets 132fps, or about 45% faster.