Javascript QtQuick Example

This guide shows an Javascript version of the previously shown C++ based implementation of the Data Processor and the Data Generator. In this tutorial the data generation part is realized with two Javascript Filters and the processing part is realized with a QtQuick Filter - this time we do not log the calcualted values, we plot them in a custom visualization solution. The functional logic of this example is split into the following parts:

Data Generator

Both data generators are based on JavaScript Filters. The first one creates velocity values ranging from 5 to 100, the second Filter creates yaw rate values between 3 and 20.

This is the velocity.js for the Velocity Generator:

  
// velocity data sample generator

var velocity_type = types.createDefinition("velocity")
                    .add("value", "tFloat32")
var output = filter.createOutputPin("velocity", velocity_type)

var velo = 10
var delta = 5

filter.createRunner("generate_velocity").trigger.connect(function(timestamp)
{
    velo += delta
    if(velo < 10 || velo > 95){
        delta *= -1;
    }

    output.write(timestamp, { value: velo })
})

  

This is the yaw_rate.js for the Yaw Rate Generator:

  
// yaw rate data sample generator

var yaw_rate_type = types.createDefinition("yaw_rate")
                    .add("value", "tFloat32")
var output = filter.createOutputPin("yaw_rate", yaw_rate_type)

var yaw = 6
var delta = 3

filter.createRunner("generate_yaw_rate").trigger.connect(function(timestamp)
{
    yaw += delta
    if(yaw < 6 || yaw > 17){
        delta *= -1;
    }

    output.write(timestamp, { value: yaw })
})

  

Display

The Display uses a QtQuick Filter to create three different kinds of displays. It receives velocity and yaw rate data samples and calculates the corresponding kappa values. The resulting kappa values are visualized using QtQuick elements which plot the data in three different charts. Have a look at the comments in the code as well.

This is the display.qml for the Display:

  
import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0
import QtCharts 2.0
import QtDataVisualization 1.2

// this is required for ImageItem
import Adtf 1.0

// you can define any QML component you like
Item
{
    // use the onCompleted handler to setup all aspects of your Filter.
    // here you can use all the functionality available within the plain javascript Filter.
    Component.onCompleted:
    {
        var velocityInput = filter.createInputPin("velocity")
        var yawRateInput = filter.createInputPin("yaw_rate")

        velocityInput.sample.connect(function(velocitySample)
        {
            var yawRateSample = yawRateInput.getLastSample()
            if (yawRateSample)
            {
                var timestamp = velocitySample.timestamp / 1000000000.0; // seconds
                var velocity = velocitySample.data.value;
                var yawRate = yawRateSample.data.value;
                var kappa = yawRate / velocity;

                // Kappa values are multiplied by 10 to improve visualization
                var displayKappa = kappa * 10

                // Update 2D Bar View
                // Clear view on each update to show only current values
                barSeries.clear();
                barSeries.append("Velocity", [velocity]);
                barSeries.append("Yaw rate", [yawRate]);
                barSeries.append("Kappa", [displayKappa]);

                // Update 2D Lines View
                // Lines View visualizes data sequentially
                // -> Always update even if the view is not active (visible)
                veloSeries.append(timestamp, velocity);
                yawSeries.append(timestamp, yawRate);
                kappaSeries.append(timestamp, displayKappa);

                // Update 3D Scatter View
                scatterModel.append({ "xPos": velocity, "yPos": yawRate, "zPos": displayKappa});
            }
        })
    }

    RowLayout{
        anchors.fill: parent
        spacing: 5

        // 2D Bar View element
        // Visible on startup
        ChartView {
            id: barView
            title: "2D Bar View"
            width: 400
            height: 400

            BarSeries {
                id: barSeries
                axisX: BarCategoryAxis { categories: ["Current values" ] }
                axisY: ValueAxis {
                    titleText: "Values"
                    titleVisible: true
                    min: 0
                    max: 100
                }
            }
        }

        // 2D Lines View element
        // Invisible on startup
        // Various LineSeries elements for each sample type
        ChartView {
            id: linesView
            title: "2D Lines View"
            width: 400
            height: 400
            antialiasing: true

            // LineSeries for velocity sample values
            LineSeries {
                id: veloSeries
                name: "Velocity"
                axisX: ValueAxis {
                    titleText: "Timestamp"
                    titleVisible: true
                    min: 0
                    max: 60
                }
                axisY: ValueAxis {
                    titleText: "Values"
                    titleVisible: true
                    min: 0
                    max: 100
                }
            }
            // LineSeries for yaw rate sample values
            LineSeries {
                id: yawSeries
                name: "Yaw rate"
            }
            // LineSeries for kappa sample values
            LineSeries {
                id: kappaSeries
                name: "Kappa"
            }
        }

        // 3D Scatter View element
        // Invisible on startup
        // Uses a model to organize data
        Scatter3D {
            id: scatterView
            width: 400
            height: 400

            // Custom axis elements
            axisX: ValueAxis3D {
                title: "Velocity"
                titleVisible: true
            }
            axisY: ValueAxis3D {
                title: "Yaw rate"
                titleVisible: true
            }
            axisZ: ValueAxis3D {
                title: "Kappa"
                titleVisible: true
            }

            Scatter3DSeries {
                ItemModelScatterDataProxy {
                    itemModel: scatterModel
                    // Mapping model roles to scatter series item coordinates.
                    xPosRole: "xPos"
                    yPosRole: "yPos"
                    zPosRole: "zPos"
                }
            }
        }
        ListModel {
            id: scatterModel
        }
    }
}

  

Project setup

In this step we create a new project.

Graph Editor

We add all three Filters to the default Filter Graph and connect the Filter as you can see in figure "Filter Graph".

  • Velocity Generator as Javascript Filter: set the velocity.js using right-click on the ADTF Component and Open Editor
  • Yaw Rate Generator as Javascript Filter: set the yaw_rate.js using right-click on the ADTF Component and Open Editor
  • Display as QtQuick Filter: set the display.qml using right-click on the ADTF Component and Open Editor
  • Then add a Timer Runner and connect it to both Generators. Finally connect both Generators to the respective InPin of the Display with a Sample Stream between.

    Filter Graph

    System Editor

    Because we make use of Qt Charts and Qt Data Visualization which are both not part of the 3rd party Qt runtime binaries within the ADTF delivery due to license issues we have to copy the required dependencies and need to reference the missing libraries in the section Platform dependencies within the System Editor for running this example.

    A complete Qt installation contains the missing files within its bin folder. Have a look here which version is required and where you can get a full Qt developer package. Afterwards you can copy the missing libraries to your <ADTF_DIR>/3rdparty/qt5 folder, which are:

  • <QT_DIR>/bin/Qt5Charts.dll to <ADTF_DIR>/3rdparty/qt5/Qt5Charts.dll
  • <QT_DIR>/bin/Qt5Chartsd.dll to <ADTF_DIR>/3rdparty/qt5/Qt5Chartsd.dll
  • <QT_DIR>/bin/Qt5DataVisualization.dll to <ADTF_DIR>/3rdparty/qt5/Qt5DataVisualization.dll
  • <QT_DIR>/bin/Qt5DataVisualizationd.dll to <ADTF_DIR>/3rdparty/qt5/Qt5DataVisualizationd.dll
  • And to access within qml script we need to copy as well:

  • <QT_DIR>/qml/Qt5Charts/ to <ADTF_DIR>/3rdparty/qt5/qml/Qt5Charts/
  • <QT_DIR>/qml/Qt5DataVisualization/ to <ADTF_DIR>/3rdparty/qt5/qml/Qt5DataVisualization/
  • Then we have to reference the libraries within our ADTF System. First we add the following two libraries to your <platform>_release:

    Next we add the following two files to your <platform>_debug

    Finally, we can run the session and visualize our data.

    Display

    Where to go next?

    Have a look at the ADTF 2 Support Toolbox to see how to connect ADTF 3 and ADTF 2 Filters.