Using behaviour three notation for behaviour description in Capella in comparison with statechart notation

Yes. it’s design

This FuncBlock notation is 2 days old. So not yet )

Let’s look at an example from software engineering.
Take class A and define several functions inside this class. And define main function that implements control flow (business logic of this class) and execute other class’ functions in some sequences.

All of this function when executed also implements some control flow (but more technical one) : analyze input parametes, prepare parameters for external functions, calls external function, analyze results, create objects based on results and so on. I named this actions as functional blocks.
We don’t want to know about them in the main control flow (busines logic). We don’t want to subdivide functions defined in class.

In case of Capella modeling we want to have class functions to be atomic functions in functional decomposition. And used them in statechart\behaviour tree defined for component.

In othere words we don’t mix busines logic with technical logic.

In IT projects there are a lot of “technical” work and logic inside atomic functions. Data are prepared, services are called, mapping between different strutures are made. In our case software implementation was done by several subcontractors. They had not very good understanding of data architecture in our system. We needed to define a lot of mappings for atomic functions:
between input data and called services, services results and atomic function resul and so on.

I’ve created special viewpoint to define these mappings (ComplexValue Viewpoint). Aftre mappings are defined we needed some way to define control\data flow inside atomic functions and “attach” these mappings to blocks of this flow. We did decomposed atomic functions into functional blocks as part of functional decomposition and attached mapping to leaf small functions. I don’t think this is a good aproach as “business logic” mix with “technical logic”.

I think this question can arise.
In Capella there a logical architecture and physical architecture. And someone can advise to
use physical architecture to add “tecnical logic”. And keep logical architecture clean from them.

I should say that FunctionalBlocks are not from physical architecture. We wanted to stay on logical architecture and specify behaviour of atomic functions in more detail.
In physical architecture FunctionalBlocks will not become physical functions.

Functional Blocks can be used on all level of architecture to specify atomic functions in more details but preserving level of abstraction for atomic functions.

Meta model used for functional decomposition is not good for defining internal behaviour of atomic functions. This meta model was not designed for FunctionalBlock level.

On this level one block calculates some variable and some other block use it. We don’t want to define ExhangeItems and pack data into it to “transfer” data to the other block. We want to define simple data exchange typed by data type we are transfering.

It’s normal to pack data into “signatures” and interfaces on the atomic function level. But it’s not good to model data transfer between two blocks of code inside one atomic function.

Term “actions” I use from Behaviour Tree notation. It’s a leaf node of Behaviour Tree. “actions” is a means to call “atomic functions” or “FncBlocks” from BehaviourTree.
If Behaviour Tree is defined for a component then actions reference atomic functions from hierarchical decomposition. If BTree is defined for atomic functions then “actions” reference to FncBlocks.

I’m coming from embedded world, so thinking rather in software components and their interfaces than classes and methods, therefore for me having function as a smallest element of architecture w/o depicting its internal behaviour is perfectly OK. But I understand, that in your case it might be not enough.

Leaf functions on higher architecture layers not necessarily have to be atomic - e.g. you can realize system function by one or more logical functions, which can be realized by one or more physical functions. So if you’re designing your system architecture on all layers it’d make sense to define functional blocks on a lowest layer.

Wondering if activity diagram from SysML wouldn’t be better here were you can have as many levels as you need and also design data flows and control flows simultaneously.

I think that FunctionalBlocks can be used on all levels. I will try to describe my understanding later.

Have spend more than 7 years with Rational Rhapsody (SysML and UML) at the same time with Thales. Was very glad to be able to swithch to Capella. Don’t want to switch back )

Don’t think it’s a good idea to have control flows and data flows on the same diagram.
Diagram becomes overloaded with information of different types.

On the next step I plan to prototype flowchart notation to specify simple control flows inside atomic functions.
They will use functions\FuncBlocks in the same manner as BTrees…
Data flow diagrams for Functional Blocks will be used in conjunctions with flowchart.
I think I will implement data flow on flowchart also but don’t plan to use it. May be in very simple cases.

Let’s look at Capella leaf functions from “call stack” view.
And let’s define 3 levels of functions of different levels. Functions of high level call middle level functions. Functions of middle level call low level functions.

In data flow digram we can show this like this

In functional decomposition functions of all levels will be “atomic” functions
image

This is the correct way of using functional decomposition in Capella.
We can clearly see that Capella helps to define functional interactions but does not define behaviour of functions.

There is the only way to define behaviour of HighLevelFunction is to allocate functions to components and define behaviour using statectart

Let’s allocate HighLevelFunction and MiddleLevelFunctions to HighLevelComponent

And define behaviour of this component on the statechart
In high level state it executes HighLevelFunctions1. In “middle level” states it executes MiddleLevelFunctions

We see from the statechart that MiddleFunction2 and MiddleFunction3 are called only in some condition.

Another way to specify the behaviour of HighLevelFunction is to use Functional scenarios
image

Will continue in next post how to define the same behabiour using FunctionalBlocks and BTree notation.

FncBlocks and BTree helps us to define behaviour of any atomic functions. In the same manner we can define behaviour of high lelevl, middle level, low level atomic functions (see example from previous post). We don’t need to create components to define behaviour of higl level functions and can define behaviour of any atomic fucntions.

If want to specify bahaviour for HighLevelFunction we can add FncBlock behaviour specification that contains

  • Behaviour Tree that define control flow for FncBlocks

  • data flow diagram that defines detailed data flow betwee FncBlocks

  • BTree definition diagram is used to specify control flow and helps to define FncBlocks (leaf actions)
    image

  • FncBlock data flow diagram helps to define in details data flows betwee FncBlocks. It also delegates dataflows to input\output ports of parent function (HighLevelFunction).

I plan to change visual notation for delegate ports.

Dataflow diagram does not show “call results” (return). Every FncBlock can return: SUCCESS, FAILURE or RUNNING. The same result type for all FuncBlocks. Based on this result BTree make decision about next node execution.

The result model created for specifying detailed behaviour of function HighLevelFunction wiil look like this

image
Leaf actions in BTree are involvements of FncBlocks.

When detailed data flows between FunctionBlocks are defined it’s possible to add addition information about behaviour of separate functionBlocks. In many cases behaviour of FncBlocks that call some other function is simple. It takes own input parameter, prepare input parameter for function call. Receive output parameter from called function. And prepare it’s own output parameter.
For such simple FncBlocks it’s possible to use ComplexValues to define data mapping between different parameters
For example in CallMiddleLevelFunction1

  • how in1 value is defined based on in input
  • how out value is defined based on out1

For this puprpose we use ComplexValue Viewpoint to define mappings between different parameters.
I wiil add example of using ComplexValues with FncBlocks in next posts.

Using FncBlocks we was able to specify behaviour of atomic function in detail without decomposing atomic function to small functions like “Call MediumLevelFunction”. It would be incorrect usage of functional decomposition in Capella.

I came to the conclusion that BehaviourTrees for component behaviour description should be used via the “main” function of component. BTree is used widh FncBlocks of main function of component in the same way as for other functions.

The main function of a component is defined as atomic function in functional decomposition.
FncBlocks and BTree are used to specify behaviour of the “main” function of a component.
“Main” function of a component calls only functions allocated to the same component.

In this way behaviours of all levels are defined in functions. It’s possible to define behaviour before defining components. When components are defined all is needed is to allocate functions to components. Their behaviour will be defined already.

As I result I came to the single way of using BTrees. Leaf nodes of BTree can invoke only FncBlocks of the function for which BTree is defined. There is no way to invoke other “atomic” functions in BTree. Calling of other atomic functions is possible only via FncBlocks.

Have dived into Capella meta model. Below are some findings that helps to integrate BTree and FncBlocks with it.

There is three types of Behaviour elements
image

StateMachine, Scenario are generally used.
BehaviourTree should also inherited from AbstractBehaviour.

AbstractActivity is very close to SysML activity. They can include activity nodes, pins, control and object flow, partitions and so on.

It’s possible to use this meta model but not introduce a new one for FuncBlocks.

All Capella functions are inherited from ActivityNode and as a result can be used as part of activities.
All Capella functions can call other Behaviours. They have a reference to called AbstractBehaviour.

FunctionSpecification can be linked to every Capella function and used to specify behaviour of function using activity.

General conclusion from this finding that the need to specify behaviour of atomic functions using some activity diagram is not new. It’s not implemented in Capella UI and is not used in Arcadia. But activity meta model is an integral part of Capella meta model and can be used while extending Capella for behaviour specification of atomic functions.

Below is a class diagram for activity.ecore Capella meta model

All Capella functions are inherited from CallBehaviourAction.
Functional exchange is inherited from ObjectFlow.

It’s not correct. It’s possible to use BTree for component while invoking atomic functions.
In this case there is “main” function. Behaviour is defined for component. BTree call atomic functions allocated to the same component. All is the same as for statemachines defined for components.

Have tried to extend Capella by inheritance. And it’s also working.

Before I was adding new elements to Capella elements using extensibility mechanism.
In this way I was able to add FncBlockRoot to LogicalFunction as a child.

For test purpose have created new type that extends LogicalFunction and FncBlock.
Capella automatically have added menu item to create new element type in LogicalFunction elements.
New element type is creating in the same list ownedFunctions as ordinary child Logical functions and
behaves as LogicalFunction and FncBlocks at the same time

For example it’s possible to allocate this element to component. It’s also possible to add child FncBlocks to element for the purpose to specify it’s behavior.

Below is an example of adding FncBlocks by extensibility and by inheritance.
AtomicFunctions2 - is a LogicalFunctions that was inherited from FncBlock.

image

image

How do you understand the role of ports in case of components, functions, functional blocks and their exchanges?

Component ports and Component exchanges define a set of possible functional exhanges between components. Component ports\exchanges are typed by interfaces that contains full list of operation, events, flows and so on (ExhangeItems).

Funtional ports and Functional Exchanges for atomic Functions are used to modell functional exchanges (calls, events, …). Data in this ports and exhanges can transfer in both direction (input and output parameters). Functional ports\exghanges are allocate to component ports\exhanges.

Data ports and DataExchanges on FncBlocks are used to model data transfers. Data can be transfered only into one direction. Data exchanges clearly show this direction. Data ports and data exchanges are allocated to functional ports and functional exchanges.