Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[VSS2] Position-related branches proposal #81

Closed
klotzbenjamin opened this issue Nov 27, 2018 · 126 comments · Fixed by #164
Closed

[VSS2] Position-related branches proposal #81

klotzbenjamin opened this issue Nov 27, 2018 · 126 comments · Fixed by #164

Comments

@klotzbenjamin
Copy link
Contributor

The current VSS contains about 1100 signals in total, but only about 300 if we remove the position-related redundancy. The data model would also benefit from an udate of how positions are described, to make a clearer difference between what branches physically represent (composents, domains) and there position branch (Front, Left, Row1...).

Currently we have for instance
Signal.Chassis.Axle.Row1.Wheel.Left.Tire.Pressure
to describe the tire pressure on the front left tire.
The metadata of this signal, and of its hosting branch is the same as in
Signal.Chassis.Axle.Row1.Wheel.Right.Tire.Pressure, Signal.Chassis.Axle.Row2.Wheel.Left.Tire.Pressure, Signal.Chassis.Axle.Row2.Wheel.Right.Tire.Pressure

In addition, there is no fix rule about position modeling, and in the same example, there is the branch Wheel between 2 position branches.

Proposal
We could dedicate a branch type to positions, and add a dedicated symbol (for instance "-") in a similar way as URI parameters. So for instace the previous example could become:
Signal.Chassis.Axle-Row1.Wheel-Left.Tire.Pressure
Where the branches Chassis and Wheel are parametrized with their position.
Or even
Signal.Chassis.Axle.Wheel.Tire.Pressure-Row1.Left
Where the signal is parametrized with the position.

This could be a way of not only remove redundant concepts, but also allow access on multiple positions at once with a wildcard, as proposed in #48

@danielwilms danielwilms added this to the vss2 milestone Nov 27, 2018
@danielwilms
Copy link
Collaborator

I would see it more as a tooling issue, if I understand it right. How I read it from your description, the main concern is redundancy.

I think redundancy in the representation of the final tree it's not a big issue. IMO we should make sure (e.g. by the compilers), that there is no redundancy in the spec file. Always if something is used in more than one place it has to be done with an include.

In addition, there is no fix rule about position modeling, and in the same example, there is the branch Wheel between 2 position branches.

I see that this is an issue. But it's again more of a tooling/rule question.

So for instace the previous example could become:
Signal.Chassis.Axle-Row1.Wheel-Left.Tire.Pressure

The dash notation is in my opinion not intuitive and I don't understand the issue it tries to solve. The wild-card as in #48 is in the current tree structure possible as well.

@danielwilms
Copy link
Collaborator

what about this one @klotzbenjamin, @UlfBj? Any further opinions? Do you think it's needed? I'd close it otherwise.

@klotzbenjamin
Copy link
Contributor Author

I think redundancy in the representation of the final tree it's not a big issue. IMO we should make sure (e.g. by the compilers), that there is no redundancy in the spec file. Always if something is used in more than one place it has to be done with an include.

I agree. That should be a first step for being a bit more consistent.

The dash notation is in my opinion not intuitive and I don't understand the issue it tries to solve.

It is not so much an issue in regard to the tree structure of VSS. We can always use include to import another file and that would reduce the size of the spec, while containing the same information. But this is not the point here.

The issue is mostly about clarifying what a branch is and how to use them. We have component or domains from a car as branches, as well as position. From a modeling perspective, this results first in an unclear definition of branch, and secondly in the specification of several position branches. E.g. Left in Wheel.Left is not the same as in Seats.Left.

I would suggest clarifying first the type of branch. It could be with a sub-type like "position branch". And secondly I would propose aligning all position branches in term of definition.

@UlfBj
Copy link
Contributor

UlfBj commented Dec 3, 2018 via email

@magnusfeuer
Copy link
Contributor

Late to the party.

I am fairly agnostic on the structural solution we pick, and would be happy to support whatever we agree on.

However, Volvo Cars, BMW, and JLR, and possibly others, now have an interest in VSS, meaning that it is potentially being used in production projects. (I casn obviously not talk about how we do or do not use VSS in JLR's internal development.)

With that in mind, we need to be careful of drastic changes that would impact said projects. At the very least we need to look at versioning releases with the potential pain of back-porting and maintaining new entries to older releases.

I really don't know the best process for handling this, and would appreciate any input from other stakeholders on this.

Any ideas? @UlfBj / @klotzbenjamin

Regards,

/Magnus F.

@klotzbenjamin
Copy link
Contributor Author

Then there would be no position information in the path, but in the respective nodes instead.

This raises another question: do we use VSS as a set of signal classes (with parameters in the node itself), or as the signals static metadata.

So far, VSS is meant to be used to directly map VSS signals to data sources, and for example the Row1.Right.Wheel has a one-to-one mapping with a signal from a car. There is no instance of this signal, simply a mapping.

If we want to make classes of signals instead, I do not see why we would bother with a tree structure at all, and graphs would be more consistent. This is basically the model that result when you reduce the redundancy of VSS concepts, like I did with VSSo.

With that in mind, we need to be careful of drastic changes that would impact said projects. At the very least we need to look at versioning releases with the potential pain of back-porting and maintaining new entries to older releases.

For this matter, we agree to create a "v1" branch so that applications and developers working on the current VSS can at least keep it, and we will try to ensure compatibilities.

@danielwilms
Copy link
Collaborator

With that in mind, we need to be careful of drastic changes that would impact said projects. At the very least we need to look at versioning releases with the potential pain of back-porting and maintaining new entries to older releases.

For this matter, we agree to create a "v1" branch so that applications and developers working on the current VSS can at least keep it, and we will try to ensure compatibilities.

Absolutely agreeing to this. Even though the structure is changing in a potential version 2, the nodes and sub branches should be easily backwards compatible, so that both can profit from newly mapped signals.

@danielwilms
Copy link
Collaborator

danielwilms commented Feb 5, 2019

I had quite some discussions in the last weeks with various people, so that I think I understand better the need of change in the positioning. For the records:

  • Query positioning parameters in RESTful interfaces don't work with having the positioning information
  • In VSSo is the positioning information modeled as attributes
  • Various other projects use Instances (e.g. LwM2M), zoning (e.g. Android), etc.

That being said, I took one proposal and developed it a bit further. Currently, we have:
Signal.Chassis.Axle.Row2.Wheel.Right.Tire.Pressure

I like the proposal #81 (comment) most, when putting the positioning info at the end, but with dot-notation:
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row2.Right

Going forward from there here's a way on how to introduce this in the spec file with the goal of:

  • avoiding duplication
  • avoiding possible hard-coded values.

Let's look at the example above. We have two branches, which contain positioning information, namely Axis and Wheel. I think it would be beneficial to keep the information in the spec file close to the branch definition. Therefore I would like to add a new parameter to a branch:

  • position: Defines the position information of the branch itself. Following the example it would be Row1 and Row2. If differentiation for the branch is needed it could be named pbranch to make it explicit.

I see two types of positioning information:

  • Fixed enumerations: fixed names for positioning like left, right, front, back, etc., which could be modeled accordingly. Looking at the example from above:
- Wheel:
  type: pbranch
  description: something meaningful here
  position: [LEFT, RIGHT]
#include Wheel.vspec Wheel
  • Positioning counting: Simple counting of elements, e.g. row, position, etc. The definition should have an identifier (e.g. Row) and a range, either fix (e.g. [1,2]) or dynamic (e.g. [1, AxleCount]). Following the example from above:
- Axle:
  type: pbranch
  description: something meaningful here
  position: Row[1,2]
#include Axle.vspec Axle

An adoption of the tooling would then help to create the definitions in every representation, like csv, yaml, etc. to achieve the combination of all branch positions attached to the leaves:
Signal.Chassis.Axle.Wheel.Tire.Pressure
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row1
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row1.LEFT
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row1.RIGHT
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row2
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row2.LEFT
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row2.RIGHT

Final question: What do you guys think? @UlfBj @klotzbenjamin @magnusfeuer @rtroncy

@UlfBj
Copy link
Contributor

UlfBj commented Feb 5, 2019

So the tool would then generate a tree like the following?
image

@tpanagos
Copy link

tpanagos commented Feb 5, 2019

JSON style accessor might look like:

  • Signal.Chassis.Axle[1].Wheel[RIGHT].Tire.Pressure

where array accessors are embedded at the level to which they apply.

This has the advantage of supporting multiple levels of arrays (or maps) in an unambiguous way.

RESTFUL VERSION: Signal/Chassis/Axle/1/Wheel/RIGHT/Tire/Pressure

@danielwilms
Copy link
Collaborator

JSON style accessor might look like:
* Signal.Chassis.Axle[1].Wheel[RIGHT].Tire.Pressure

where array accessors are embedded at the level to which they apply.
This has the advantage of supporting multiple levels of arrays (or maps) in an unambiguous way.

RESTFUL VERSION: Signal/Chassis/Axle/1/Wheel/RIGHT/Tire/Pressure

@tpanagos: The issue isn't so obvious, if you request the pressure for one specific tire. But how would you like to address the pressure of all tires? We had the proposal like:
'RESTFUL VERSION: Signal/Chassis/Axle//Wheel//Tire/Pressure'

But I think this is not so nice. As well 4 requests in this case is not really practical, especially, if you want to get notified, when one value is changing. To get the entire subtree of axle would be as well overkill.

For the entire discussion please check out the minutes.

@danielwilms
Copy link
Collaborator

Hi @UlfBj,

sorry for the delay. I could imagine a tree being generated like this:
screen shot 2019-02-12 at 14 54 41

For the description please check #81 (comment)

@UlfBj
Copy link
Contributor

UlfBj commented Feb 12, 2019

The new tree certainly has an advantage in terms of redundancy elimination. There are however some issues that needs to be sorted out, such as:

  • The Datatype property, and other properties, are no longer always found in the leave nodes. It will add complexity to an server impl, but my guess is it is manageable.
  • What node type will be assigned to the new (purple) nodes? Do the leave nodes contain any metadata?
  • How does the path expression look like that returns the pressure of all LEFT wheels?
    Do not get me wrong, I think this will improve the tree structure, but all details must be clear.

@danielwilms
Copy link
Collaborator

  • The Datatype property, and other properties, are no longer always found in the leave nodes. It will add complexity to an server impl, but my guess is it is manageable.

Leave nodes are either the datatype as before (single node) or a list/structure {"Row1":{"LEFT":,...}}

  • What node type will be assigned to the new (purple) nodes? Do the leave nodes contain any metadata?

Those are basically instances of pressure addressed by the position structure

  • How does the path expression look like that returns the pressure of all LEFT wheels?

This is not possible right now, but wasn't before either. Same question I got of a colleague ;)

Do not get me wrong, I think this will improve the tree structure, but all details must be clear.

Of course, that's why we discuss it here. Happy to get comments so quickly!

@UlfBj
Copy link
Contributor

UlfBj commented Feb 12, 2019

Just to exhaust all possibilities I want to propose one more solution.
The Pressure node is the leaf node, in this case four of them, under the Tire node. Each Pressure node must, due to the pbranch nodes in its path, contain a property called "positionInstance". This property must as its value have one enum instance from the Axle pbranch, and one from the Wheel pbranch, for example "positionInstance : Row1, LEFT".
The path expression "Vehicle.Chassis.Axle.Wheel.Tire.Pressure" would address all four Pressure nodes. To select any specific a query would have to be addded to the path, e.g. "Vehicle.Chassis.Axle.Wheel.Tire.Pressure?positionInstance=LEFT" would return all left wheel pressures, etc.
This would not break the rule with leaf nodes containing Datatype and other metadata. It would also be more flexible in terms of search options (I believe).

@UlfBj
Copy link
Contributor

UlfBj commented Feb 12, 2019

This is not possible right now, but wasn't before either.
I think it was - "Vehicle.Chassis.Axle.*.Wheel.LEFT.Tire.Pressure".

@PeterWinzell
Copy link

How would this translate for subscribe ?

Vehicle.Chassis.Axle.Wheel.Tire.Pressure?positionInstance=LEFT" would return all left wheel pressures, etc.

...

{"action": "subscribe", "path": "Vehicle.Chassis.Axle.Wheel.Tire.Pressure", "positionInstance":"{*,LEFT}, "requestId": ' id '}'

Or how would one express this for subscribe ? It seems that this does complicate both the server implementation and the client

@UlfBj
Copy link
Contributor

UlfBj commented Feb 12, 2019

What makes it different for subscribe compared to other actions?
I cannot see how it complicates it more for the server, or client, than using wildcards for the same thing in the current VSS structure? Possibly the syntactic parsing of the query, but not otherwise.
Strict rules needs to be defined for query syntax.

@PeterWinzell
Copy link

I was referring to the syntactic parsing - it is not as clean as wildcards in my view. One other question is how the positionInstance is defined ? LEFT and RIGHT would not suffice for example for seatbelts , but I guess we could cover this with numbers then ...or how would we make a generic positionInstance ?

@UlfBj
Copy link
Contributor

UlfBj commented Feb 12, 2019

As I have understood Daniels proposal on introducing pbranch nodes, the available enum position values are declared there. So it is just to declare what you need for the specific case, which would then set the scope for what can be found as positionInstance values.
I agree that wildcards syntax is "cleaner", i.e. more simple and thus easier to parse/use. But if we want to eliminate redundancy in vspec and tree, I guess we have to leave it.

@PeterWinzell
Copy link

Ok.

@danielwilms
Copy link
Collaborator

The path expression "Vehicle.Chassis.Axle.Wheel.Tire.Pressure" would address all four Pressure nodes. To select any specific a query would have to be addded to the path, e.g. "Vehicle.Chassis.Axle.Wheel.Tire.Pressure?positionInstance=LEFT" would return all left wheel pressures, etc.
This would not break the rule with leaf nodes containing Datatype and other metadata. It would also be more flexible in terms of search options (I believe).

I thought more about it. I think this can be an implementation detail of the usage of VSS in whatever protocol. GraphQL might have different ways of accessing it, then REST. IMHO, it might be important, that an ID is created for each node, as shown above:

Signal.Chassis.Axle.Wheel.Tire.Pressure
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row1
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row1.LEFT
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row1.RIGHT
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row2
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row2.LEFT
Signal.Chassis.Axle.Wheel.Tire.Pressure.Row2.RIGHT

How it then get's accessed through the protocol is another question then.

@UlfBj
Copy link
Contributor

UlfBj commented Feb 13, 2019

I think we are getting there now:). My thinking has been leaning towards tree implementability, while you have been more on a logical level (maybe).
I agree that it is desirable to be possible to address each node separately, but I think we can get there by introducing the notion of "virtual position nodes", which then are represented in the tree realisation by the data in the "positionInstance" property in the (physical) leaf node (the property name is just a suggestion). It is then up to the server to map the ID/path to the correct node by reading the positionInstance value in leave nodes.
Nothing would stop us from allowing LEFT wheel pressures to then be addressed by "Signal.Chassis.Axle.Wheel.Tire.Pressure.LEFT" if we would like to. The last two path segment are virtual, and their order in the path expression is loosely coupled to the (physical) tree structure (that a tree parser implementation has to deal with).
It would also be a possibility to search for the LEFT wheel pressures using a query, if the above suggestion sounds too "rule breaking".
I think it is important to have a solution that do not have built in search limitations, so one of the two above should at least be supported, in my view.
So to summarize my current view:
In the vspec files positioning is expressed through pbranches, as Daniel has suggested earlier in this thread. The Tools that transforms vspec to other formats then from the pbranch data creates positionInstance properties a number of leaf node instantiations given by the pbranch data.
The server utilizing this tree will then use this positionInstance data when decoding the paths provided to it from clients as discussed above.
I think we now have all in place - redundancy elimination in both vspec and tree realisations, ability to address separate position nodes, including search without asymmetrical limitations.
I am ready to go with this:).

@UlfBj
Copy link
Contributor

UlfBj commented Feb 13, 2019

This is how the implementation of the tree would look like, as I see it from the comment above. The logical representation would be as shown in Daniels figure above, the "Proposal" tree.
image

@PeterWinzell
Copy link

PeterWinzell commented Feb 13, 2019

Ok, in the figure I see two trees. How are Chassis and Axle connected ? If I understand this correctly we are able to express position on vehicle "objects" which would match the actual "instance " of a particular vehicle model. Thus, eliminating redundancy. One concrete example would be a 7 seater SUV compared to a 4 seater sedan. I think it would be good to examplify this new approach...

@danielwilms
Copy link
Collaborator

This is how the implementation of the tree would look like, as I see it from the comment above. The logical representation would be as shown in Daniels figure above, the "Proposal" tree.

This looks good. One possible improvement. How about Tire - Pressure < - instanceOf - "Row1, LEFT"... This would have the advantage, to draw a line between the specification and instantiation. I will draw it tomorrow, when I'm back in the office.

One concrete example would be a 7 seater SUV compared to a 4 seater sedan. I think it would be good to examplify this new approach...

@PeterWinzell Sounds like a good use-case for checking the concept. Will write it down.

@rtroncy
Copy link

rtroncy commented Nov 10, 2019

Hey @UlfBj

To illustrate the actual difference in our proposals, regarding an instance declaration as "instance":["A","B"], let us say that in YAML a branch with nodes C, D, and E are declared, where then mentioned instance declaration is included in D.
The YAML branch then looks (in dot notation):
C.D.E
It will by the Tools expand to:
In your proposal:
C.D.A.E
C.D.B.E
In my proposal:
C.A.E
C.B.E
I hope we agree on what is shown above?

(I'm stripping out the case of "instance":"[1..2]", since there is less controversy for this case I think).
So, yes, we agree to some extent. Let me take a concrete example, the same than before, where ["A","B"] = ["Left","Right"] and where D (the node being instantiated) is Wheel.

  • In @gunnarx's proposal, indeed, we have new nodes appearing so that we get, e.g. C.Wheel.Left.E
  • In @UlfBj's proposal, the node get replaced, so we end-up with C.Left.E
    This means, we forgot that we are talking about a left wheel! One alternative would be to name the instances differently, e.g. ["A","B"] = ["WheelLeft","WheelRight"] but I don't think you have ever proposed this nor that you like it.
    The other alternative you proposed is to introduce a placeholder node, that you named WheelHandedness. Here, we will see a difference in the original YAML declaration.
  • In @gunnarx's proposal, we have the original: C.Wheel.E (and Wheel gets instantiated)
  • In @UlfBj's proposal, we have instead: C.Wheel.WheelHandedness.E (and WheelHandedness gets instantiated/replaced)
    With the instances ["A","B"] = ["Left","Right"] this leads to
    • In @gunnarx's proposal: C.Wheel.Left.E
    • In @UlfBj's proposal: C.Wheel.Left.E

Is my interpretation of you proposals correct?

In the A/B case above there will now be two leaf nodes at the end of the branches (E.A and E.B). As VSS rules say that all "interior" nodes in the tree must be branch nodes, we here break this rule.

Here, I pledge ignorance. Where is this rule stated?

It seems to me that this "instance holder node" type could be defined to anything because "disappears" anyway and gets replaced by the instances?

It does not disappear, its name gets replaced in the instantiation process, as shown in the example above. The branch depth is preserved from YAML branch to Tool output branch.

I understand this design rationale. But then, IMHO, you need to name your instances differently to remind what they are replacing while in @gunnarx's proposal you don't have to. This means you need to provide additional guidelines or best practices on how instances should be named.

It might have been good to do that just for clarity. I hope that everyone can see how names get replicated (and sometimes not) in the end result.

It seems unnecessary to me, because it is exactly the same output, I think this thread is long enough without duplication of larger amounts of text.

I'm on the side of @gunnarx here. For the ones who really try to understand the value of each other's proposal, I can tell you that we much prefer clarity than saving x number of lines in lengthy comments. I appreciate though that this is a matter of style.

@UlfBj
Copy link
Contributor

UlfBj commented Nov 10, 2019

Is my interpretation of you proposals correct?

From my view: Yes.

Here, I pledge ignorance. Where is this rule stated?

Your ignorance may be excused by that there seems not to be a normative statement expressing it.
The only textual attempt to express it that I could find is:
"The leafs contain the actual information as shown in the figure."
However, the existing tree contains well over thousand signals, all of them (to my knowledge) are located as leaves. If this was not the result of an at least unspoken rule, the theory of probability may need to be rewritten. I think you can ask any member of this group about their opinion on the matter, and it would surprise me if they have a different opinion.

This means you need to provide additional guidelines or best practices on how instances should be named.

This is a good point, I agree. It does not strike me as a particularly hard task to resolve. One suggestion from the top of my head could be to specify that the name should be "Placeholder:A/B" where A and B are the names from the instance declaration.

@gunnarx
Copy link
Contributor

gunnarx commented Nov 10, 2019

To illustrate the actual difference in our proposals...
...
I hope we agree on what is shown above?

I think we do. But I really don't have the time to doublecheck if you correctly restated my position again. You can't convince people by repeating the same things until they give up. I already provided an answer to the full example before. Actually, I asked you to not restate the differences once again. Maybe it helped someone else, I don't know, but I really feel they were better described earlier.

we have new nodes appearing

That is your way of writing it. In my opinion the parent is already written in the YAML. And I suppose the instances appear, yes, that's the instantiation process. You did not like my description "disappearing", so I don't like yours where you call them "appearing". Shall we leave it at that?

In the A/B case above there will now be two leaf nodes at the end of the branches (E.A and E.B). As VSS rules say that all "interior" nodes in the tree must be branch nodes, we here break this rule.

I also sort of felt these rules seem fairly arbitrary since we are talking about a major design change to VSS here. I still feel it is better than the alternatives. In my proposal, either the new parent node (Wheel in our example) needs to transformed to a branch once when it is instantiated, or perhaps it does not matter that much?

I think I'm just more focused on the YAML definition (where no rules are broken in my proposal), and on the ability to address the end result. If you want to be formal about it, then sure we can say that the parent becomes a branch in the instance process. It's not that important to me.
Why is it not important. Maybe we can open up this question. In the interest of simplicity, is the meaning of "branch" important in any way or could we even get rid of it? Leaves, they are defined by their more specific type (sensor) anyway?

It does not disappear, its name gets replaced in the instantiation process

Its name disappears, that's for sure. But you feel the node does not disappear. It is all matter of definition for me, so let's leave it.

(on writing guidelines)

This is a good point, I agree. It does not strike me as a particularly hard task to resolve

Is it roughly comparable to writing the following line to resolve the supposed problem with my proposal: "When a node is instantiated in a way that creates new children, a branch is inserted and the instances become its children"
(Now once again, I don't know if it actually is very important - I don't know what the knowledge of something having type branch is actually used for in practice? Can you fill us in?)

My answer to these questions is that I think one should be careful with breaking design rules, to do so at a minimum a strong case argument should be presented.

Oh here we go again... ;) And why do we not have a design rule that we don't put node names in the YAML tree that are never part of the resulting addressing path? The rule that your proposal would violate? OF COURSE you should try to avoid breaking design rules. You should also make sure those rules are there for a reason, and also be willing to compromise between different conflicting choices. I don't see this helping the discussion. It would be enough that you specify what you find to be illogical and then leave it there.

Yes, I think we might need to add such an example to understand the effects.
The effects of this is shown earlier in my comment where your proposal outputs C.D.E.A and C.D.E.B, which my restriction to only allow the declarations in branch nodes avoid.

First, I was talking about the effects in both mine and your proposal. Primarily yours, since we had not seen it (for leaf instances). I was also talking about including it in the full example which we use for the comparison. You correctly described what my proposal would yield, but not how your proposal might address it. That is why I think it is better if we have a real example for this.

which my restriction to only allow the declarations in branch nodes avoid.

I still don't understand because I feel you keep avoiding the question and repeating other details we already know. HOW would you make several instances of a sensor in your proposal, or can you please show on a real example a different way forward? I imagine you propose that the designer needs to create a branch above the sensor in order to enable instantiation on that branch instead of the sensor itself. But it's not helpful that I try to interpret and make things up about your proposal. I will probably get it wrong. You should provide it so that it becomes correct. A real example would help us understand this.

Also I don't know why you ignored my idea that we might deal with if instances (of sensor) are allowed or not after deciding on how the instantiation on branch nodes. Maybe see if we can add it to your proposal. It was really intended as a way to help your proposal, and help find some new compromise ways forward. Otherwise it seems to me that your proposal would fail immediately because of inability to have instances on things like sensors? But there are surely ways around, so why not look at them?

@gunnarx
Copy link
Contributor

gunnarx commented Nov 10, 2019

I understand this design rationale. But then, IMHO, you need to name your instances differently to remind what they are replacing while in @gunnarx's proposal you don't have to. This means you need to provide additional guidelines or best practices on how instances should be named.

I'm not sure exactly how to do that in a good way but how about this then.
I might propose the following possible change to @UlfBj proposal. Call this node by the same name all the time? For example we could require it to be "instances".

Vehicle.Chassis.Axle.Row.Wheel.WheelHandedness:

becomes

Vehicle.Chassis.Axle.Row.Wheel.instances:

or "instance_definition" or whatever.

or some symbol:

Vehicle.Chassis.Axle.Row.Wheel.#
Vehicle.Chassis.Axle.Row.Wheel._

Of course it could be just a guideline to use the same generic name all the time, while the actual rule is that it could be anything.

Since the name "disappears" (sorry, I don't know a better word) anyway we could reconsider all of these options - maybe then think outside the box and consider other formats of defining instances.

I know we are eager to close this, but we should take the time to get it right.

Of course I'm opening this mostly because of how much I dislike the addition of a node name that is not used in the result. This is illogical to me. So I'm wondering if there are compromises. Maybe there is a completely different and better way to write instance definitions.

@rtroncy
Copy link

rtroncy commented Nov 11, 2019

Thanks @gunnarx for proposing a possible convention for naming placeholder node that aim to be instantiated, e.g.

Vehicle.Chassis.Axle.Row.Wheel.instances:

Now, a naive question, that I think is relevant for the 2 proposals on the table: will we necessarily always instantiate those nodes? I mean, what if you want to write something for both wheels? At some point, much earlier in the discussion, we were talking about the use of wildcards, is it related?

@UlfBj
Copy link
Contributor

UlfBj commented Nov 11, 2019

|| HOW would you make several instances of a sensor in your proposal

With the risk of being told to continue repeating, I point to comment #81 (comment)
with a condensed version below.
The YAML branch with "instance":["A", "B"] in D:
C.D.E
expands to two instances of E
C.A.E
C.B.E
The instantiation of D into A and B leads to that all nodes below D also becomes instantiated (in this case E). To make it as clear as possible, C, D, A, B are branch nodes, E is a leaf node.
To make it a real example from the VSS tree:
YAML:
Mirrors.instances.Heating

  • "instance":["Left", "Right"] in instances
    is then expanded to:
    Mirrors.Left.Heating
    Mirrors.Right.Heating

@gunnarx proposal of using a reserved word for nodes in YAML that will be expanded is a good idea, which I already have adopted;)

If we by this now are on the same page, I think we should try to move on.

@rtroncy I do not get your question, please elaborate a bit more.
If jokers are the same as wildcards, I do not think we have discussed it in the VSS spec context, but it is used in W3C VISS, and have been discussed for Gen2, where it to my understanding is not to be used in the explicit address (=URI when HTTP is used), but possibly in a query component appended to the address.

@gunnarx
Copy link
Contributor

gunnarx commented Nov 11, 2019

"instance":["Left", "Right"] in instances

is then expanded to:
Mirrors.Left.Heating
Mirrors.Right.Heating

OK, understood and this is as expected, but it is an example of where leaves (The leaf is "Heating", or earlier in your text "E") gets duplicated because of the branch having instances. My example, as given also before, is rather one where the actual leaf needs instances. Just building on your example here, you might have had two Heating sensors on each mirror. So two on the Left and two on the Right. You cannot instantiate Heating in your proposal, so it will then require the designer to add another branch to achieve it, like this:

Mirrors._
    instances ["Left","Right"]

Mirrors.HeatingSensor._
   instances: ["Primary", "Secondary"]

yielding:

Mirrors.Left.HeatingSensor.Primary
Mirrors.Left.HeatingSensor.Secondary
Mirrors.Right.HeatingSensor.Primary
Mirrors.Right.HeatingSensor.Secondary

It's possible, but I wanted to find consensus with you that this becomes the required behavior.

@gunnarx
Copy link
Contributor

gunnarx commented Nov 11, 2019

Now, a naive question, that I think is relevant for the 2 proposals on the table: will we necessarily always instantiate those nodes?

My understanding is that all combinations will be instantiated (as we saw in the full example).
If we want possibility to only generate instances on some nodes (e.g. let's put tire sensors on only the Left wheels, but not the Right) then I believe we must basically stop this track and consider a format that will allow an a fully flexible object model to be defined. I mean we're stepping towards UML territory then, IMHO. I don't think it is needed or worth it for VSS to do that. Finding a balance between expressiveness, flexibility and simplicity.

I have a slight different thinking when it comes to "generating" nodes but I have just accepted it for the sake of the conversation so far. In my view, a server might never actually print out a list of all combinations, but might just directly implement based on the YAML spec the ability to address each node using the path we have shown and called "generated" result. Do they "exist" as objects. Yes I would suppose so. I just don't put emphasis on the generated one being the official tree (as opposed to the original YAML file including its instances). Maybe they will be printed in a flat list or CSV just for clarity. But I would prefer to never see a YAML file generated to include them - I much prefer there is basically only one YAML file in the system at any time, which defines the database once. Those are probably very minor distinctions, I don't know. Nonetheless, I think listing all the combinations that become "generated" helps our discussion.

I mean, what if you want to write something for both wheels?

Don't understand. We already have examples of instances that end up on both wheels, simply because the wheels have instances. (All branches below the instantiation become duplicated automatically, as seen in the full example).
Do you mean different things on different wheels? Example please.

At some point, much earlier in the discussion, we were talking about the use of wildcards, is it related?

I'd say it is worth discussing. I know the group has from time to time said remove the simple wildcard (I here am talking about W3C VISS/v2/Gen2, so to be strict the protocol discussion is distinct from VSS itself, but still important to keep in mind). So I mean addressing a path like A.B.C.*.E. I've always thought such wildcards are useful to keep, actually.
Might we also apply wildcards in the YAML definition, even? Ideas?
If you meant some other usage of wildcards then, example please.

@UlfBj
Copy link
Contributor

UlfBj commented Nov 11, 2019

I think the example below solves your scenario also?
YAML:
Mirrors.instances.instances.Heating

"instance":["Left", "Right"] in first instances
"instance":["Primary", "Secondary"] in second instances
is then expanded to:
Mirrors.Left.Primary.Heating
Mirrors.Left.Secondary.Heating
Mirrors.Right.Primary.Heating
Mirrors.Right.Secondary.Heating

This example shows that the idea with the reserved word "instances" may need some further development.
"instances1", "instances2", etc maybe?
But maybe not, as the YAML dot notation is invented here, it is not seen in vspec files. So the instance declaration would be close to the node name declaration.

@gunnarx
Copy link
Contributor

gunnarx commented Nov 11, 2019

Mirrors.instances.instances.Heating

What? Yuck. :) So you would write this in the YAML?
The ugliness (and difficulty to understand) makes me opposed to this, to be honest.

"instance":["Left", "Right"] in first instances
"instance":["Primary", "Secondary"] in second instances

Please write out both nodes, what the YAML looks like. Until now I didn't expect ever seeing "instances.instances", so I think the full example is needed (You could edit above).

is then expanded to:
Mirrors.Left.Primary.Heating

Fine. But just like the original plan where instances were pushed to the leaf, this tree does not look like it is mirroring the "real" hierarchy -- would much prefer to have it named Heating.Primary

This example shows that the idea with the reserved word "instances" may need some further development.
"instances1", "instances2", etc maybe?

I still have my own original proposal as choice #1, but regarding the modification of yours I'm much more partial to this alternative actually:

Vehicle.Chassis.Axle.Row.Wheel._

The question on wildcards is interesting too. Perhaps

Vehicle.Chassis.Axle.Row.Wheel.*

even makes sense?

@gunnarx
Copy link
Contributor

gunnarx commented Nov 11, 2019

Also a tip is to use the triple back-tick
```
preformatted text
```
to get formatted text, like this:

preformatted text

or ```a few words``` to get : a few words

Helps to separate code examples from text...

@UlfBj
Copy link
Contributor

UlfBj commented Nov 12, 2019

Please write out both nodes, what the YAML looks like.

Mirror:
   type: branch

instances:
   type: branch
   instances: ["Left", "Right"]

instances:
   type: branch
   instances: ["Primary", "Secondary"]

Heating:
   type: sensor

The question on wildcards is interesting too

I think wildcard is actually a better choice than "instances" as placeholder node name.
Thanks for the formatting tip.

danielwilms added a commit to danielwilms/vehicle_signal_specification that referenced this issue Nov 15, 2019
First attempt on how the tooling could look like
with the positions as instances. Dot notation might
not be the best form. But as discussion item for now
to conclude COVESA#81.
@danielwilms
Copy link
Collaborator

Hi all,
sorry for the longer silence, but I was travelling. Now two PRs:

  1. Changes to the spec
  2. CSV tooling

Unfortunately Github can't do sequences of PRs properly, or at least I don't know how. So please just consider the second commit of the second PR.

@gunnarx
Copy link
Contributor

gunnarx commented Nov 26, 2019

I think wildcard is actually a better choice than "instances" as placeholder node name.

That's great. I think we might then be getting towards an acceptable compromise. I still prefer my proposal but think we can reach a compromise here. My favorite wildcard (until convinced otherwise) if following "your proposal" is then to use underscore, as shown earlier. A.B.C._ :

Please write out both nodes, what the YAML looks like.

  type: branch

instances:
  type: branch
  instances: ["Left", "Right"]

instances:
  type: branch
  instances: ["Primary", "Secondary"]

I don't understand this example. I think we require the full path in the YAML?
I.e. you can write "Mirror.Heating.instances:" but you can't only write "instances:".
If you don't mind, please edit to clarify. If you meant to write the above I would recommend against it. It seems you then use the relative positioning of the node definition in the file which I think is not the YAML way. YAML here defines a set of data items. The first line of each signal is an association from the "word" that ends with colon: to the content below it. The order that such items are defined should not matter. In this case you have redefined the value of the word "instances:" which should not be possible.

I just copied this from some YAML documentation (not the actual spec, it is harder to read) :

A dictionary is represented in a simple key: value form (the colon must be followed by a space):

martin:
   name: Martin D'vloper
   job: Developer
   skill: Elite

... so you can't redefine the value of the key to something else and expect to keep both of them, and also you can't depend on the order they are defined.

@gunnarx
Copy link
Contributor

gunnarx commented Nov 26, 2019

Unfortunately Github can't do sequences of PRs properly, or at least I don't know how.

@danielwilms GitHub will compare your branch used for the PR against the "base branch" the PR is sent to, which in the case of #130 and #131 is GENIVI:master. If your second branch (named second_pr_positioning) included only the tooling commit on top of master then only that would be shown. It however includes both commits - you can see it in the list here

Possibly you created your second branch starting from the first, and then just added the new change.
There are different ways to achieve what you want. I can explain if needed.

@danielwilms
Copy link
Collaborator

Please write out both nodes, what the YAML looks like.
  type: branch

instances:
  type: branch
  instances: ["Left", "Right"]

instances:
  type: branch
  instances: ["Primary", "Secondary"]

If you meant to write the above I would recommend against it.

I agree with @gunnarx. I would see the instances as part of the yaml branch or leaf.

But just like the original plan where instances were pushed to the leaf, this tree does not look like it is mirroring the "real" hierarchy -- would much prefer to have it named Heating.Primary

I would prefer the instances at the end, too. as shown in the csv result of #131. This leads to an understandable and readable base tree with a minimal number of concepts, which have to be understood. Further the path to the leaf is clear. The instances are added after the leaf in the definition. Further instances can change, without effecting the base tree.

I've always thought such wildcards are useful to keep, actually.
Might we also apply wildcards in the YAML definition, even? Ideas?
If you meant some other usage of wildcards then, example please.

In my opinion the definition of how to address the instances with e.g. wildcards shouldn't be part of VSS, but the protocol serving the tree. It might be different in e.g. GraphQL vs REST. I would keep that discussion out of context here.

danielwilms added a commit to danielwilms/vehicle_signal_specification that referenced this issue Feb 11, 2020
First attempt on how the tooling could look like
with the positions as instances. Dot notation might
not be the best form. But as discussion item for now
to conclude COVESA#81.
gunnarx pushed a commit to gunnarx/vehicle_signal_specification that referenced this issue Feb 14, 2020
First attempt on how the tooling could look like
with the positions as instances. Dot notation might
not be the best form. But as discussion item for now
to conclude COVESA#81.
danielwilms added a commit that referenced this issue Feb 16, 2020
First attempt on how the tooling could look like
with the positions as instances. Dot notation might
not be the best form. But as discussion item for now
to conclude #81.
@gunnarx gunnarx closed this as completed Apr 14, 2020
@gunnarx gunnarx reopened this Apr 14, 2020
@magnusfeuer
Copy link
Contributor

All. Do we need to move the instance support, currently only implemented in the CSV generator, into vspec.py to get generic instance support.

If that is the case, are we ok with the current YAML structure and its corresponding CSV output structure that is about to be replicated for all other generated formats, or do we want to change anything?

@gunnarx
Copy link
Contributor

gunnarx commented May 1, 2020

Whatever the result of instantiation and include statements is, it should naturally be same for all generators. I am not convinced that we are all fully agreed yet but the CSV has sort of been the place to evaluate the results. I see no problem in moving the code to a common place even if we discuss a fee more tweaks of the result later.

danielwilms added a commit to danielwilms/vehicle_signal_specification that referenced this issue Jun 17, 2020
danielwilms added a commit that referenced this issue Sep 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Development

Successfully merging a pull request may close this issue.

9 participants