• GenIcam标准(五)


    2810Enumeration, EnumEntry

    Enumeration节点把一个名称(name)映射到一个索引值(index value),并实现Ienumeration接口。Enumeration节点拥有一系列EnumEntries,每一个都表现为可能的{name, index}对。Enumeration节点从Node节点继承元素和属性。另外,它要么有一个表现当前索引值的<Value> ,要么有一个连接到IInteger节点的<pValue>元素。

    下面的例子是用Enumeration来描述相机的ColorCode。如果ColorCodeReg被设定为1,则相机就是Mono16。

    <Enumeration Name="ColorCode">

    <EnumEntry Name="Mono8">

    <Value>0</Value>

    </EnumEntry>

    <EnumEntry Name="Mono16">

    <Value>1</Value>

    </EnumEntry>

    <EnumEntry Name="YUV422">

    <Value>3</Value>

    </EnumEntry>

    <pValue>ColorCodeReg</pValue>

    </Enumeration>

    <IntReg Name="ColorCodeReg">

    <Address>0x1234</Address>

    <Length>1</Length>

    <AccessMode>RW</AccessMode>

    <pPort>Device</pPort>

    <Sign>Unsigned</Sign>

    <Endianess>BigEndian</Endianess>

    </IntReg>

    经常发生的情况是,枚举值列表中的某些值暂时不可用,因而不应该显示给用户。为用GenICam来描述这种情况,你可以用EnumEntry子节点中的<pIsImplemented>和<pIsAvailable>元素,就像你可以用其它任何节点一样。

    通常,实现程序会预处理相机描述文件,并会为每个EnumEntry创建一个独立的节点,节点的Name是“EnumerationName_EnumEntryName”。在Enumeration节点中放入一个<pEnumEntry>元素以代替EnumEntry本身。在新创建的EnumEntry节点内,原来的EnumEntry名称被复制到<Symbolic>元素。枚举入口点所代表的索引值被复制到EnumEntry的<Value>元素。

    Enumeration节点也可以有一个<pSelected>元素。参见2.8.4。

    2811StringReg

    字符串是一个(可能是以NULL结尾的)ASCII字符串,存放在相机地址空间的某处,字符串通过一个Istring接口来操作。下面的例子显示了用一个StringReg节点来取得相机型号名的方法。我们假定ModelName最多可以有128个字节,包括结尾的空字符。

    <StringReg Name="ModelName">

    <Address>0x1234</Address>

    <Length>128</Length>

    <AccessMode>RO</AccessMode>

    <pPort>Device</pPort>

    </StringReg>

    你可以通过Istring来取得并设置一个字符串。

    2812SwissKnife, IntSwissKnife, Converter, and IntConverter

    为在GenICam中进行数学运算,我们引入了两个节点,SwissKnife节点用来处理浮点数,IntSwissKnife节点用来处理整数。两个节点有相同的语法。

    下面的例子显示了得到两个数字计算结果的方法。XtimesY节点引出一个IInteger接口,通过这个接口可以读出504 (=12*42):

    <IntSwissKnife Name="XTimesY">

    <pVariable Name="X">XValue</pVariable>

    <pVariable Name="Y">YValue</pVariable>

    <Formula>X*Y</Formula>

    </IntSwissKnife>

    <Integer Name="XValue">

    <Value>42</Value>

    </Integer>

    <Integer Name="YValue">

    <Value>12</Value>

    </Integer>

    <Formula>元素包含一个数学公式,公式指向由<pVariable>元素定义的变量,<pVariable>元素指向一个IInteger节点,并拥有一个定义了公式中变量名的Name属性。变量名必须是大写的。

    参考实现中使用的瑞士军刀功能相当强大。不过,为简化那些想写自己实现的人的工作,标准仅允许有限的一组数学操作。标准支持下面的操作:

    ( )                  括号

    + - * /            加减乘除

    %                  取模

    **                  乘方

    & | ^ ~         按位与 / 或 / 异或 / 非

    <> = > < <= >=     逻辑关系 不等于 / 等于 / 大于 / 小于 / 小于等于 / 大于等于

    && ||           逻辑与 / 或

    << >>            按位左移,按位右移

    条件表达式:

    <条件> ? <真操作.> : <假操作>

    函数:

    SGN, NEG,

    仅对SwissKnife提供的函数,不对IntSwissKnife提供:

    ATAN, COS, SIN, TAN, ABS, EXP, LN, LG, SQRT,

    TRUNC, FLOOR, CEIL, ROUND( x, precision ),

    ASIN, ACOS, SGN, NEG, E, PI

    当把公式嵌入XML文件的时候,又引发了新的问题:不能直接使用<,>和&字符,因为它们是XML语法的一部分。关于这个问题有两个可能的解决方案。

    第一,你可以像下面这样替换这些字符:

    <     变成       &lt; (lt = less than)

    >     变成       gt;   (gt = greater than)

    &    变成       &amp;   (amp = ampersand)

    结果,公式 (x>0) && (x<10) 变成

    <formula>(x &gt; 0) &amp;&amp; (x &lt; 10)</formula>

    第二,你可以把整个公式声明成非XML文本,方法是把它们用<![CDATA[ 和 ]]>括起来。这样的话公式就变成了:

    <formula><![CDATA[ (x>0) && (x<10) ]]>/formula>

    与只读的SwissKnife不同,Converter可以双向工作。它实现一个Ifloat接口,这一点有点像SwissKnife,不过它还另有一个<pValue>元素,这个元素可以指向一个IInteger或Ifloat接口。它有两个公式:<FormulaFrom>描述从int生成float的方法;<FormulaTo>描述从float生成int的方法。<Slope>入口表示这个公式是否是单调Increasing或Decreasing,或者是Varying(这种情况下,使用整个数字范围),或者slope是Automatic方式决定的。

    下面的例子显示了一个Converter计算绝对快门值(一个浮点数)的方法,做法是把一个原始快门值(一个整数)和一个时间基数(另一个整数)相乘。

    <Converter Name="ShutterAbs">

    <pVariable Name="TIMEBASE">TimeBase</pVariable>

    <FormulaTo> FROM / TIMEBASE </FormulaTo>

    <FormulaFrom> TO * TIMEBASE </FormulaFrom>

    <pValue>ShutterRaw</pValue>

    <Slope>Increasing</Slope>

    </Converter>

    <Integer Name="ShutterRaw">

    <Value>2</Value>

    </Integer>

    <Integer Name="TimeBase">

    <Value>10</Value>

    </Integer>

    IntConverter很像Converter,只不过它实现一个IInteger接口。

    2813ConfRom, TextDesc, and IntKey

    1394相机用的DCAM标准实现一个树形数据结构的配置ROM,它由IEEE 1212标准定义。它在相机上下文中的主要作用是,提供型号名称,制造商名称,所支持的标准版本接口,以及DCAM标准寄存器的基地址。由于IEEE 1212兼容配置ROM的特殊排列,引入了一个特殊的ConfROM节点,以提供对所有这些信息的访问。

    在下面的例子中,我们通过单元ID查找一个描述DCAM兼容相机的单元目录,单元ID由<Unit>元素给出。在这个单元中,加入了三个入口,作为子节点。<IntKey> CommandRegBase元素会转换成一个带IInteger接口的节点,用于读DCAM寄存器的基地址。<TextDesc> VendorName和ModelName元素转换成带Istring接口的节点,用于读相机的制造商和型号名称(脚注:注意,不要求配置ROM中的字符串是以NULL结尾的,参见IEEE 1212),元素中的16进制数值是各自的key值,和入口一起储存在单元目录中。

    <Category Name="Root">

    <pFeature>CommandRegBase</pFeature>

    <pFeature>VendorName</pFeature>

    <pFeature>ModelName</pFeature>

    </Category>

    <ConfRom Name="ConfRom">

    <Unit>0x00A02D</Unit>

    <Address>0x400</Address>

    <pAddress>InitialNodeSpace</pAddress>

    <Length>0x400</Length>

    <pPort>Device</pPort>

    <IntKey Name="CommandRegBase">0x40</IntKey>

    <TextDesc Name="VendorName">0x81</TextDesc>

    <TextDesc Name="ModelName">0x82</TextDesc>

    </ConfRom>

    <Integer Name="InitialNodeSpace">

    <Value>0xFFFFF0000000</Value>

    </Integer>

    注意,ConfROM节点有<Address>,<pAddress>,<IntSwissKnife>,<Length>和<pPort>元素,它们的含义和别的Registers一样(参见2.8.3)。

    典型的实现会为<IntKey>和<TextDesc>元素各自创建节点,区分的方法是通过各自入口的Name属性,一个指向ConfROM节点的<p1212Parser>元素,以及一个带有相应key值的<Key>元素。

    2814DcamLock and SmartFeature

    目前,大多数标准寄存器的构造是固定的,需要提供机制和方法来访问那些没有在标准中定义的自定义属性。GenICam目前支持两种机制。

    DcamLock节点可以得到根据DCAM高级属性机制提供的智能属性的地址,它从Register节点继承元素和属性。在下面的例子中,我们对一个高级DCAM属性解锁,属性的<FeatureID>元素是0x0030533B73C3,其中0x003053是制造商的ID,0x3B73C3是这个制造商所定义的属性ID。<Timeout>元素的值是0,意味着这个属性不会自动解锁。

    <AdvFeatureLock Name="BaslerAdvFeatureLock">

    <FeatureID>0x0030533B73C3</FeatureID>

    <Timeout>0</Timeout>

    <Address>0xfffff2f00000</Address>

    <Length>8</Length>

    <AccessMode>RW</AccessMode>

    <pPort>Device</pPort>

    </AdvFeatureLock>

    如果一个智能属性在<FeatureID>元素中给定了一个GUID,则SmartFeature节点可以得到这个属性的地址。它也从Register节点继承元素和属性。下面的例子中,我们取得一个智能属性的地址,属性的GUID是{5590D58E-1B84-11D8-8447-00105A5BAE55}:

    <SmartFeature Name="TimeStampAdr">

    <FeatureID>5590D58E - 1B84 - 11D8 - 8447 - 00105A5BAE55</FeatureID>

    <Address>0xfffff2f00010</Address>

    <pPort>Device</pPort>

    </SmartFeature>

    2815Port

    Port对象仅仅是个代理,它把读写请求转送给传输层。不过要注意,这个代理有Node的所有特征,例如,它可以是“未实现”,这样就把传输层驱动暂时没有打开的信息告诉了所有从属节点,结果所有的从属属性也自动变成了“未实现”。另一个例子是用户设定加载器的实现。如果把一个用户设定从闪存加载到相机,则节点图内所有的属性都要无效。简单地令Port节点无效就可以实现这一点,用一个连接到ReadUserSet属性节点的<pInvalidator>就可以自动实现Port节点的无效。

    如果传输层有最大数据长度的限制,或者需要特别的对齐方式,例如按quadlet对齐,传输层的实现必须模拟Iport接口,把超出最大长度的请求分成多条请求,给不符合对齐要求的请求补上附加数据。为支持某些处理quadlet的接口,引入了<SwapEndianess>元素:如果它是true,那么在通过Iport接口向GenICam提供数据之前,每个quadlet的字节序都要转换。

    Port从Node节点继承元素和属性。另外,它有一个用来标识缓冲区内大块数据的<ChunkID>元素。这个大块数据可能被映射到一个虚拟端口,这个虚拟端口不提供对真实设备的访问,但是提供对内存中大块数据的访问。

    <Port Name="Device" NameSpace="Standard">

    <ChunkID>4711</ChunkID>

    </Port>

    2816Group element

    <Group>元素可以让一个大的相机描述文件更具可读性。如下所示,这个元素可以把节点封装成很多块:

    <Category Name="Root">

    <pFeature>Analog</pFeature>

    <pFeature>Trigger</pFeature>

    </Category>

    <Group Comment="Analog section">

    <Category Name="Analog">

    <pFeature>Shutter</pFeature>

    <pFeature>Gain</pFeature>

    <pFeature>Offset</pFeature>

    </Category>

    <IntReg Name="Shutter">

    <!-- more elements -->

    </IntReg>

    <IntReg Name="Gain">

    <!-- more elements -->

    </IntReg>

    <IntReg Name="Offset">

    <!-- more elements -->

    </IntReg>

    </Group>

    <Group Comment="Trigger section">

    <!-- more elements -->

    </Group>

    XML编辑器应该可以隐藏一个组的内容,像下面的截屏图一样:

     

    <Group>节点有一个Comment属性,当组被折叠的时候,编辑器会显示这个属性。组可以在任何深度展开。组对相机的功能没有任何影响,当解析相机描述文件的时候,会忽略它们。

  • 相关阅读:
    datanode报错Problem connecting to server
    使用命令查看hdfs的状态
    Access denied for user root. Superuser privilege is requ
    ElasticSearch默认的分页参数 size
    SparkStreaming Kafka 维护offset
    【容错篇】Spark Streaming的还原药水——Checkpoint
    251 Android 线性与相对布局简介
    250 Android Studio使用指南 总结
    249 如何解决项目导入产生的中文乱码问题
    248 gradle更新问题
  • 原文地址:https://www.cnblogs.com/zzdbullet/p/9467056.html
Copyright © 2020-2023  润新知