Providing a shot with data
In the previous example we showed how timing information about one shot can be obtained using the ARM instrumentation provided with this tutorial. This example explains how additional data can be provided for each shot. Since each shot differs from another by the force and angle selected by the user these values will be saved with each shot. The way to do this with ARM are so called "metrics". Roughly spoken, metrics describe a "name=value" pair, where the name is provided during transaction definition (i.e. when the QSimpleArmTran object is instantiated) while the value can be changed each time the transaction is started. The metric content can therefore be unique for each transaction instance.
Source code
Modifications to the previous example are marked. The other source files were not touched:
| lcdrange.h | contains the LCDRange class definition |
| lcdrange.cpp | contains the LCDRange implementation |
| autoshoottimer.h | contains AutoShootTimer class (modified) |
| cannonfield.h | contains the CannonField class definition |
| cannonfield.cpp | contains the CannonField implementation (modified) |
| gameboard.h | contains the GameBoard class definition |
| gameboard.cpp | contains the GameBoard implementation |
| main.cpp | contains MyWidget and main |
Line-by-Line walkthrough
cannonfield.cpp
The difference to this file in the last chapter is the way the
AutoShootTimer is started. Now the
AutoShootTime::start() method is provided with angle
and force.
autoShootTimer->start(5,(int)shootAngle,(int)shootForce);
autoshoottimer.h
The main changes were made in this class. The class has two new attributes
QSimpleArmNumId *angle;
QSimpleArmNumId *force;
|
E x c u r s u s
|
ARM metrics are numbers that can be provided with a transaction instance. Metrics can be used to serve different purposes:
The name of a metric and its specific type have to be bound to an ARM application. There is no limit of how many metrics can be bound to an application but to a specific transaction definition. When a transaction is defined it has to be decided which of the metrics are registered to that transaction definition and a so called slot (a number from 0 to 6) is used as identification for that metric. Later when the transaction is started (the transaction instance is created) the slots can be filled with values. Therefore each transaction instance can serve up to 7 different metrics with a type and name specified during transaction definition. |
These created ARM metric objects are used to store all data
regarding the additional information needed to provide the
"shoot-transaction" with the force and angle value during each
start. These values are named metrics within ARM context, with a
metric type named "numeric id". A numeric id is a metric that does
not change its value while the transaction is executed, therefore
it has only to be provided during start(). Other types
of metrics are "counters" and "gauges". See the ARM standard for
details of metric types.
The two metric objects are allocated in the constructor:
angle = new QSimpleArmNumId("Shot Angle","deg");
force = new QSimpleArmNumId("Shot Force","[N]");
metrics.append(angle);
metrics.append(force);
The name of the metrics is "Shot Angle" and "Shot Force", their
unit is "degree" and "Newton". They are organised in a
QArmMetricList called "metrics". This is necessary since
different methods from QArmTransaction are using the metric
information, first during instantiation and later during
start(). The "shoot-transaction" is defined as a
pointer
QSimpleArmTran *shootTransaction;
since now the shoot-Transaction needs to know that some numeric
ids will be provided during start(). You might ask
why, since this does not directly influence the constructor of this
class. The reason can be found in the ARM standard. The number of
metrics as well as their type has to be provided at the time when
the transaction is registered to the ARM application. This is done
when the class is instantiated. The reason for this is simple:
Performance. It is better to spend some time registering a metric
at the time when the program is initialised (and when classes are
instantiated normally) as if all the data is provided at the time
when the transaction is started. All the data needed to identify a
metric (the name, the unit, the type of data etc.) is therefore
defined when the definition is instantiated
shootTransaction = new QSimpleArmTran("shot airborne",
0,
&metrics);
Here you see again the QArmMetricList that was created
earlier. All the data provided by the metrics (name, unit, type) is
now known to the transaction and there is no need to use that
information when the start() method of this
transaction is called. What is missing yet are the metric values.
These are provided during start():
angle->setValue(_ang);
force->setValue(_force);
shootTransaction->start(&metrics);
First the values are filled and afterwards the list of metrics
is provided to start(). The list is the same that was
provided when the class was instantiated. But now the transaction
is not interested in name or unit of the metric but in its value
provided earlier. It is important that the list of metrics is the
same that was used earlier since the order of metrics is
important.
You will see that the data provided with each metric is copied to each transaction instance by looking at the results of this example.
Compiling
The code can be compiled using the standard Qt qmake mechanism.
Just go into the directory tutorial/t3 and say:
qmake
make
Behaviour
The behaviour is the same as with the former example with one difference: You know more about the situation when the measurement was made. An ARM expert provided with this information will be able to see the learning curve of a user shooting the cannon and trying different values. A tendency for the user might be the result, assuring that the computers performance didn't influence this curve. On the other hand, a computer that is running on its performance limit might influence the users learning curve. Both questions can be answered by analysing the data provided by the ARM instrumentation.
Exercise
No exercises defined yet.