areaDetector / ADGenICam

areaDetector base class for GenICam cameras.
https://areadetector.github.io/master/ADGenICam/ADGenICam.html
7 stars 16 forks source link

Should GainRaw be GCFeatureTypeDouble? #23

Closed mpdunning closed 2 years ago

mpdunning commented 2 years ago

Mark, thanks for adding support for GainRaw in R1-8. This was exactly what I needed to support our old cameras.

But I found that it didn't quite work for our cameras, as the GenICam feature datatype for this parameter appears to be a float.
Here is one example: $ bin/arv-tool-0.4 -n "Allied Vision Technologies-50-0503321242" features | grep -i gain Category: 'Gain' Enumeration: 'GainSelector' Float: 'GainRaw' ...

This causes a failed type conversion and the driver to print the following error messages: 2021/08/09 13:37:41.583 VimbaFeature::VimbaFeature error input feature type=0 != Vimba feature type=3 for featurename=GainRaw 2021/08/09 13:37:41.583 VimbaFeature:readInteger: ERROR calling GetValue error=-10 As a result the gain can't be set or read correctly.

If I change the feature datatype to a double it fixes the problem:

$ git diff GenICamApp/src/ADGenICam.cpp
diff --git a/GenICamApp/src/ADGenICam.cpp b/GenICamApp/src/ADGenICam.cpp
index 073b03f..91a1a86 100755
--- a/GenICamApp/src/ADGenICam.cpp
+++ b/GenICamApp/src/ADGenICam.cpp
@@ -511,7 +511,7 @@ asynStatus ADGenICam::addADDriverFeatures()

     // Make a single parameter that maps to either Gain, GainRaw, or GainRawChannelA
     features = {{"Gain",            GCFeatureTypeDouble},
-                {"GainRaw",         GCFeatureTypeInteger},
+                {"GainRaw",         GCFeatureTypeDouble},
                 {"GainRawChannelA", GCFeatureTypeInteger}};
     createMultiFeature(ADGainString, asynParamFloat64, ADGain, features);

So are there cameras out there that actually use an integer type for GainRaw? I found three cameras of ours that are old enough to use GainRaw and they are all floats. They are all Manta G033B cameras with FW versions 00.01.42.00 or 00.01.44.00.

I can submit a PR if you agree that this change makes sense. If different cameras use different datatypes for this parameter, how do we deal with this?

Thanks, Mike Dunning SLAC

MarkRivers commented 2 years ago

So are there cameras out there that actually use an integer type for GainRaw?

Yes. The older cameras from Allied Vision GainRaw is an integer, which is why I did all that work in R1-8.

corvette:~>arv-tool-0.8 -n "Allied Vision Technologies-GC1380H (02-2142A)-02-2142A-06110" features | grep -i gain
        Category    : 'GainControl'
            Enumeration : 'GainSelector'
                  * GainRaw
                  * GainAuto
            Integer     : 'GainRaw'

If different cameras use different datatypes for this parameter, how do we deal with this?

The code needs to be more complex and determine if GainRaw is an Integer or float GenICam parameter. I have not looked closely enough to see how that can be done.

Mark

MarkRivers commented 2 years ago

@mpdunning I just looked at the firmware release notes https://cdn.alliedvision.com/fileadmin/content/documents/products/software/firmware/Allied_Vision_GigE_Firmware_Release_Notes_32702.pdf

It says:

FW 01.44.04
Release date: 2012-Feb-13
Supported models: Manta G-031, G-032, G-033, G-046, G-095, G-125, G-145, G-145-30fps, G-146,
G-201, G-201-30fps, G-504
Resolved issues
• TimestampValue between first and second frame was not correct
• Delay between first and second image in external triggered acquisition
• Influence of ExposureValue in ExposureMode = External
Other
• Feature renamed: BlackLevelValue to BlackLevel according to GenICam SFNC version 1.5
• Feature renamed: GainRaw to Gain according to GenICam SFNC version 1.5

So back in 2012 they were renaming GainRaw to Gain to be GenICam compliant on the Manta G-033. It seems strange that your newer firmware from 2016 on the Manta G033B would not have the new Gain feature. It may be worth contacting their tech support to ask that.

MarkRivers commented 2 years ago

I just searched the template files in ADGenICam for output records with _GainRaw. These are the occurrences:

corvette:areaDetector/ADGenICam/db>grep -H _GainRaw\" * | grep "OUT,"
AVT_GC1380CH.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_GC1380H.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_GC3300C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_GE1050C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_GT1380.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_GT1380C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_GT2450CB.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Mako_G125B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Mako_G158C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Mako_G234B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Mako_G234C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Mako_G507B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Manta_G235C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Manta_G507B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Manta_G507C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Manta_G895B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Prosilica_GC655C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
AVT_Prosilica_GT5120.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
Basler-acA1300-30gm.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
Basler-acA2000-50gmNIR.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
Basler-acA2040-35gm.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
Basler-acA2440-20gm.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
Basler-scA1300-32gm.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")
Basler_piA640_210gm.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_I_GainRaw")

Note that in all cases there is an _I, so these are all integer features.

This is the list of all cameras that contain output records with D_Gain.

corvette:areaDetector/ADGenICam/db>grep -H _D_Gain\" * | grep "OUT,"
AVT_GC3300C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_GT1380.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_GT1380C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_GT2450CB.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Mako_G030B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Mako_G125B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Mako_G158C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Mako_G234B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Mako_G234C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Mako_G507B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G125B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G146C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G235B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G235C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G507B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G507C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G609B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Manta_G895B.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
AVT_Prosilica_GT5120.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
FLIR_BFLY_PGE_13H2M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
FLIR_BFS_31S4M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
FLIR_BFS_70S7M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
FLIR_FL3_U3_13S2C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
FLIR_ORX_10G_51S5M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_BFS_PGE_04S2M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_BFS_U3_51S5M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_BlackflyS_13Y3M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_BlackflyS_16S2M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_BlackflyS_50S5C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_Blackfly_20E4C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_Blackfly_50S5C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_GS3_PGE_23S6C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_GS3_U3_23S6M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_GS3_U3_51S5C.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_GS3_U3_51S5M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
PGR_US3_51S5M.template:  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")

The only cameras we need to worry about are those that have GainRaw and do NOT have Gain. That includes the GC1380CH, GC1380H and a few others. I wonder if the GC1380CH was updated to the latest firmware if it would then support Gain?

Note that all of the Manta cameras in this module have GainRaw, but they also have Gain, so GainRaw does not need to be used. It seems strange that your Manta cameras have GainRaw as a double and not Gain. I wonder if that is fixed in more recent firmware?

MarkRivers commented 2 years ago

According to the GenICam 1.0 spec GainRaw is an int. https://www.emva.org/wp-content/uploads/GenICam_v2_0_Update.pdf

 v1.0 had multiple feature names
were the committee could not agree
on one type, e.g. GainRaw (Int) and
GainAbs (Float)

So it seems strange that GainRaw is not an int on your camera, since that seems to violate the standard. Is it possible arv-tool-0.4 has a bug and you should try arv-tool-0.8?

mpdunning commented 2 years ago

Thanks for looking at this Mark.

Yes, it seems like there's something funny (or non-GenICam compliant) about the firmware on the older G033B cameras. Unfortunately a firmware upgrade for these is considered too risky because they'd be a nightmare to replace if we bricked one during the upgrade.

I have previously upgraded the firmware on G125B Mantas and GainRaw gets replaced by Gain. I didn't take note of the datatype of GainRaw when I did this though. I'll try to find some older cameras which are different models and see what Gain/GainRaw looks like on these.

I'll also try arv-tool-0.8 as you suggested.

MarkRivers commented 2 years ago

I just tried to update the firmware on my Alliied Vision GC1380CH. It turns out that for my hardware version I am already running the latest firmware, 1.50.01. That means it only supports GainRaw, not Gain. GainRaw is an integer feature.

mpdunning commented 2 years ago

OK, thanks for testing that.

I just tried arv-tool-0.8 and unfortunately I still get a float:

$ arv-tool-0.8 -n "Allied Vision Technologies-Manta_G-033B (E0020012)-50-0503321242" control DeviceFirmwareVersion
DeviceFirmwareVersion = 00.01.44.00 

 $ arv-tool-0.8 -n "Allied Vision Technologies-Manta_G-033B (E0020012)-50-0503321242" features | grep -i gain
        Category    : 'Gain'
            Enumeration : 'GainSelector'
                  * GainRaw
                  * GainAuto
            Float       : 'GainRaw'
            Enumeration : 'GainAuto'
            Category    : 'GainAutoControl'
                Integer     : 'GainAutoTarget'
                Float       : 'GainAutoMin'
                Float       : 'GainAutoMax'
                Integer     : 'GainAutoRate'
                Integer     : 'GainAutoOutliers'
                Integer     : 'GainAutoAdjustTol'

In ADBase.template I replaced the drvUser GAIN parameter with GC_D_GainRaw and this seems to work fine. Maybe it doesn't make sense to patch the driver for non-GC compliant cameras. I'll have to maintain separate ADBase and vimba template files, but that's not a big deal. Do you see any problems with this workaround?

Thanks again for the help.

MarkRivers commented 2 years ago

That seems like a reasonable fix. I still think it is worth asking AVT tech support about why GainRaw is a double on that camera, and if it is changed to an int in newer firmware.

mpdunning commented 2 years ago

On newer firmware GainRaw is replaced by Gain (a float), which seems to agree with the latest GC standard (which doesn't include GainRaw). https://www.emva.org/wp-content/uploads/GenICam_SFNC_v2_6.pdf

arv-tool fails to get the gain parameter on the newer cameras because of some formatting issues, but if I look at the xml file, here is what it shows:

<Float Name="Gain" NameSpace="Standard">
  <Extension>
   <PvDelete/>
  </Extension>
  <ToolTip>Gain value of analog A/D stage. Units are usually in dB.</ToolTip>
  <Description>Gain value of analog A/D stage. Units are usually in dB.</Description>
  <Streamable>Yes</Streamable>
  <pValue>RegGainValueFloat</pValue>
  <pMin>RegGainValueMinFloat</pMin>
  <pMax>RegGainValueMaxFloat</pMax>
 </Float>

This is firmware 00.01.44.04.

Compared to older firmware (00.01.44.00):

<Float Name="GainRaw" NameSpace="Standard">
  <Extension>
   <PvDelete/>
  </Extension>
  <ToolTip>Gain value of analog A/D stage. Units are usually in dB.</ToolTip>
  <Description>Gain value of analog A/D stage. Units are usually in dB.</Description>
  <Streamable>Yes</Streamable>
  <pValue>RegGainValueFloat</pValue>
  <pMin>RegGainValueMinFloat</pMin>
  <pMax>RegGainValueMaxFloat</pMax>
 </Float>
MarkRivers commented 2 years ago

If you use the Python tools in ADGenICam to create the template file from the XML file for the new firmware does the ao Gain record get created correctly?

mpdunning commented 2 years ago

I think so.

Here's what I get for the newer firmware:

record(ao, "$(P)$(R)GC_Gain") {
  field(DTYP, "asynFloat64")
  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_Gain")
  field(PREC, "3")
  field(DISA, "0")
}

And the old firmware:

record(ao, "$(P)$(R)GC_GainRaw") {
  field(DTYP, "asynFloat64")
  field(OUT,  "@asyn($(PORT),$(ADDR=0),$(TIMEOUT=1))GC_D_GainRaw")
  field(PREC, "3")
  field(DISA, "0")
}
MarkRivers commented 2 years ago

OK, so the new firmware should work fine.

mpdunning commented 2 years ago

Thanks a lot Mark. I'll close this after I test both.

mpdunning commented 2 years ago

Tested successfully on latest G033B firmware (00.01.44.04). Thanks Mark. Closing.