If you have a problem or need to report a bug please email : support@dsprobotics.com
There are 3 sections to this support area:
DOWNLOADS: access to product manuals, support files and drivers
HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects
USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here
NEW REGISTRATIONS - please contact us if you wish to register on the forum
Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright
My eagle eyes surrender... (Ruby Issue)
13 posts
• Page 1 of 2 • 1, 2
My eagle eyes surrender... (Ruby Issue)
So, I don't feel good, because I can't find an obvious reason for this behavior. Please help my bleeding, runny eyes!
Facts:
Mono to frame sends to a RubyEdit, frame by frame. Some sizes are calculated, important one is the "block size". This is a number, a "counter" is tested for. If counter and block size match a redraw is triggered. The counter is resetted to 0 in the draw method, and raised by one each time a frame comes in.
What I expect:
The view of the schematic shows some values. It should show a stable block size, a stable counter value and "true" for the equality check.
What I get:
A stable block size. But the counter shows anything from 0 to 12 (while the watch method at the piece of code that triggers the redraw shows a stable value equal to block size, just as expected) and equality check is always false (which is even weirder, since drawing only occurs when true!).
Please help me and give me back my confidence. If this is not a bug, what didn't I see?
(To see what I'm talking of, you need to switch on DS Out, of course)
Facts:
Mono to frame sends to a RubyEdit, frame by frame. Some sizes are calculated, important one is the "block size". This is a number, a "counter" is tested for. If counter and block size match a redraw is triggered. The counter is resetted to 0 in the draw method, and raised by one each time a frame comes in.
What I expect:
The view of the schematic shows some values. It should show a stable block size, a stable counter value and "true" for the equality check.
What I get:
A stable block size. But the counter shows anything from 0 to 12 (while the watch method at the piece of code that triggers the redraw shows a stable value equal to block size, just as expected) and equality check is always false (which is even weirder, since drawing only occurs when true!).
Please help me and give me back my confidence. If this is not a bug, what didn't I see?
(To see what I'm talking of, you need to switch on DS Out, of course)
- Attachments
-
- ruby_frame_issue.fsm
- (730 Bytes) Downloaded 881 times
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: My eagle eyes surrender... (Ruby Issue)
I have seen the schematic quickly, but I do not consider never reset any parameter in the Draw method,
because it is not only run by the Redraw method, so it is unpredictable.
perhaps resetting your counter before executing the method redraw, you get what you want?
because it is not only run by the Redraw method, so it is unpredictable.
perhaps resetting your counter before executing the method redraw, you get what you want?
- Tronic
- Posts: 539
- Joined: Wed Dec 21, 2011 12:59 pm
Re: My eagle eyes surrender... (Ruby Issue)
The reason is obvious to me... redraws work like events - "redraw" method doesn't call "draw" method directly - it only sends a "redraw" order into the queue - the actual draw may or may not happen later (if it even happens - redraws are limited to 100/s). I wouldn't be surprised if redraws happened on different thread. In your schematic once the actual draw happens several frames have already came through event method. The counter has already increased by then...
conclusion: Do not rely on synchronisation between frames, green and view (including mouse interaction).
conclusion: Do not rely on synchronisation between frames, green and view (including mouse interaction).
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
Re: My eagle eyes surrender... (Ruby Issue)
Thanks to both of you, but that can't be the reason(s). Of course I resetted the value before calling the draw method in the original. This example code was just to make absolutely sure that the value changed from valid to invalid between the event happening and the execution. I experienced the very same with my original code.
The drawing speed: This is what the counter is for. It makes sure that redraw is only called within drawable range. In this case the value is chosen so that the trigger happens ~30 times per second. And indeed, in my original code the view is drawn 30 times per second - just with nonsense values.
(A block is the number of frames needed to get all data, while drawing only 30 times per second). In this example, from 44100 samples per second they are send as frames of 256 values. A block size of 6 gets 6 frames of data (= 1536 values) and only then sends a redraw. That's 44100 / 1536 = 28.71 times per second. And that matches the frame rate, that the original draw method shows.
Conclusion: My math is correct, and while it works like it should, it just confuses the numbers. Without those, I can't build a buffer. Just drawing the block of data is no issue, works very well. But buffering would enable me to do more than just draw what comes in, and that's what I need.
Maybe if you take a little more time to actually investigate the issue?
The drawing speed: This is what the counter is for. It makes sure that redraw is only called within drawable range. In this case the value is chosen so that the trigger happens ~30 times per second. And indeed, in my original code the view is drawn 30 times per second - just with nonsense values.
(A block is the number of frames needed to get all data, while drawing only 30 times per second). In this example, from 44100 samples per second they are send as frames of 256 values. A block size of 6 gets 6 frames of data (= 1536 values) and only then sends a redraw. That's 44100 / 1536 = 28.71 times per second. And that matches the frame rate, that the original draw method shows.
Conclusion: My math is correct, and while it works like it should, it just confuses the numbers. Without those, I can't build a buffer. Just drawing the block of data is no issue, works very well. But buffering would enable me to do more than just draw what comes in, and that's what I need.
Maybe if you take a little more time to actually investigate the issue?
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: My eagle eyes surrender... (Ruby Issue)
Because you can't rely on redraw happening exactly when it's called, you need two buffers, that alternate.
PseudoCode:
hope it is clear enough.
PseudoCode:
- Code: Select all
def init
@buffers=[buffer0,buffer1]
@b=0
end
def draw(v)
buffer=@buffer[(@b+1)%2] #the previous buffer
#do your drawing
end
def event(i,v)
@buffer[@b] << v #write to current buffer
if @buffer[@b].length == some value
@b=(@b+1)%2 #alternates 0 and 1
redraw
end
end
hope it is clear enough.
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
Re: My eagle eyes surrender... (Ruby Issue)
And here's proof that I'm not crazy.
The same thing, but size hardcoded this time, and using a second variable to see the state of the counter. Works like a charme.
The same thing, but size hardcoded this time, and using a second variable to see the state of the counter. Works like a charme.
- Attachments
-
- ruby_frame_issue2.fsm
- (746 Bytes) Downloaded 886 times
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: My eagle eyes surrender... (Ruby Issue)
KG_is_back wrote:hope it is clear enough.
Yes it is, and thanks for taking the time. It is just not the issue (see example 2). But well, I might solve it after having put this aside for a day.
Thanks for wanting to help
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: My eagle eyes surrender... (Ruby Issue)
tulamide wrote:KG_is_back wrote:hope it is clear enough.
Yes it is, and thanks for taking the time. It is just not the issue (see example 2). But well, I might solve it after having put this aside for a day.
Thanks for wanting to help
No, that's exactly the problem. You move the value of @cx into new variable @v, which from that moment holds its value independent of @cx. It doesn't solve the issue - it "solves" the issue. You are just freezing the value of @cx (by storing it in @v) in the moment when "redraw" was called. I suggest you do the same with the buffer you need to pass to "draw" method.
It's not cheating - it's how continuous data sending works. If you need to send data to unsynchronized processing, you just store it in a buffer and send that buffer away. You can't rely that the buffer will be processed instantaneously.
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
Re: My eagle eyes surrender... (Ruby Issue)
KG_is_back wrote:tulamide wrote:KG_is_back wrote:hope it is clear enough.
Yes it is, and thanks for taking the time. It is just not the issue (see example 2). But well, I might solve it after having put this aside for a day.
Thanks for wanting to help
No, that's exactly the problem. You move the value of @cx into new variable @v, which from that moment holds its value independent of @cx. It doesn't solve the issue - it "solves" the issue. You are just freezing the value of @cx (by storing it in @v) in the moment when "redraw" was called. I suggest you do the same with the buffer you need to pass to "draw" method.
It's not cheating - it's how continuous data sending works. If you need to send data to unsynchronized processing, you just store it in a buffer and send that buffer away. You can't rely that the buffer will be processed instantaneously.
I know how it works. And I see your point. I worked very often with such situations. So I agree to all you say. Thing is, I worked this way.
Didn't you see from the code, that I don't rely on instantanous processing? I just made sure that the data is drawable at all times (by making sure the draw method isn't called more than 30 times per second, keeping it in a range with a lot of headroom). I don't care when exactly the drawing will happen. In my main code there's a copy of the array that will be drawn (aka the buffer). And, as I already said, that works just fine. No issues. The issue arises only when I use the frame size to calculate the block size. If I hardcode the blocksize, it again works.
Meanwhile I realized that one issue was the calculation's value. I used two integers for division, although I need a float as result. I corrected this, so that at least the blocksize is now valid. There must be a second (or third or ...) small error that I have in there.
However, if the code will run with my errors, but double buffered, I will try that. But I doubt it will work either single or double buffered, until the code issues aren't resolved. I rather expect it to work with my single buffer solution, as soon as all issues are resolved.
"There lies the dog buried" (German saying translated literally)
- tulamide
- Posts: 2714
- Joined: Sat Jun 21, 2014 2:48 pm
- Location: Germany
Re: My eagle eyes surrender... (Ruby Issue)
I think I don't understand what (you think) the issue is... setting the "block size" fixed solves nothing in the original schematic. @cx gets incremented by every incoming frame and @cx is reset in draw method (which is most definitely >=block size, because redraw happens after/at the same time as last frame to the block).
explanation of the problem - block fills with 6 values and calls for redraw. Once the draw method is called, the block has received multiple new values (that's why counter shows something >=6). The draw method resets the counter and the process repeats. In this scenario once the redraw actually happens the block received 6+ values =the average block size is bigger than 6 = less then 30fps will happen.
This way you will always draw all the data on screen, but the size of the block will fluctuate (because streams and redraws are not perfectly synced). If you want the frames to be cca.30 fps and always show block of same size, you need "buffer", to store the finished block for later drawing (like in example 2. you used @v to store exact value of @cx when redraw was called, opposed to when the draw happened).
explanation of the problem - block fills with 6 values and calls for redraw. Once the draw method is called, the block has received multiple new values (that's why counter shows something >=6). The draw method resets the counter and the process repeats. In this scenario once the redraw actually happens the block received 6+ values =the average block size is bigger than 6 = less then 30fps will happen.
This way you will always draw all the data on screen, but the size of the block will fluctuate (because streams and redraws are not perfectly synced). If you want the frames to be cca.30 fps and always show block of same size, you need "buffer", to store the finished block for later drawing (like in example 2. you used @v to store exact value of @cx when redraw was called, opposed to when the draw happened).
- KG_is_back
- Posts: 1196
- Joined: Tue Oct 22, 2013 5:43 pm
- Location: Slovakia
13 posts
• Page 1 of 2 • 1, 2
Who is online
Users browsing this forum: No registered users and 78 guests