Develop: Camera Settle

497 views
Skip to first unread message

ma...@makr.zone

unread,
Apr 22, 2020, 12:07:52 PM4/22/20
to OpenPnP
Hi

I plan to try and make the Camera Autosettle work more reliably for me.

It seems I can't really get this right for my setup, so I have some ideas.
  1. Using a fixed settle time works, but must be set awfully high to get every single capture right. There seem to be some occasional extra lags. I don't know why.
  2. So I am very interested in getting the Autosettle to work.
  3. The maximum absolute pixel difference method used now, seems a bit unstable at least for my ELP camera and stock Liteplacer LED ring lighting.
  4. I need to set a high value of 90 or so for it to settle. Probably due to sensor noise in the image (LEDs are too weak).
  5. There may also be some artifacts from image compression. Obviously compression is made for human perception, not for maximum absolute pixel difference scrutiny, especially on edges ;-).
  6. On the other hand with a high difference like 90 it will sometimes ok excessively motion-blurred images, it seems, as those may in deed be quite grey-in-grey if the machine zooms over the table (still investigating) ...
  7. .. or as an alternative explanation: I suspect the camera sometimes sends the same frame multiple times, excessive motion blur or dark images might trigger some sort of image post processing in the camera that combines sensor frames to improve quality(?) If this is done by repeating the same frame, it is easy to see that Autosettle will falsely ok it. This is still just a suspicion.
  8. A difference value set too low will hang the camera (no timeout in the org.openpnp.spi.base.AbstractCamera.autoSettleAndCapture() loop).
Now for the proposed changes:
  1. Would like to update the UI: add a combo box for method select: Fixed Time, Maximum Pixel Difference, new methods I'm investigating.
  2. Instead of the negative value trick, add a separate difference field and keep the settle time as the timeout.
  3. Add a @Commit to migrate.
  4. Add a Gaussian blur radius (switched off if left zero). This should handle sensor noise and compression artifacts, excessive image sharpening, plus all sorts of camera sensor binning and aliasing problems, moiré effects, etc.  
  5. Option for a circle mask, with diameter set as a factor of camera height. Switched off if zero. To restrict/emphasis the analysis of the center and not be distracted by peripheral noise (for bottom view, mostly).
  6. I would also like to reuse the graph I made for the vacuum stuff and plot the obtained differences over the frames.
  7. Plus perhaps a test button for a simulated move & settle.
The new methods I'm investigating will primarily be those offered by OpenCV Core.norm() i.e. getting the difference from the whole image rather the worst single pixel (after Gaussian blur and circle mask). I'm hoping for NORM_L2 to give very robust signals, but that's just speculation for now.

norm =  \forkthree{\|\texttt{src1}-\texttt{src2}\|_{L_{\infty}} =  \max _I | \texttt{src1} (I) -  \texttt{src2} (I)|}{if  $\texttt{normType} = \texttt{NORM\_INF}$ }
{ \| \texttt{src1} - \texttt{src2} \| _{L_1} =  \sum _I | \texttt{src1} (I) -  \texttt{src2} (I)|}{if  $\texttt{normType} = \texttt{NORM\_L1}$ }
{ \| \texttt{src1} - \texttt{src2} \| _{L_2} =  \sqrt{\sum_I (\texttt{src1}(I) - \texttt{src2}(I))^2} }{if  $\texttt{normType} = \texttt{NORM\_L2}$ }

I would also change over the maximum pixel difference method to use NORM_INF, I believe this is effectively the same but faster, as it creates no intermediate image.

If the new methods prove impractical I have other ideas up my sleeve. If nothing works, I believe the change still makes sense just with the current two methods to choose and new options to blur and mask. 

What do you think?


_Mark

Marek T.

unread,
Apr 22, 2020, 12:13:00 PM4/22/20
to OpenPnP
 "Maximum Pixel Difference" is the way basing on negative values?

ma...@makr.zone

unread,
Apr 22, 2020, 12:19:59 PM4/22/20
to ope...@googlegroups.com

In the current version, Yes, exactly.

Jason von Nieda

unread,
Apr 22, 2020, 12:40:02 PM4/22/20
to ope...@googlegroups.com
Hi Mark,

I think that sounds great, with one small change: Instead of overloading the settle time as either a timeout or settle time, let's just make the settle time truly settle time and have a separate field for Maximum Pixel Difference timeout. During the first boot a negative settle time would become 0 and we'd set the type to Maximum Pixel Difference with a default timeout of 250ms (or whatever seems appropriate).

Thanks,
Jason


--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/73bd57df-9607-4041-9d3a-cae6fec766b2%40googlegroups.com.

ma...@makr.zone

unread,
Apr 22, 2020, 1:07:10 PM4/22/20
to ope...@googlegroups.com

Hi Jason

thanks for the quick answer.

I'm not sure I understand correctly.

I planned to detect the upgrade in @Commit an migrate as follows

    public enum SettleMethod {
        FixedTime,
        MaximumPixelDifference,
        OverallDifference,
        EuclideanMetric,
    }

    @Attribute(required = false)
    protected SettleMethod settleMethod = null;

    @Attribute(required = false)
    protected long settleTimeMs = 250;

    @Attribute(required = false)
    protected double settleThreshold = 0.0;

    @Attribute(required = false)
    protected double settleGaussianBlur = 0.0;

    @Attribute(required = false)
    protected double settleMaskCircle = 0.0;

    @SuppressWarnings("unused")
    @Commit
    private void commit() throws Exception {
        if (settleMethod == null) {
            if (settleTimeMs < 0) {
                settleMethod = SettleMethod.MaximumPixelDifference;
                // migrate the old threshold, coded as a negative number
                settleThreshold = Math.abs(settleTimeMs);
                settleTimeMs = 500;
            }
            else {
                settleMethod = SettleMethod.FixedTime;
            }
        }
    }

I thought the same settleTimeMs can be used for both methods, once as a fixed time, once as a timeout. Otherwise one or the other field would be left unused. 

Or do you want to retain the FixedTime settle time as a separate field so the user can switch back and forth between methods, because the timeout will usually be more generous?

_Mark

Jason von Nieda

unread,
Apr 22, 2020, 1:22:36 PM4/22/20
to ope...@googlegroups.com
I'd like for settleTimeMs to only be used for the FixedTime method, and add a new timeoutMs for the MaximumPixelDifference. In other words, don't use the same variable for two different things. I understand that they accomplish similar things in that they both set the maximum time we'll settle, but for the sake of cleaner code and documentation I'd like them split.

Thanks,
Jason


ma...@makr.zone

unread,
Apr 22, 2020, 1:29:01 PM4/22/20
to ope...@googlegroups.com

Understand.

ma...@makr.zone

unread,
Apr 26, 2020, 6:29:03 PM4/26/20
to OpenPnP

ma...@makr.zone

unread,
Apr 26, 2020, 6:31:09 PM4/26/20
to ope...@googlegroups.com
--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

ma...@makr.zone

unread,
Apr 27, 2020, 7:50:49 AM4/27/20
to OpenPnP
Hi Jason

Exploring this some more, I found a strange effect. Suddenly the frame rate dropped to half, so I got 30p from a 60p mode.

Background: I added a third camera to test in my office (away from the machine) and even though it did not find the other two USB cameras, this seems to slow down the third camera:


I frantically searched for a problem with my new settling code, but it turns out the cameras somehow interlock with each other, even if unconnected!

Do you have an idea why that is?

Once I removed the third camera and instead reassigned the UBS device, I got (almost) no frame drops (as you see in the screenshot below, I got 6 frames after 104ms, which is expected for a 60p camera mode).

I guess the ocasional frame drop I still get comes from the camera view stealing one frame (not sure). Guess this could be remedied if need be.

_Mark


Jason von Nieda

unread,
Apr 27, 2020, 11:04:01 AM4/27/20
to ope...@googlegroups.com
Hey Mark, what if you remove the two cameras that are not being used? Does that make any difference?

Thanks,
Jason


--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

Harjit Singh

unread,
Apr 27, 2020, 11:42:14 AM4/27/20
to ope...@googlegroups.com
I hope I'm not butting in.

Could the third camera be on the same USB host controller and that is the issue?

On Windows, you can use USBView (download from Microsoft) to see if this is happening.

Or, you can unplug one of the other cameras to see if the frame rate goes back up...


ma...@makr.zone

unread,
Apr 27, 2020, 11:56:03 AM4/27/20
to ope...@googlegroups.com

Funny.

I haven't saved the original machine.xml where this happened, then I deleted the third camera. Now that I try to reproduce the same situation using a backup, I can't recreate it.

But it was not a singular incident, I tried everything like restarting OpenPNP, disconnecting the camera, etc. and it kept dropping frames. Now it all works with three cameras (two unconnected). Very strange.

:-(

Sorry to bother.

_Mark

ma...@makr.zone

unread,
Apr 27, 2020, 12:12:10 PM4/27/20
to ope...@googlegroups.com

> I hope I'm not butting in.

English is a funny language: "butting in" ...  :-)

> Could the third camera be on the same USB host controller and that is the issue?

It is definitely on the same controller, but the other two cameras are unconnected as they are on the machine and I am in the (home) office, so they can't compete for bandwidth (I hope). :-)

I'm acquainted with the problem, as I researched it quite profoundly here.

_Mark

ma...@makr.zone

unread,
Apr 27, 2020, 2:06:03 PM4/27/20
to ope...@googlegroups.com

Hi Jason

Something is still amiss. I was trying to recreate the problem when suddenly OpenPnP was hanging.

Can this be the classical deadlock?

1. GUI thread is blocked on my settle test button waiting for a capture in the Camera:

2. Camera's own thread is blocked by OpenPnpCaptureCamera.captureNotifier waiting in turn for the GUI (I guess).

Snake bites its tail?

Well that's my take. Frankly I don't know enough about Java's synchronized working together with native code blocking.

Strangely the GUI thread appears twice in Eclipse looking identical(???)

Most camera captures are probably from the machine tasks thread, so this won't happen in Jobs. But in this case I specifically want it to work with the machine not started, so I can use the test button with the machine unconnected i.e. with a third camera when I'm away from the machine (similar to capturing in the pipeline's editor).

Should I decouple this with yet another thread?

How?

Out of curiosity, why are frames pushed by the captureNotifier? Why not just let the camera view invalidate itself with the chosen fps, then in its paint handler (if and when it is executed at all) pull the frame instead? But use no blocking i.e. no CaptureStream.hasNewFrame(), just use the last captured frame instead (I believe the CaptureStream does just that, If you skip the hasNewFrame()). 

If this works, it could have several advantages:

  • Frames are only captured as long as a camera's view is actually visible. I believe Java Swing is highly optimized (from the olde days, when it still mattered) to only repaint what is absolutely necessary. No repaints for hidden or even just obstructed windows. Multiple repaint requests  are collapsed into one i.e. repaints also never pile up.
  • I believe users most often use just one camera view, so the other view(s) would leave the camera (and CPU) alone.
  • If the GUI is busy, nothing (bad) happens (i.e. no deadlocks, no machine captures blocked and no frames stolen, also no CPU wasted).
  • If the GUI was busy for some time (or the whole CPU struggling), no stale frames are displayed, i.e. no lag in the camera view (still stuttering, but that's half as bad).

Could this be related?

https://github.com/openpnp/openpnp/issues/760

_Mark

John Plocher

unread,
Apr 27, 2020, 2:12:27 PM4/27/20
to ope...@googlegroups.com
but but but (more butting in :-)....

If by "unconnected" you really mean "not configured in OpenPnP but still physically / electrically cabled into the USB ports", 
then the cameras still actively participate in the physical layer USB connection management protocols independent from the OS and Applications, 
including potentially reserving (or hanging on to a once reserved) isochronous USB controller bandwidth...

  -John




ma...@makr.zone

unread,
Apr 27, 2020, 2:24:01 PM4/27/20
to OpenPnP


On Monday, April 27, 2020 at 8:12:27 PM UTC+2, John Plocher wrote:
but but but (more butting in :-)....

If by "unconnected" you really mean "not configured in OpenPnP but still physically / electrically cabled into the USB ports", 
then the cameras still actively participate in the physical layer USB connection management protocols independent from the OS and Applications, 
including potentially reserving (or hanging on to a once reserved) isochronous USB controller bandwidth...


No it's the other way around. It is configured in OpenPnP but physically / electrically unconnected since last night. The machine is in my workshop two floors down. So unless there is some freaky USB Zombie / Phantom Limb Syndrom happening, there is nothing going on with these two USB devices :-)

_Mark

ma...@makr.zone

unread,
Apr 28, 2020, 7:39:51 AM4/28/20
to OpenPnP
Hi Jason

I figured it out. :-)

It has nothing to do with my new Autosettle code.

Step to reproduce with any OpenPnP 2 version:
  1. Use an OpenPnpCaptureCamera
  2. Make sure it is live in the CameraView
  3. Go to the Pipeline Editor
  4. Make sure it captured the camera image alright (does not matter whether settleFirst is active or not).
  5. Disconnect the camera (USB)
  6. Press the Update picture button in the Pipeline Editor.
  7. Try using the GUI.
I was playing around with the third ELP on my desk and gave it countless jolts to simulate settling. I must have gradually losened the tiny connector on the camera board and it then seems to have disconnected from USB sporadically.

I guess people will sometimes disconnect live USB cameras, so I fixed it here
as part of

The camera will then timeout and display the red X.

_Mark

Marek T.

unread,
Apr 28, 2020, 8:33:34 AM4/28/20
to OpenPnP
Hi Mark,

I don't know if I have accidental mechanical discontacts on USB or it is matter of noises. But from time to time I get the top camera frozen and dmesg says there was usb device disconnected. Since it happens at 100% of speed only, and never if speed is limited to 90% - I tend to opinion it is a problem of noises. Restart Openpnp makes camera alive again.

So your fix #995 should be great for me?

ma...@makr.zone

unread,
Apr 28, 2020, 9:10:46 AM4/28/20
to ope...@googlegroups.com

Hi Marek

The camera will not be reconnected, unless you go to the camera Wizard and fiddle something and then press Apply. This will restart the camera, but it will also unfortunately reset the device settings (sliders) to defaults. That's a pain anyways, it also means you can't exchange a camera of the same make and model with another one without losing settings.

Maybe Jason will know a way how to try and reconnect a camera without having to restart OpenPnP or lose settings?

_Mark

Marek T.

unread,
Apr 28, 2020, 12:20:17 PM4/28/20
to OpenPnP
Ok, so let's wait till Jason's wake up :-)

Mike M.

unread,
Apr 28, 2020, 12:41:38 PM4/28/20
to OpenPnP
Hi Mark
Yes I have the same issues - what I do is change the frame rate and than I can set it beck - but I need to restart Open PnP each time..
Mike

Maple_Dude

unread,
Apr 28, 2020, 7:52:06 PM4/28/20
to OpenPnP
Now that is very very cool


On Sunday, April 26, 2020 at 4:31:09 PM UTC-6, ma...@makr.zone wrote:

Larger GIF:

https://makr.zone/AdvancedCameraSettle.gif

;-)

Am 27.04.2020 um 00:29 schrieb ma...@makr.zone:
--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ope...@googlegroups.com.

Jason von Nieda

unread,
Apr 28, 2020, 11:45:25 PM4/28/20
to ope...@googlegroups.com
Reopening the device via openpnp-capture should be enough. Probably the "right" way would be to detect this situation and just retry, but that might require some changes in the native code, as well as the Java. An easy fix would just be to add an "Reconnect" button to the wizard.

Jason


--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

John deGlavina

unread,
Apr 30, 2020, 11:07:59 PM4/30/20
to OpenPnP
Hey Mark - I'm having an issue with my camera lighting after loading this up - bottom light is turning on too late. 
I have the scripting in Camera.BeforeSettle and Camera.AfterCapture
If I move from BeforeSettle to BeforeCapture I get a strobe effect as the bottom camera light turns on and off for each fast capture, but even then the light isn't syncing up. Adding a delay in the M code just slows everything down.

Here's a snippet from the log: 
2020-04-30 21:40:29.761 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-04-30 21:40:29.761 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-04-30 21:40:29.762 GcodeDriver TRACE: [serial://COM11] >> M810
2020-04-30 21:40:29.762 GcodeDriver TRACE: [serial://COM11] << ok
2020-04-30 21:40:29.763 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-04-30 21:40:29.768 AbstractCamera DEBUG: autoSettleAndCapture t=211 auto settle score: 1.3622143297099274
2020-04-30 21:40:29.770 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-04-30 21:40:29.783 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-04-30 21:40:29.784 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-04-30 21:40:29.786 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-04-30 21:40:29.786 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-04-30 21:40:29.787 GcodeDriver TRACE: [serial://COM11] >> M813
2020-04-30 21:40:29.788 GcodeDriver TRACE: [serial://COM11] << ok
2020-04-30 21:40:29.788 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]


For some reason the Camera.BeforeSettle isn't recorded in the logs, but the light is getting turned on, so it must be executing. In that file is this: 

 upCamLights = machine.getActuatorByName("UpCamLights");
 downCamLights = machine.getActuatorByName("DownCamLights");

if (camera.looking.equals(org.openpnp.spi.Camera.Looking.Up)) {
  /* we need looking up camera: turn on up lights and turn off down camera lights */
    upCamLights.actuate(true);
    downCamLights.actuate(false);
} else if (camera.looking.equals(org.openpnp.spi.Camera.Looking.Down)) {
  /* we need the down looking camera: turn off up looking camera light */
    upCamLights.actuate(false);
    downCamLights.actuate(true);
}

Any ideas on how to correct this? 

ma...@makr.zone

unread,
May 1, 2020, 3:30:20 AM5/1/20
to ope...@googlegroups.com

Hi John

> I'm having an issue with my camera lighting after loading this up

the code is real simple there, the script is called before it even enters the autoSettleAndCapture() that I changed, so I believe this is not related to the change:

https://github.com/openpnp/openpnp/blob/c6c100e175a71460ebfe969a7a880dd46f4e8c61/src/main/java/org/openpnp/spi/base/AbstractCamera.java#L667-L675

> I'm having an issue with my camera lighting after loading this up - bottom light is turning on too late.

I would expect some frames to be (half) dark in the settle, because of the lag brought in by the camera capturing, processing and compressing images, the USB communication, the driver uncompressing frames and the way OpenPnP is finally getting the frames. The first frame picked up by OpenPnP is always one behind, i.e. it is not waiting for a new frame, if one is already waiting to be picked up.

See how m_newFrame works here:

So what you get in the first frame is almost certainly an unlit one. The only reason for it to be "fresh" would be the off chance of CameraView snatching the last frame away right before. It depends on your Camera's preview fps setting of how probable that is, but I recommend against setting a high fps because currently the CameraView is snatching these frames away from Computer Vision i.e. they can't be used for both purposes and Camera Settling might then take longer.

I guess that dark image was there even before my change, only you didn't see it ;-)  These diagnostics tend to unearth some unexpected truths.


DANGER Heretical question: why do you switch the LEDs at all?

Admittedly it looks cool, and that's a perfectly valid reason :-). One good reason to switch LEDs might be if you have one camera light disturb the opposite camera. But I guess that should always be solved with a shade.  Other than that I don't see any real use.

I believe professional machines have expensive global shutter cameras and they use the LEDs like flashes to have a very short exposure times to get rid of motion blur and to overpower all ambient and background light. But this only works with global shutter (as opposed to rolling shutter) and the camera being synced in hardware to the LEDs. I believe they also drive the LEDs with much higher currents than what those could take for continuous operation.  Finally they might use the LED strobe in the video stream as a signal to sync the non-real-time vision software to the real time motion controller, so they can do vision in "fly-by" mode.

Most OpenPnP cameras are rolling shutter. So this flashing does not work. For my camera (ELP) I can't switch off white balance or it will deliver awfully tinted images that won't work with the green screen technique I use with BlindsFeeder etc. If I switch off the LEDs it takes longer for the camera to get the white balance right (that's admittedly not a good solution and I plan to add an RGB color correction to OpenPnP).


_Mark
--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

Marek T.

unread,
May 1, 2020, 4:20:05 AM5/1/20
to OpenPnP
I don't understand why everybody use beforeSettle or beforeCapture instead of beforePartAlign. Then Led is on much earlier and camera have a lot of time to "find itself" in new light condition. At least it's works perfect in 1.0.

ma...@makr.zone

unread,
May 1, 2020, 7:10:52 AM5/1/20
to ope...@googlegroups.com
It's probably best to use both
beforeSettle
and
beforePartAlign
otherwise you won't have light in nozzle tip calibration and other uses of the bottom camera including the new Camera Settle diagnostic tests.

beforeCapture
is definitely wrong for LEDs.

_Mark

Marek T.

unread,
May 1, 2020, 7:32:43 AM5/1/20
to OpenPnP
It will be the best when the LightActuator will be built-in into Openpnp instead of scripts using. As I remember it was somewhere far on Jason's list to add.
I made it for my 1.0 but it bases on hardcoded actuator name (not important for custom version). Works great since I've added the firings I needed to the required points.

ma...@makr.zone

unread,
May 1, 2020, 7:46:26 AM5/1/20
to ope...@googlegroups.com

>LightActuator

Agree. I've had it in 2.0 once, but Jason has extended ideas with setting intensity/color etc.

But the question still stands: Why do people want to switch the LEDs at all?

...other than that it looks cool ;-)

_Mark

--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

Marek T.

unread,
May 1, 2020, 8:05:56 AM5/1/20
to OpenPnP
My oppinion is like yours, since the real strobe cannot be used with cheap cameras like ELP - it makes not any sense for the bottom vision lightning.
Yes it looks cool :-).
I power bottom lightning constantly, even don't have there any actuator but the LEDs are connected directly to the machine power supplier.

For upper camera:
- if the higher power LEDs are used, they're emitting a lot of heat that may destroy the camera housing somehow (have you maybe seen a question of @Ravenspark on the Discord).
This is MAYBE my case as I use 12 LEDS in small box of the PLA coaxial lightning. But I have never measured the temperature there :-). So I can only imagine it is good to don't power the LEDs nonstop :-).
Also when you look on Keyence or other, with some large coolers and many Watts shown in their datasheet they take...

- when you bring the nozzle to the bottom vision and light from upper camera is facing directly onto the bottom camera lens - it's obvious case. In my case it happens when it is N1 or N2 but not N3.

John deGlavina

unread,
May 1, 2020, 8:15:47 AM5/1/20
to OpenPnP
Thanks for your through explanation as always Mark! 

The reason I have the bottom camera light switched is because it looks cool, and I rather not have the glaring light staring back at me when doing something with the machine. I always have the top light on except for when the bottom camera is being used. 

If I just leave on the bottom camera light, but still want to switch the top camera light off when the nozzles are over the bottom camera, what is the "right" way to set up the scripts? 
<div

ma...@makr.zone

unread,
May 1, 2020, 9:10:40 AM5/1/20
to ope...@googlegroups.com

From the theory of it it should always work if you use beforeSettle.

Yes the first frame may be dark, but that frame is stale anyway and it is a good thing if this forces the camera settling to get one more frame.

If you have multiple black frames at the beginning then you may need to increase "Debounce" so it won't compare the two black ones and think it is settled.

In fact I would be very interested in your settling images. You can get them as follows (using the newest OpenPnP 2.0):

  1. Set the machine to Debug or Trace log level.
  2. On the Camera Vision Wizard, choose and configure one of the Autosettle methods (i.e. not FixedTime)
  3. Switch on Diagnostics
  4. Prompt the camera to settle, either use the test buttons or use a real operation, like aligning a part, or visual homing.
  5. Go back to the camera, avoid moving your mouse over the graph then slowly scratch over the settle graph from the left to the right.
  6. This will create the settle images in your HOMEDIR/.openpnp2/org.openpnp.machine.reference.camera.OpenPnpCaptureCamera folder.
  7. Send them to me, please ;-)

_Mark

--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

John deGlavina

unread,
May 1, 2020, 10:16:39 AM5/1/20
to OpenPnP
This is with the scripting above in beforeSettle and afterCapture turning the bottom camera lights on and off. The light doesn't appear to be lining up with the capture as before, but I think it's bright enough to not be black, so it's actually calculating the settle time appropriately. 
settle1810435456852079319.png
settle2448736707392278067.png
settle2961571376110609373.png
settle5685079065549688460.png
settle6487559732415095406.png
settle7117012485926791024.png

John deGlavina

unread,
May 1, 2020, 10:20:28 AM5/1/20
to OpenPnP
And this is with the bottom camera light constantly on.


On Friday, May 1, 2020 at 9:10:40 AM UTC-4, ma...@makr.zone wrote:
settle1778750519199812770.png
settle8815876814839288749.png
settle2516122155863446117.png
settle1114796723026393212.png
settle1207359817632689311.png
settle7150067675518266599.png

ma...@makr.zone

unread,
May 1, 2020, 11:19:28 AM5/1/20
to ope...@googlegroups.com

Hi John

The first series with switched LEDs is no good, IMHO. This is strange.

Just to be sure, these are LEDs, right, not halogen or something that takes ages?

What happens if you set Threshold 0 and a Timeout of 1000ms? Will the light eventually come on? After how many Milliseconds and how many frames?

(need to change how OpenPnP creates log filenames. These should be sequential in some way)

_Mark

--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

John deGlavina

unread,
May 1, 2020, 12:04:35 PM5/1/20
to OpenPnP
Yes, LED. With the bottom switched on in BeforeSettle, and off in AfterCapture, the light never lines up with a capture. The captures are set to 10 FPS. For some reason, if I set to 30 FPS I get a lot of freezing despite having plenty of CPU and memory available. Here's the entire log for one settle with threshold of 0 and timeout of 1000ms:

2020-05-01 11:55:04.073 ReferenceNozzle DEBUG: N1.moveTo((234.025591, 79.143968, 0.000000, 540.000000 mm), 1.0) (runout compensation: (-0.131696, -0.027436, 0.000000, 0.000000 mm))
2020-05-01 11:55:04.074 GcodeDriver DEBUG: sendCommand(G0 X248.7264    F60000, 10000)...
2020-05-01 11:55:04.074 GcodeDriver TRACE: [serial://COM11] >> G0 X248.7264    F60000
2020-05-01 11:55:04.075 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.078 GcodeDriver DEBUG: sendCommand(serial://COM11 G0 X248.7264    F60000, 10000) => [ok]
2020-05-01 11:55:04.079 GcodeDriver DEBUG: sendCommand(G1 X248.8264    F6000, 10000)...
2020-05-01 11:55:04.079 GcodeDriver TRACE: [serial://COM11] >> G1 X248.8264    F6000
2020-05-01 11:55:04.080 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.080 GcodeDriver DEBUG: sendCommand(serial://COM11 G1 X248.8264    F6000, 10000) => [ok]
2020-05-01 11:55:04.080 ReferenceNozzle DEBUG: N1.moveTo((244.025591, 79.143968, 0.000000, 540.000000 mm), 1.0) (runout compensation: (-0.131696, -0.027436, 0.000000, 0.000000 mm))
2020-05-01 11:55:04.080 GcodeDriver DEBUG: sendCommand(G0 X258.7264    F60000, 10000)...
2020-05-01 11:55:04.080 GcodeDriver TRACE: [serial://COM11] >> G0 X258.7264    F60000
2020-05-01 11:55:04.081 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.081 GcodeDriver DEBUG: sendCommand(serial://COM11 G0 X258.7264    F60000, 10000) => [ok]
2020-05-01 11:55:04.082 GcodeDriver DEBUG: sendCommand(G1 X258.8264    F6000, 10000)...
2020-05-01 11:55:04.082 GcodeDriver TRACE: [serial://COM11] >> G1 X258.8264    F6000
2020-05-01 11:55:04.083 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.083 GcodeDriver DEBUG: sendCommand(serial://COM11 G1 X258.8264    F6000, 10000) => [ok]
2020-05-01 11:55:04.083 Scripting TRACE: Scripting.on Camera.BeforeSettle
2020-05-01 11:55:04.084 Scripting TRACE: Scripting.on found Camera.BeforeSettle.bsh
2020-05-01 11:55:04.089 ReferenceActuator DEBUG: UpCamLights.actuate(true)
2020-05-01 11:55:04.089 GcodeDriver DEBUG: sendCommand(M812, 10000)...
2020-05-01 11:55:04.089 GcodeDriver TRACE: [serial://COM11] >> M812
2020-05-01 11:55:04.307 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.308 GcodeDriver DEBUG: sendCommand(serial://COM11 M812, 10000) => [ok]
2020-05-01 11:55:04.308 ReferenceActuator DEBUG: DownCamLights.actuate(false)
2020-05-01 11:55:04.308 GcodeDriver DEBUG: sendCommand(M811, 10000)...
2020-05-01 11:55:04.308 GcodeDriver TRACE: [serial://COM11] >> M811
2020-05-01 11:55:04.309 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.309 GcodeDriver DEBUG: sendCommand(serial://COM11 M811, 10000) => [ok]
2020-05-01 11:55:04.309 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.331 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.332 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.334 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.334 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.335 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.335 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.335 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.335 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.335 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.335 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.336 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.336 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.345 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.363 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.363 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.365 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.365 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.366 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.366 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.366 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.366 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.366 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.366 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.367 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.367 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.372 AbstractCamera DEBUG: autoSettleAndCapture t=63 auto settle score: 61.34067134541703
2020-05-01 11:55:04.372 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.395 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.395 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.398 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.398 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.398 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.398 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.398 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.398 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.399 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.399 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.399 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.399 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.404 AbstractCamera DEBUG: autoSettleAndCapture t=95 auto settle score: 158.04792843485788
2020-05-01 11:55:04.404 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.426 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.427 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.429 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.429 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.429 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.430 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.430 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.430 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.430 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.430 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.431 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.431 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.436 AbstractCamera DEBUG: autoSettleAndCapture t=127 auto settle score: 39.8975247176252
2020-05-01 11:55:04.436 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.458 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.459 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.461 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.462 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.462 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.462 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.462 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.462 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.463 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.463 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.463 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.466 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.471 AbstractCamera DEBUG: autoSettleAndCapture t=162 auto settle score: 3.884243424197424
2020-05-01 11:55:04.471 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.491 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.492 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.494 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.494 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.494 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.495 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.495 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.495 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.495 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.495 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.496 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.496 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.501 AbstractCamera DEBUG: autoSettleAndCapture t=192 auto settle score: 2.851009703972038
2020-05-01 11:55:04.501 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.522 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.523 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.525 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.525 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.525 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.526 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.526 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.526 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.526 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.526 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.527 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.527 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.531 AbstractCamera DEBUG: autoSettleAndCapture t=222 auto settle score: 2.6164583269905326
2020-05-01 11:55:04.531 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.554 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.554 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.557 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.557 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.557 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.557 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.557 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.558 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.558 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.558 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.558 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.559 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.563 AbstractCamera DEBUG: autoSettleAndCapture t=254 auto settle score: 2.3212501824686043
2020-05-01 11:55:04.563 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.586 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.587 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.589 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.589 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.589 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.594 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.594 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.595 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.595 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.595 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.595 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.596 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.600 AbstractCamera DEBUG: autoSettleAndCapture t=291 auto settle score: 3.239129007212365
2020-05-01 11:55:04.600 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.634 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.635 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.637 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.637 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.637 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.638 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.638 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.638 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.638 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.638 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.639 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.639 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.643 AbstractCamera DEBUG: autoSettleAndCapture t=334 auto settle score: 3.3586861743534335
2020-05-01 11:55:04.644 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.669 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.669 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.672 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.672 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.672 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.672 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.673 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.673 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.673 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.673 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.674 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.674 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.677 AbstractCamera DEBUG: autoSettleAndCapture t=368 auto settle score: 3.011825654300086
2020-05-01 11:55:04.678 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.698 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.699 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.701 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.701 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.701 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.701 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.702 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.702 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.702 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.702 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.703 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.703 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.707 AbstractCamera DEBUG: autoSettleAndCapture t=398 auto settle score: 2.51681853245877
2020-05-01 11:55:04.708 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.734 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.735 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.737 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.737 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.737 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.738 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.738 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.738 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.738 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.738 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.739 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.739 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.743 AbstractCamera DEBUG: autoSettleAndCapture t=434 auto settle score: 2.575413153163592
2020-05-01 11:55:04.744 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.763 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.764 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.766 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.766 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.767 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.767 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.767 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.767 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.767 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.767 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.768 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.768 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.773 AbstractCamera DEBUG: autoSettleAndCapture t=464 auto settle score: 2.589821723444164
2020-05-01 11:55:04.773 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.794 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.795 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.797 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.797 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.797 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.798 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.798 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.799 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.799 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.799 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.799 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.799 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.804 AbstractCamera DEBUG: autoSettleAndCapture t=495 auto settle score: 2.3442863096342257
2020-05-01 11:55:04.804 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.827 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.827 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.830 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.830 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.830 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.830 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.831 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.831 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.831 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.831 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.832 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.832 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.836 AbstractCamera DEBUG: autoSettleAndCapture t=527 auto settle score: 2.262750850018355
2020-05-01 11:55:04.837 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.857 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.858 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.861 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.861 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.861 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.861 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.862 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.862 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.862 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.862 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.862 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.862 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.866 AbstractCamera DEBUG: autoSettleAndCapture t=557 auto settle score: 2.736699727450884
2020-05-01 11:55:04.867 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.895 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.896 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.898 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.898 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.898 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.899 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.899 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.899 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.899 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.899 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.900 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.900 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.904 AbstractCamera DEBUG: autoSettleAndCapture t=595 auto settle score: 2.640859241816555
2020-05-01 11:55:04.904 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.923 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.924 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.926 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.926 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.926 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.927 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.927 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.927 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.927 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.927 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.928 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.928 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.933 AbstractCamera DEBUG: autoSettleAndCapture t=624 auto settle score: 2.411057951217945
2020-05-01 11:55:04.933 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.954 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.955 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.957 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.957 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.957 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.958 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.958 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.958 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.958 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.958 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.959 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.959 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.963 AbstractCamera DEBUG: autoSettleAndCapture t=654 auto settle score: 2.327845322310279
2020-05-01 11:55:04.964 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:04.986 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:04.987 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:04.989 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:04.989 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:04.989 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:04.990 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.990 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:04.990 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:04.990 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:04.990 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:04.991 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:04.991 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:04.995 AbstractCamera DEBUG: autoSettleAndCapture t=686 auto settle score: 4.382946359226127
2020-05-01 11:55:04.995 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.019 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.019 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.021 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.021 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.021 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.022 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.022 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.022 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.022 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.022 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.023 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.023 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.027 AbstractCamera DEBUG: autoSettleAndCapture t=718 auto settle score: 2.7198686138304207
2020-05-01 11:55:05.028 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.069 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.070 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.072 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.072 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.072 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.073 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.073 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.073 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.073 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.073 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.074 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.074 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.079 AbstractCamera DEBUG: autoSettleAndCapture t=770 auto settle score: 2.7394680325258425
2020-05-01 11:55:05.079 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.099 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.099 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.101 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.102 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.102 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.102 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.102 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.102 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.102 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.102 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.103 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.103 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.107 AbstractCamera DEBUG: autoSettleAndCapture t=798 auto settle score: 3.7106092600195115
2020-05-01 11:55:05.107 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.131 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.132 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.134 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.134 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.134 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.135 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.135 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.135 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.135 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.135 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.135 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.136 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.140 AbstractCamera DEBUG: autoSettleAndCapture t=831 auto settle score: 2.4371088218948787
2020-05-01 11:55:05.141 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.162 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.163 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.165 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.165 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.165 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.166 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.166 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.166 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.166 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.167 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.167 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.167 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.171 AbstractCamera DEBUG: autoSettleAndCapture t=862 auto settle score: 2.316937443999051
2020-05-01 11:55:05.171 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.193 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.194 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.196 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.196 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.196 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.197 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.197 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.198 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.198 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.198 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.198 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.198 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.203 AbstractCamera DEBUG: autoSettleAndCapture t=894 auto settle score: 2.2890023068870358
2020-05-01 11:55:05.203 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.231 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.231 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.233 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.233 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.233 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.233 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.233 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.234 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.234 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.234 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.234 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.235 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.239 AbstractCamera DEBUG: autoSettleAndCapture t=930 auto settle score: 2.280588604623982
2020-05-01 11:55:05.239 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.261 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.262 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.264 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.264 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.264 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.264 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.265 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.265 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.265 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.265 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.266 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.266 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.270 AbstractCamera DEBUG: autoSettleAndCapture t=961 auto settle score: 3.6911968101613386
2020-05-01 11:55:05.270 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.290 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.291 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.294 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.294 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.294 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.295 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.295 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.295 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.295 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.295 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.296 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.296 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.300 AbstractCamera DEBUG: autoSettleAndCapture t=991 auto settle score: 2.6952125767977555
2020-05-01 11:55:05.300 Scripting TRACE: Scripting.on Camera.BeforeCapture
2020-05-01 11:55:05.321 Scripting TRACE: Scripting.on Camera.AfterCapture
2020-05-01 11:55:05.322 Scripting TRACE: Scripting.on found Camera.AfterCapture.bsh
2020-05-01 11:55:05.324 ReferenceActuator DEBUG: UpCamLights.actuate(false)
2020-05-01 11:55:05.324 GcodeDriver DEBUG: sendCommand(M813, 10000)...
2020-05-01 11:55:05.324 GcodeDriver TRACE: [serial://COM11] >> M813
2020-05-01 11:55:05.325 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.325 GcodeDriver DEBUG: sendCommand(serial://COM11 M813, 10000) => [ok]
2020-05-01 11:55:05.325 ReferenceActuator DEBUG: DownCamLights.actuate(true)
2020-05-01 11:55:05.325 GcodeDriver DEBUG: sendCommand(M810, 10000)...
2020-05-01 11:55:05.325 GcodeDriver TRACE: [serial://COM11] >> M810
2020-05-01 11:55:05.326 GcodeDriver TRACE: [serial://COM11] << ok
2020-05-01 11:55:05.326 GcodeDriver DEBUG: sendCommand(serial://COM11 M810, 10000) => [ok]
2020-05-01 11:55:05.330 AbstractCamera DEBUG: autoSettleAndCapture t=1021 auto settle score: 2.4485397861869496
2020-05-01 11:55:05.333 AbstractCamera DEBUG: autoSettleAndCapture in 1024 ms

ma...@makr.zone

unread,
May 1, 2020, 3:10:41 PM5/1/20
to OpenPnP
Hi

like I said before, I never switch my lights. This is the first time I'm looking into this.

BUT: How the heck is this supposed to work? There is no Camera.AfterSettle script, so you can't switch off the LEDs at the right time.

AfterCapture won't work. It is clear from John's script that the camera light will be switched off after the first frame is returned.

I don't think this works at all.

However I made a PR with the missing Script trigger. Read in the PR for why I think this was broken:


_Mark



Jason von Nieda

unread,
May 1, 2020, 3:19:12 PM5/1/20
to ope...@googlegroups.com
Okay, I am getting more and more lost here. Camera lighting has certainly not been broken for months, and is typically used with BeforeSettle and AfterCapture. Why would you want to turn the lights off after settling and before making the actual capture?

Also, your PR says "I guess it's the way the OpenPnpCaptureCamera now works, capturing the frame that is readily available and not strictly waiting for a new one." - but the code does the exact opposite of that - doesn't it?

Jason


--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

ma...@makr.zone

unread,
May 1, 2020, 4:41:16 PM5/1/20
to ope...@googlegroups.com

Hi Jason

Thanks for looking into this.

> Camera lighting has certainly not been broken for months, and is typically used with BeforeSettle and AfterCapture.

I must be more precise:

If you use the FixedTime methode (positive Settle Time in the previous version) there is a Thread.sleep() that will make sure there is no unlit frame in the buffer, so this does not happen. During the Thread.sleep there is also no call to capture(), so no AfterCapture script can turn the LED back off.

However if you use Autosettle (negative Settle Time in the previous version) there is a loop of capture() calls, each of which turns the LED back off by triggering the AfterCapture script. I'm quite convinced I haven't changed any of that. See the original loop:

https://github.com/markmaker/openpnp/commit/bb5c03521eeca683caefdaec0087082f4f96ae8a#diff-0abadd12f5c7acd7b2a4cabbbc9770f4


> Why would you want to turn the lights off after settling and before making the actual capture?

It happens, because of the multiple capture()s in the loop. The way I trace the code, the actual capture you mention is part of the settling . There is no extra capture() after the settle was deemed ok. Hence the name settleAndCapture().

_Mark

John deGlavina

unread,
May 1, 2020, 4:56:53 PM5/1/20
to OpenPnP
That explains what I was seeing. If I reverted to the previous method of a static settle time, the light would stay on much longer.  
To unsubscribe from this group and stop receiving emails from it, send an email to ope...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ope...@googlegroups.com.

John deGlavina

unread,
May 1, 2020, 4:57:24 PM5/1/20
to OpenPnP
Thanks for doing that so quickly! 

Jason von Nieda

unread,
May 5, 2020, 12:05:01 AM5/5/20
to ope...@googlegroups.com
Hi Mark,

There's a lot to digest here, and I'm not sure if it all still applies, but I saw you pinged me so I will give some quick answers and if we need to go more in depth we can do that.


On Mon, Apr 27, 2020 at 1:06 PM ma...@makr.zone <ma...@makr.zone> wrote:

Hi Jason

Something is still amiss. I was trying to recreate the problem when suddenly OpenPnP was hanging.

Can this be the classical deadlock?

1. GUI thread is blocked on my settle test button waiting for a capture in the Camera:

2. Camera's own thread is blocked by OpenPnpCaptureCamera.captureNotifier waiting in turn for the GUI (I guess).

Snake bites its tail?

Well that's my take. Frankly I don't know enough about Java's synchronized working together with native code blocking.


I don't think there is any native code blocking here. The basic idea is that we want to send a frame on two occasions:

1. When we've waited long enough for the FPS setting, or.
2. When a frame has been captured by the vision system. This is the "don't waste a frame" comment.

The reason behind this complexity was to support the "0" setting for FPS in that we only actually capture when a movement is made. It's a hack, and probably not a well considered one.

hasNewFrame() is used to avoid transferring megabytes of memory repeatedly between native and Java when nothing has actually happened in the camera later.

Strangely the GUI thread appears twice in Eclipse looking identical(???)

Most camera captures are probably from the machine tasks thread, so this won't happen in Jobs. But in this case I specifically want it to work with the machine not started, so I can use the test button with the machine unconnected i.e. with a third camera when I'm away from the machine (similar to capturing in the pipeline's editor).

Should I decouple this with yet another thread?

Generally - yes. You should never block in the UI thread because, as you saw, it blocks the UI. If you need to do something that takes more than a few ms it should be in it's own thread.

How?

Out of curiosity, why are frames pushed by the captureNotifier? Why not just let the camera view invalidate itself with the chosen fps, then in its paint handler (if and when it is executed at all) pull the frame instead? But use no blocking i.e. no CaptureStream.hasNewFrame(), just use the last captured frame instead (I believe the CaptureStream does just that, If you skip the hasNewFrame()). 

Frames are pushed because the original OpenCV camera implementation, and some other existing ones, push frames from the OS layer. Instead of asking for frames, there is a callback, so when I wrote it I figured that if the OS is telling us a frame is available, we should display it.

Additionally, I had originally envisioned the camera being visible in multiple places, and I didn't want each of those running their own thread asking the camera for images, so I used a listener system to send frames as they were ready.

The FPS setting (on the camera) is intended to be a hint to the camera driver to only bother capturing that many FPS regardless of how many are going to be displayed.

If this works, it could have several advantages:

  • Frames are only captured as long as a camera's view is actually visible. I believe Java Swing is highly optimized (from the olde days, when it still mattered) to only repaint what is absolutely necessary. No repaints for hidden or even just obstructed windows. Multiple repaint requests  are collapsed into one i.e. repaints also never pile up.
  • I believe users most often use just one camera view, so the other view(s) would leave the camera (and CPU) alone.
  • If the GUI is busy, nothing (bad) happens (i.e. no deadlocks, no machine captures blocked and no frames stolen, also no CPU wasted).
  • If the GUI was busy for some time (or the whole CPU struggling), no stale frames are displayed, i.e. no lag in the camera view (still stuttering, but that's half as bad).

Could this be related?

https://github.com/openpnp/openpnp/issues/760


Probably not. This seems to be related to memory, and it seems to be Windows specific, and it only seems to happen to certain users, for some reason. I think it's probably due to the well documented problem of OpenCV not releasing memory correctly when called from Java.

I don't know if that all helps or not. If not, let's narrow it down and try again :)

Jason


_Mark


Am 27.04.2020 um 17:55 schrieb ma...@makr.zone:

Funny.

I haven't saved the original machine.xml where this happened, then I deleted the third camera. Now that I try to reproduce the same situation using a backup, I can't recreate it.

But it was not a singular incident, I tried everything like restarting OpenPNP, disconnecting the camera, etc. and it kept dropping frames. Now it all works with three cameras (two unconnected). Very strange.

:-(

Sorry to bother.

_Mark

Am 27.04.2020 um 17:03 schrieb Jason von Nieda:
Hey Mark, what if you remove the two cameras that are not being used? Does that make any difference?

Thanks,
Jason


On Mon, Apr 27, 2020 at 6:50 AM ma...@makr.zone <ma...@makr.zone> wrote:
Hi Jason

Exploring this some more, I found a strange effect. Suddenly the frame rate dropped to half, so I got 30p from a 60p mode.

Background: I added a third camera to test in my office (away from the machine) and even though it did not find the other two USB cameras, this seems to slow down the third camera:


I frantically searched for a problem with my new settling code, but it turns out the cameras somehow interlock with each other, even if unconnected!

Do you have an idea why that is?

Once I removed the third camera and instead reassigned the UBS device, I got (almost) no frame drops (as you see in the screenshot below, I got 6 frames after 104ms, which is expected for a 60p camera mode).

I guess the ocasional frame drop I still get comes from the camera view stealing one frame (not sure). Guess this could be remedied if need be.

_Mark


--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/1bd18693-ad84-4ace-839e-22265a2f2b40%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/CA%2BQw0jyu-RdQsY6Dfno8yi%2B-vzKN7M7S9ypR2ebgmpJ7wF4OXg%40mail.gmail.com.
--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/44acc53c-1d31-a53f-8553-cfef0c780766%40makr.zone.

--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/5a5b43b7-26df-cac5-66bd-ab793d52c60b%40makr.zone.

John deGlavina

unread,
May 5, 2020, 9:27:45 AM5/5/20
to OpenPnP
After moving the light script from AfterCapture to AfterSettle, the lighting works as it did previously. Thanks Mark! 


On Friday, May 1, 2020 at 3:10:41 PM UTC-4, ma...@makr.zone wrote:

ma...@makr.zone

unread,
May 5, 2020, 9:58:57 AM5/5/20
to ope...@googlegroups.com

Hi John

Glad to hear it.

Could you please update the Wiki here?

https://github.com/openpnp/openpnp/wiki/Scripting#scripting-event-list

and in the three sections here?

https://github.com/openpnp/openpnp/wiki/Scripting#camerabeforesettle

I guess the Wiki should now tell users not to use Camera.BeforeCapture and Camera.AfterCapture for lighting anymore and warn them the Camera.BeforeCapture is not guaranteed to be run before the captured frame is physically taken by the camera (due to buffering).

I'm in the middle of the axis/motion rework and would greatly appreciate if you could do that. The next guy setting up lights will thank you :-)

_Mark

--
You received this message because you are subscribed to the Google Groups "OpenPnP" group.
To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.

John deGlavina

unread,
May 6, 2020, 9:30:16 AM5/6/20
to OpenPnP
Sure! Done!
To unsubscribe from this group and stop receiving emails from it, send an email to ope...@googlegroups.com.

ma...@makr.zone

unread,
May 6, 2020, 2:19:52 PM5/6/20
to ope...@googlegroups.com

Cool thanks! :)

To unsubscribe from this group and stop receiving emails from it, send an email to openpnp+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/openpnp/3d804f31-3afb-4ba4-81e8-f5e934491ed8%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages