We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I am writing a dashboard UI for an arduino and am running into the error "pushmatrix cannot use push more than 32 times" this appears to be caused when a pushmatrix is used too many times without popmatrix. I am not totally sure what is causing it as all my pushes have pops. Additionally I tried putting all my different draw sections in try statements so I could see what was causing the problem, but this did not stop the error from happening. This makes me think I am not catching it in a try because there is really no drawing going on outside a try at this point. Finally, I am using the graphica library to plot the data in real time from the arduino. All graphing is in seperate try statements, so its the same thing.
Does anybody know what exception I should use for this error? Right now I am using runtime.
Thanks!
Answers
yes this is the problem. There is no easy solution, except to step through your code one line at a time. You cannot catch this exception because you cannot 'recover' from it, in other words the program crashes because OpenGL does cannot continue after this error.
Things to watch out for are
1) recursive functions where the push-pop-pair statements straddle the recursive call.
2) the push-pop-pair statements are not at the same level. For instance the push is inside a for loop but the pop statement is after the for loop ends.
3) the push-pop-pair are not in the same function. Although the syntax is OK it is very difficult to ensure that pop is called for every push or even if they are called in the right order.
Just an extra addendum:
4) Using push/pop (or anything related to the canvas) outside the "Animation" Thread.
Thanks a ton for both your speedy answers! So by running the code with no pushMatrix commands used on my side I think I have narrowed down that it is happening inside the grafica library. Which stinks because it is not my code. Alas.
Digging through the source for that library I found all kinds of push pop violations on this list.
Here is one function that has a push, then it enters a for loop with a push and a pop, then a pop. Theoretically this seems ok to me as it would accumulate 2 pushes before the pop. But it still seems off to me.
Here is another example. Here we have a popMatrix and a pushMatrix used in different functions.
Im at a bit of a loss how to proceed here. Should I just start re-writing the grafica library? Is there anyway to catch when there is a problem? I am thinking now to run the code with a print at each line to see where it fails. The problem is sometimes the code needs to run for 2 days because it will crash. This is my burden I suppose.
Thoughts?
I like many others have used graphica and no one has reported a similar problem.
I agree with GoToLoop's statements and add that the
beginDraw
andendDraw
methods are a pair and your code should make sure that one method is not called more often than the other.I ran a test last night commenting out all push and pop calls in my code. It crashed after only a few hours. The grafica library is the only possible source of the push and pop calls. Do either of you have ideas about how I might test to see how grafica is getting into this situation? I have tried to track down the creator of grafica via github with no success. I'm a bit at a loss.
There's still the possibility that you're misusing the grafica library...
I assume it crashed with the same error i.e. exceeded push limit. Normally this would happen almost immediately the program started the fact that it is happening much later is puzzling.
The fact that you have commented out all the push/popMatrix calls in your code does not prove the problem is with graphica.
For instance the
beginDraw()
method callspushMatrix
and theendDraw()
method callspopMatrix
so if you callbeginDraw()
more often thanendDraw()
you will eventually exceed the push limit. In this case it is NOT a problem caused by graphica but by incorrect use of the library.I assume that you are using the serial communication with your arduino device. Are you calling graphica library methods from the serial event handler because that would be wrong. Graphica methods should only be called from the main event thread e.g.
draw()
method.Difficult to help further without seeing the code.
@Koogs: Helpful...
@quark: actually helpful!! There is no doubt that it could be me using the library incorrectly. The documentation on the library is "light" and I am absolutely not an expert java-er. I assembled the calls based on the examples that are out there.
I can't upload the full code because it is too long but here are the two important sections:
In the serial event I do call Grafica methods. I use this event to add points to the array using the plot.addpoint function. I could move this to the draw method, but I don't see why this is wrong.
Below is the section of draw() where I run all the other grafica methods.
will try moving the grafica methods to draw and keep you posted. If you see anything let me know.
Like I've warned about before as an extra 4th rule:
You're calling methods from a library which manipulates the canvas outside the "Animation" Thread!!! [-X
A Processing sketch is a single Java application but it has multiple threads. The most important thread is the event despatch thread. This thread is used to process all mouse and keyboard events and to update the user interface i.e. the display.
Catching and processing serial events is done in a separate thread which is not synchronised with the event despatch thread. Attempting to access the UI (display) from the serial thread in any way is problematic, sometimes you might get away with it, in the sense you don't notice the problem, other times your program crashes. This might explain why it took so long for the program to crash.
The moral of the story is that updating the UI must ONLY be done in the event despatch thread. This thread executes the
draw()
method.Thanks a ton to you both. I have made the edits and am currently running a test.
Clearly I have little to no idea what I am doing. I will report what happens.
If you are interested in seeing what threads exist in a running sketch you can add the code from this discussion. Might prove interesting.
Bad news over here. Grafica still crashes in the same way with
pushMatrix
being called too many times.Here is the new serial section:
And here is the new draw section:
There are no calls that effect any kind of draw outside the draw thread. I added you thread tracking code and its working, but I am having trouble learning much. I am starting a new test now, but will it report the tread that was active when the crash occurs?
As usual, thanks for the help!
Update: On crash, no thread info is generated. Which makes sense. I was just hoping it would happen.
Add the following method
You aren't creating any additional threads yourself so pressing and releasing the 't' key will display the current threads. It should show whether the serial port is being accessed in another thread.