The Production Line System models a plant that generates hammers. There is a generator of heads and another one of handles. These pieces are moved by conveyors until they get on a tray from which they are taken by an assembler. This one produces hammers which finally get on a tray and are collected by an user. The addition of observers to the system allows us to monitor some QoS properties of the system.

System Modeling


The metamodel of this system is shown here:

The plant is composed of elements which have a specific position. There are different kinds of machines (head generators, handle generators and assemblers), containers (users and containers with a limited capacity, such as trays and conveyors) and parts (head, handles and hammers). They all have a position in the plant, indicated by a set of coordinates. Generators will produce as many parts as their counter indicates and deposit them in conveyors; conveyors move parts from machines to trays with a speed; and assemblers consume parts from trays to create hammers, which are deposited in conveyors and finally collected by users. Parts can be either defective or not. Machines work according to a production time (pt) that dictates the average number of time units that they take to produce a part. They also have an attribute (defective rate) that shows the percentage of defective parts they produce, which depends on their production time (normally, the faster they work the more defective parts they produce). Trays and conveyors may contain parts up to their capacity.

Now, apart from the metamodel of the system, we add a new one with the observers.

These observers are able to monitor the QoS properties of our system. Let us explain the aim of all of them:

  • TimeBusyOb. This observer monitors the time a machine is working (not idle).
  • TimeStampOb. This observer is associated to a part, i.e., a handle, a head or a hammer. Its ts attribute stores the time at which the generator started producing the part. This information is required for the computation of the cycle time. Attribute oct keeps the optimal cycle time of the part, which is updated while the part moves forward in the system. This attribute will be used for the calculation of the delay.
  • MTBOb. This observer monitors the average time that all machines in the system have been working. For this calculation it uses the number of machines in the system, a value that is stored in attribute machines, and it also uses the attributes of the TimeBusyOb observers of all machines.
  • MCTOb. This observer keeps the mean cycle time of every collected hammer in its mct attribute. To perform this calculation, it adds all cycle times of every collected hammer, stored in the act attribute, and the timestamp of the TimeStampOb observers associated to the hammers.
  • DelayOb. The addition of delays of every collected hammer with respect to their optimal cycle time is stored in its acc attribute. The hammers’ average delay is stored in its delay attribute.
  • ThroughPutOb. This observer keeps the throughput of the system in its th attribute. For the calculation it needs to know the number of collected hammers, stored in the collected attribute.
  • MTBFOb. It keeps the mean time between failures in the system due to defective collected hammers. It keeps the number of defective hammers as well.

We associate every class of the metamodel with a picture. This graphical concrete syntax will be used for the definition of the behavioral rules.


We have designed seven rules to model the behavior of the system, including the rule that initializes the system.

The InitialRule creates the initial model. There is a machine for producing handles and another that produces heads. The production time of both of them is 30 and 40 units of time respectively, and the defective rate is 2%. The assembler also has a production time of 40 units of time and it has a defective rate of 1%. The NAC pattern forbids the triggering of the rule if was already thrown before. We have defined five observers for the whole system (DelayOb, ThroughPutOb, MTBFOb, MTBOb and MTCOb), and three individual Time- BusyOb observers, each one associated to a machine to control the time it is working.

The GenHandle and GenHead rules generate a new handle and head, respectively, every time they are launched. As they are very similar, let us only describe the GenHandle rule. The time it spends when generating a handle depends on its production time attribute (pt). Instead of a fixed time, we use a random value from the interval [ - 3; + 3] to calculate its duration. This is specified using the random(n) function available in e-Motions that returns an integer value between 0 and n. For this rule to be applied, the LHS pattern indicates that the system has to have a HandleGen generator which has to be, in turn, connected to a Conveyor. The LHS pattern has also a condition (see the WITH clause), so the rule will only be applied if the attribute counter of the GenHandle object is greater than 0 and the Conveyor has room for the generated part. In the RHS pattern a new Handle is generated and it acquires the position of the Conveyor connected to the HandleGen machine. For deciding whether the new Handle generated is a defective part or not, we check if a random variable (rdm) is smaller than the defective rate of the generator. If it is, we have a defective Handle, otherwise, we have a normal (nondefective) one. The counter value of the GenHandle is decreased in 1 unit, which models that a new handle has been created. A TimeStampOb observer has been created and it is associated to the Handle, storing in its ts attribute the time at which the HandleGen started to generate the Handle—we use the Clock instance to get the time the system has been working. Its oct attribute stores the time the machine spends in generating this Handle, since it is part of the optimal cycle time of the part. Finally, the tBusy attribute of the TimeBusyOb object is increased in as many units of time as the generator has been working when producing this Handle, stored in the variable prodTime.

The Carry rule specifies how a Part is transported from the beginning of a Conveyor to the end of it. In the LHS pattern of the rule, the Part is related to the Conveyor with the parts reference, indicating that the part is placed at the beginning of it. In the RHS pattern, the relation between both objects is outParts, which indicates that the part is placed at the end of the Conveyor and is ready to be transferred to the Tray connected to it. The time this rule spends, which simulates the time needed to move a part through a conveyor, is the corresponding speed of the conveyor (15 time units in this case). We update the optimal cycle time of the TimeStampOb observer associated to the part which has been transported by adding the time the Conveyor has been transporting it.

Once there is a Part on a Conveyor ready to be transferred to the Tray connected to the end of it, the instantaneous Transfer rule deals with it. The LHS pattern specifies that this Part must be placed in the outParts part of the Conveyor for this rule to be applied. The rule condition forbids the triggering of the rule when the Tray is full of parts, or when there is only one part needed to reach the capacity of the Tray and the parts on it are of the same type of part p. This last condition, together with the restriction of generators to produce a part when their out conveyor is full, prevents the system from deadlocking: if all the parts in the Assembler’s input Tray were of the same type, the Assembler could not assemble anymore and the production line would stop.

The Assemble rule models the behavior of generating a Hammer from one Head and one Handle. We can see in the LHS pattern that the Tray which is connected to the Assembler has to contain a Head and a Handle. The NAC indicates that this rule cannot be triggered if the Assembler is already participating in an action of type Assemble, i.e., if it is already assembling a Hammer. In the RHS pattern we see how the Head, the Handle and their associated observers have been removed and a new Hammer has been created in the position of the Conveyor connected to the assembler. The defective attribute of the new collected Hammer will be true either if one of the assembled parts (or both) was defective or if the random variable (rdm) is smaller than the defective rate of the Assembler. The Hammer has an associated TimeStampOb observer whose ts attribute is the lowest value between the timestamps of the Head and the Handle. Its oct (optimal cycle time) attribute is the lowest oct value of the Head and the Handle plus the time the Assembler has spent in assembling the Hammer, which is specified by the variable prodTime. Analogously to the GenHandle rule, this variable represents the duration of the rule and depends on the production time of the Assembler. It is in the range [a:pt-3; a:pt+3]. Finally, attribute tBusy of the TimeBusyOb observer associated to the Assembler is increased by this variable because it indicates the time that the Assembler has been working.

The Collect rule models the behavior of the system when the User finally collects an assembled Hammer. The User acquires the position of the Hammer and gets associated to it. The time this rule spends is defined by the Manhattan distance between the Hammer and the User plus one, which is stored in the variable collectTime. There is also a NAC in this rule, which forbids users to collect more than one hammer at a time. This is expressed by an action execution that represents the action (Collect) being executed by the same user (u). We also see the presence of four general observers. The collected attribute of the ThroughPutOb observer is increased in one unit as long as the assembled Hammer is not defective, since it has to be properly updated for the calculation of throughput, carried out in other rule. The mean cycle time of every collected Hammer has to be updated every time a new one is collected. This is why the two attributes of the MCTOb observer are updated by this rule. The first one, act, is increased with the cycle time of the new Hammer, which is clk :time-tsOb:ts (here, tsOb:ts is the timestamp of the collected Hammer). Then, the mct attribute is computed by dividing the value of attribute act by the total number of collected Hammers. The delayOb observer is also updated in this rule. This way, we update the acc attribute by adding the delay of the new Hammer. We also update the average delay of every collected Hammer (delay attribute) by dividing the acc value by the total number of collected hammers. The MTBFOb observer is updated in this rule whenever the collected Hammer is a defective one. To do this, we use again a conditional statement to add one unit to the defective attribute if the assembled Hammer is a defective one and to update the MTBF value too.

In the UpdateIdle rule we show how the tIdle attribute of the TimeBusyOb observers is kept updated. This rule simply calculates the time the machine associated to this observer has been idle by subtracting the time the machine has been working from the current time elapse of the system.

Finally, another ongoing rule, UpdateObservers, is used to keep the state of the ThroughPutOb and MTBOb observers updated. The th attribute of the ThroughPutOb observer is calculated by dividing the number of collected hammers, stored by this observer, by the amount of time the system has been working. The MTBOb object keeps the mean time that all the machines of the system have been working and waiting. To obtain these values, we use two OCL expressions that collect all the instances of TimeBusyOb observers (which are associated to machines) present in the system and calculate the addition of their tBusy and tIdle values, respectively. Then, the obtained values are divided by the number of machines of the system. In this way we keep the state of these two observers of the whole system updated all the time (note that the LHS pattern is always present in the model).

Self-adaptive systems

Apart from computing the values of the properties that we want to analyze in the system, observers can also be very useful for defining alternative behaviors of the system, depending on specific threshold levels. For instance, the system can self-adapt under certain conditions, since we are able to search for states of the system in which some attributes of the observers take certain values, or go above or below some limits.

As an example, let us consider the mean cycle time value given by the MCTOb observer. This value computes, every time a new hammer is collected, the mean cycle time of all hammers produced so far, and it directly depends on the production time of the machines (as we saw in the previous section). Let us suppose now that the production time of the machines can be changed during execution time. In fact, it is very common in real world systems, where the working speed of different machines can be adjusted according to certain parameters while the system operates.

Let us consider the two configurations that gave us better results in the previous simulations (those where all the machines had the same production time). The simulation of the configuration on which every machine has a production time of 40” (resp. 30”) resulted in a final mean cycle time of 2’03” (resp. 1’37”). Now, suppose that we want to keep the value of the mean cycle time close to a given optimal value for us (let us say 1’50”) by appropriately swapping the two configurations. Taking this into account, we insert two new rules in the system to self-adapt its configuration. The first rule, DecreasePt, will be fired whenever the current mean cycle time of the system goes above 1’50” and the current production time of the three machines is 40”. This rule will change the production times of every machine to 30” (and consequently their defective rate) with the aim of raising up the mean cycle time. Rule IncreasePt will then be triggered whenever the mean cycle time goes below 1’50” and the production time of the three machines is 30”. It will change the production times of every machine to 40” (and accordingly their defective rate) to decrease the mean cycle time.


We have run some simulatons and have elaborated some graphs using the results.

Figures a and b show, for instance, two charts that display the mean cycle time of the simulations. We can see in both of them how, in general, the mean cycle time of parts grows as time goes by. This is because tray t1 becomes eventually overloaded, and when this occurs the generated parts at that moment increase the mean cycle time. However, in some time intervals the mean cycle time does not vary or even slightly decreases. This is caused by the parts that are produced when the generators re-start their work after stopping to avoid a deadlock, since these new parts will have a smaller mean cycle time than the average.

(a) Production times 40-30-40

(b) Production times 40-30-30

Figure c shows the busy time of the handle generator in the simulation. In this simulation, the production time of the handle generator was smaller than the other machines. Therefore, handles were generated faster than heads and the handle generator had to eventually stop generating handles to avoid the overload of parts in tray t1 and the overload of heads in conveyor c2. In particular, we see that the generator stops for its first time around minute 8 (moment at which the overload happened) and after this moment it continuously restarts and stops the generation of parts while needed, working as expected.

(c) Handles generator busy time 40-30-40

This analysis also indicates further potential points for improvement in the system, such as replacing the current conveyors by faster ones (although probably more expensive—hence another trade-off to consider). Finding the right balance between costs, performance and benefits is not easy, although the kind of analysis presented here can help solving this problem at very early phases of the system design, with precise and objective figures, and also using notations and mechanisms which are quite close to the domain experts.


We can configure eMotions launcher to run the simulation as shown in the next figure. Please note that we do not need to specify an initial model of the system since we have a rule that creates it.


The file contains the project with all files required to try this example: the metamodel definition, the graphical concrete syntax for the metamodel and its corresponding behavioral specifications. To import this project, right click on the navigation view Import...-> General -> Existing Projects into Workspace -> Select archive file and then select the