Nameclashes in generated source files

Questions regarding the use of UaModeler

Moderator: uamodeler

Post Reply
JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

Nameclashes in generated source files

Post by JeromeBos »

I've noticed some issues with UaModeler in regard to source code generation. I'm using the ANSI C Server 1.6.0 template.

Name-clashes occur in the generated source files when the model contains 2 nodes that share the same name. The name-clashes occur in at least 2 different parts:
1. The uaprovider_someprovider_identifiers.h header files. UaModeler generates defines that share the same name.
2. The generated uaprovider_someprovider_nodes.c source files. UaModeler generates non-static functions that share the same name.

Is this a bug in UaModeler or the UaModeler-template? If so, can this be fixed? If not, is there a proper way to circumvent these issues?

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re: Nameclashes in generated source files

Post by Support Team »

Hello,

It is allowed to have nodes with the same BrowseName. It is even required that children of instances have the same names than the children that are defined at the type.
It also allowed to have different types or instances with the same name, e.g. you can have some instances located directly in the Objects folder having the name "Test".
However having types or instances with the same does not make sense in most cases. Use cases which are very special are not supported by all templates within the UaModeler.

Please describe the structure of your addressspace. What kind of nodes cause the naming confilics (NodeClass, BrowsePath in the addressspace)?
Best regards
Unified Automation Support Team

JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

Re: Nameclashes in generated source files

Post by JeromeBos »

That's a bit unfortunate. I'm aware that it is allowed to have nodes with the same BrowseName. However UaModeler or the specific template doesn't seem to take this into account. I've temporarily circumvented some issues by renaming #defines and making some functions static. However, I wonder if this is the proper way to handle these issues.

Unfortunately I am not the author of the models. These models are provided to us by another company and we are expected to use them. I'm currently not in a position to say whether these models make sense.

I'll provide some examples. Could you enlighten me?

----------------------------------------
Example #1:

The information model:

Code: Select all

Types
|- ObjectTypes 
|  |- BaseObjectType
|  |  |- SomeCustomType (ParentRef=HasSubtype, NodeClass=ObjectType, TypeDef=FolderType, Namespace=3:aaa)
|  |  |- SomeCustomType (ParentRef=HasSubtype, NodeClass=ObjectType, TypeDef=FolderType, Namespace=4:bbb)
The generated output:
uaprovider_someprovider_identifiers_3.h has a #define SomeProvider_SomeCustomTypeId
uaprovider_someprovider_identifiers_4.h has a #define SomeProvider_SomeCustomTypeId
uaprovider_someprovider_nodes_3.c has a non-static function UaProvider_SomeProvider_AddSomeCustomType()
uaprovider_someprovider_nodes_4.c has a non-static function UaProvider_SomeProvider_AddSomeCustomType()

----------------------------------------
Example #2:

The information model:

Code: Select all

Types
|- DataTypes
|  |- OPC Binary (Unknown node info)
|  |  |- SomeCustomType (ParentRef=HasComponent, NodeClass=ObjectType, TypeDef=DataTypeDictionaryType)
|  |  |  |- NamespaceUri (Unknown node info)
|  |  |- SomeCustomType (ParentRef=HasComponent, NodeClass=ObjectType, TypeDef=DataTypeDictionaryType)
|  |  |  |- NamespaceUri (Unknown node info)
The generated output:
uaprovider_someprovider_identifiers_x.h has
2 #defines SomeProvider_Types_OPCBinarySchema_TypeSystem_SomeCustomType
2 #defines SomeProvider_Types_OPCBinarySchema_TypeSystem_SomeCustomType_NamespaceUri
2 #defines SomeProvider_Types_XmlSchema_TypeSystem_SomeCustomType
2 #defines SomeProvider_Types_XmlSchema_TypeSystem_SomeCustomType_NamespaceUri

----------------------------------------
Example #3:

The information model:

Code: Select all

Types
|- ObjectTypes
|  |- BaseObjectType
|  |  |- TopologyElementType (ParentRef=HasSubType, NodeClass=ObjectType)
|  |  |  |- DeviceType (ParentRef=HasSubType, NodeClass=ObjectType, IsAbstract = true)
|  |  |  |  |- SomeCustomProperty (ParentRef=HasProperty, NodeClass=Variable, TypeDef=PropertyType, NamespaceIndex 3)
|  |  |  |  |- SomeCustomProperty (ParentRef=HasProperty, NodeClass=Variable, TypeDef=PropertyType, NamespaceIndex 4)
|  |  |  |  |- DeviceImplementation (ParentRef=HasSubtype, NodeClass=ObjectType)
So far there is no problem. The node identifiers are generated in place (in UaProvider_SomeProvider_CreateAddressSpaceX)

However, when I create an Object Instance of DeviceImplementation another name-clash occurs.

The information model:

Code: Select all

Objects
|- DeviceSet
|  |- MyDevice (ParentRef=Organizes, NodeClass=Object, TypeDef=DeviceImplementation)
|  |  |- SomeCustomProperty (ParentRef=HasProperty, NodeClass=Variable, TypeDef=PropertyType)
|  |  |- SomeCustomProperty (ParentRef=HasProperty, NodeClass=Variable, TypeDef=PropertyType)
The generated output:
uaprovider_someprovider_identifiers_x.h has 2 #defines SomeProvider_Objects_MyDevice_SomeCustomProperty

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re: Nameclashes in generated source files

Post by Support Team »

Hello,

Using the same name part of a BrowseName for different types or different children of the same type is supported by UaModeler but not by all template sets for all SDKs.
There are only two workarounds which are not easy to handle.
1. Modify the generated code
2. Modify the symbolic names of the nodes that cause the naming conflicts. The symbolic name of a node is used for code generatation only.
Best regards
Unified Automation Support Team

JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

Re: Nameclashes in generated source files

Post by JeromeBos »

Thanks for the clarification.

JeromeBos
Sr. Member
Sr. Member
Posts: 14
Joined: 09 May 2016, 15:31

Re: Nameclashes in generated source files

Post by JeromeBos »

The second option is not always viable and therefore isn't a practical workaround.

For example. My model has the following Type structure:

Code: Select all

Types
|- SomeParentType
|  |- CustomAddInType (NamespaceIndex=3)
|  |  |- CustomMethod (Reference=HasComponent, ModellingRule=Mandatory, NamespaceIndex=3)
|
|_ AnotherParentType
|  |- CustomType (NamespaceIndex=3)
|  |  |- CustomAddIn (Reference=HasComponent, TypeDef=CustomAddInType, ModellingRule=Mandatory, NamespaceIndex=3)
|  |  |  |- CustomMethod (Reference=HasComponent, NamespaceIndex=3)
Now I add an Instance to Objects:

Code: Select all

Objects
|- CustomObject (TypeDef=CustomType, NamespaceIndex=6)
|  |- CustomAddIn (TypeDef=CustomAddIn, NamespaceIndex=6) <-- can't change symbolic name within UaModeler
|  |  |- CustomMethod (NamespaceIndex=6) <-- can't change symoblic name within UaModeler
Unfortunately it is not possible to change the symbolic names of the either the CustomAddIn or the the CustomMethod. UaModeler still generates 2 methods named UaProvider_SomeProvider_Call_CustomAddIn_CustomMethod() in uaprovider_someprovider_call.c.

----------

I've noticed some more issues in regard to source code generation. UaModeler doesn't take multiple models into account when generating code. I'll provide an example:

The project overview looks like this:

Code: Select all

Poss
|- Models
|  |- Opc.Ua.NodeSet2.ua
|  |- Opc.Ua.Di.NodeSet2.ua
|  |- custom_model1.ua
|  |- custom_model2.ua
|  |- custom_model3.ua
The information models looks like this:

Code: Select all

CustomType (NamespaceIndex=2)
|- CustomMethod1 (NamespaceIndex=3)
|- CustomMethod2 (NamespaceIndex=4)
UaModeler generates uaprovider_someprovider_customtype_methods.h and uaprovider_someprovider_customtype_methods.c again for each model, basically overwriting the previously generated code.
This is problematic, because users have to let UaModeler generate the code model by model. Afterwards they would have to manually merge the files together.

----------

Some input-arguments and output-arguments of generated functions don't have a type declaration.


The Type structure:

Code: Select all

Types
|- DataTypes
|  |- BaseDataType
|  |  |- Enumeration
|  |  |  |- CustomDataType
|  |  |  |- CustomResultType
|
|- ObjectTypes
|  |- BaseObjectType
|  |  |- CustomType
|  |  |  |- CustomMethod
CustomMethod children:

Code: Select all

Method
|- InputArguments
|  |- ArgNr.0 (Name=CustomArgument1,DataType=String)
|  |- ArgNr.1 (Name=CustomArgument2,DataType=CustomDataType)
|- OutputArguments
|  |- ArgNr.0 (Name=Result,DataType=CustomResultType)
UaModeler generates the following code, but it lacks the type declaration for custom datatypes:

Code: Select all

UaProvider_SomeProvider_CustomType_CustomMethod(
    /* in  */ OpcUa_String *a_pCustomArgument1,
    /* in  */ a_CustomArgument2,
    /* out */ a_Result)
{
    ...
}
Something like this should be generated:

Code: Select all

UaProvider_SomeProvider_CustomType_CustomMethod(
    /* in  */ OpcUa_String *a_pCustomArgument1,
    /* in  */ CustomDataType a_CustomArgument2,
    /* out */ CustomResultType a_Result)
{
    ...
}
----------

Is there any chance these issues may be fixed?

User avatar
Support Team
Hero Member
Hero Member
Posts: 3068
Joined: 18 Mar 2011, 15:09

Re: Nameclashes in generated source files

Post by Support Team »

Hello,

At the moment different types with the same name are not supported. This feature is not at the agenda for the next releases.
In this version of the templates you have to select all models for generating that are used by another model. In your case: model 2 uses a DataType that is defined in model 1, so you have to select model 1 and model 2.
Best regards
Unified Automation Support Team

Post Reply