Week 7 :

Build core-master/x86: meta-ros + agl-demo-platform + YDLIDAR core dependencies support

  • Kindly go through build process of AGL and building for x86 for detailed reference to setup and initialize AGL workspace.

    # After setting up AGL workspace
    
    # Clone the meta-ros layer, skip if already cloned
    $ cd $AGL_TOP/master/external
    $ git clone https://github.com/ros/meta-ros.git
    $ cd meta-ros
    $ git checkout -b dunfell
    
    # Setup build directory
    $ cd $AGL_TOP/master/
    $ source meta-agl/scripts/aglsetup.sh -b core-build-x86-meta-ros-demo agl-demo agl-devel
    $ ln -sf $AGL_TOP/site.conf conf/
    $ ls -alh conf/
          
    # Edit the following conf files :
    
    $ vim conf/local.conf #add the following to the bottom, to save error logs for future debugging
    # local.conf
      INHERIT += "buildhistory"
      BUILDHISTORY_COMMIT = "1"
      IMAGE_INSTALL_append = " packagegroup-ros-world-foxy"
      PACKAGE_EXCLUDE = "psplash"
    
    $ vim conf/bblayers.conf #Replace the following chunk
    # bblayers.conf
      AGL_META_NETWORKING ?= ""
      AGL_META_PYTHON = "${METADIR}/external/meta-openembedded/meta-python"
      AGL_META_ROS = " \
        ${METADIR}/external/meta-ros/meta-ros-common \
        ${METADIR}/external/meta-ros/meta-ros-backports-gatesgarth \
        ${METADIR}/external/meta-ros/meta-ros2 \
        ${METADIR}/external/meta-ros/meta-ros2-foxy \
        "
      AGL_OTHER_DEPENDENCY_LAYERS = " \
        ${AGL_META_NETWORKING} \
        ${AGL_META_PYTHON} \
        ${AGL_META_ROS} \
        "
    
    # Edit launcher and homescreen recipe to include agl-compositor recipe
    
    $ cd $AGL_TOP/master/meta-agl-demo/recipes-demo
    $ vim launcher/launcher_git.bb
    # add this to the bottom
      DEPENDS += 'agl-compositor'
    $ vim homescreen/homescreen_git.bb
    # add this to the bottom
      DEPENDS += 'agl-compositor'
    
    # Build the image
    
    $ cd $AGL_TOP/master/core-build-x86-meta-ros-weston/
    $ source agl-init-build-env #if not sourced
    $ bitbake -p ros-core #build ros-core first, to check all layers are added.
    $ time bitbake agl-demo-platform #wait for the build process to finish.
    

Run core-master/x86: meta-ros + agl-demo-platform + YDLIDAR core dependencies support

  • Kindly use pre-built image agl-demo-core-qemux86-64, if you want to skip the building process.

  • Kindly go through using prebuilt x86 images for detailed reference to setup and initialize AGL workspace.

    # gdrive : https://drive.google.com/drive/folders/1kYX5AnVYgJDGceBEKjdNJ6YeYFLHcYjq?usp=sharing
    
    # Install the dependencies
    $ apt-get install qemu
    $ sudo apt install vinagre
    $ sudo apt install qemu-system-x86
    
    # Copy image and kernel files
    $ cp ~/Downloads/agl-demo-platform-qemux86-64.ext4 ./
    $ cp ~/Downloads/bzImage ./
    $ sync
    
    # Run
    $ vim startup.sh
      # attach YDLIDAR to the host system.
      #-device usb-host,hostbus=1,hostport=4, change accordingly to ydlidar usb port `lsusb -t` 
    
        ( sleep 5 && vinagre --vnc-scale localhost ) > /tmp/vinagre.log 2>&1 &
            qemu-system-x86_64 -device virtio-net-pci,netdev=net0,mac=52:54:00:12:35:02 -netdev user,id=net0,hostfwd=tcp::2222-:22 \
            -drive file=agl-demo-platform-qemux86-64.ext4,if=virtio,format=raw -show-cursor -usb -usbdevice tablet -device virtio-rng-pci \
            -device usb-host,hostbus=1,hostport=4 -vga virtio \
            -vnc :0 -soundhw hda -machine q35 -cpu host -enable-kvm \
            -m 2048 -serial mon:vc -serial mon:stdio -serial null -kernel bzImage \
            -append 'root=/dev/vda rw console=tty0 mem=2048M ip=dhcp oprofile.timer=1 console=ttyS0,115200n8 verbose fstab=no debug psplash=false'
    
    $ sudo ./startup.sh
    
    # Boots up
    qemu-system-x86_64: -usbdevice tablet: '-usbdevice' is deprecated, please use '-device usb-...' instead
    qemu-system-x86_64: warning: host doesn't support requested feature: CPUID.80000001H:ECX.svm [bit 2]
    
  • At this stage, there are still some bugs to be fixed and the demo-image doesn’t boot up sucessfully. In the process to debug and fix these issues. demo-image-error

Setup AGL SDK to develop apps & services

  • Kindly go through setting up AGL SDK for detailed reference to setup and initialize AGL SDK.

  • Download prebuilt sdk x86_64 to help quickstart the service and application development process.

    # agl sdk x86-64 : https://download.automotivelinux.org/AGL/snapshots/master/latest/qemux86-64/deploy/sdk/poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-corei7-64-qemux86-64-toolchain-12.90.0+snapshot.sh
    
    # Create application developmment directory and copy SDK into them
    $ mkdir ~/Documents/agl-app
    $ cp ~/Downloads/poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-corei7-64-qemux86-64-toolchain-12.90.0+snapshot.sh ~/Documents/agl-app/
    $ cd ~/Documents/agl-app
    
    # Install the downloaded SDK
    $ chmod +x poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-corei7-64-qemux86-64-toolchain-12.90.0+snapshot.sh 
    $ mkdir agl-sdk-x86/
    $ ./poky-agl-glibc-x86_64-agl-demo-platform-crosssdk-corei7-64-qemux86-64-toolchain-12.90.0+snapshot.sh 
      # Select target directory for SDK : ~/Documents/agl-app/agl-sdk-x86/
          
      Automotive Grade Linux SDK installer version 12.90.0+snapshot
      =============================================================
      Enter target directory for SDK (default: /opt/agl-sdk/12.90.0+snapshot-corei7-64): ~/Documents/agl-app/agl-sdk-x86
      You are about to install the SDK to "/home/boron/Documents/agl-app/agl-sdk-x86". Proceed [Y/n]? Y
      Extracting SDK................................................................................................................................................done
      Setting it up...done
      SDK has been successfully set up and is ready to be used.
      Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
      . /home/boron/Documents/agl-app/agl-sdk-x86/environment-setup-corei7-64-agl-linux
    
    # Source the SDK environment setup, each time you wish to use the SDK in a new shell session
    $ source ~/Documents/agl-app/agl-sdk-x86/environment-setup-corei7-64-agl-linux
    

Create test application

  • Kindly go through Creating a New Application for detailed reference to on Creating a New Application from scratch.

    # Create new project development directory
    $ cd ~/Documents/agl-app
    $ mkdir newtestapp/
    $ cd newtestapp/
    
    # Source the SDK environment setup
    $ source ~/Documents/agl-app/agl-sdk-x86/environment-setup-corei7-64-agl-linux
    
    # Copy initial CMAKE configuration templates
    $ mkdir -p conf.d/cmake
    $ cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/config.cmake.sample conf.d/cmake/config.cmake
    $ cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/CMakeLists.txt.sample CMakeLists.txt
    
    # Edit CMAKE configuration template
    
    $ vim conf.d/cmake/config.cmake
    
      ###########################################################################
      # Copyright 2021 
      #
      # author: Shankho Boron Ghosh <shankhoghosh123@gmail.com>
      #
      # Licensed under the Apache License, Version 2.0 (the "License");
      # you may not use this file except in compliance with the License.
      # You may obtain a copy of the License at
      #
      #     http://www.apache.org/licenses/LICENSE-2.0
      #
      # Unless required by applicable law or agreed to in writing, software
      # distributed under the License is distributed on an "AS IS" BASIS,
      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      # See the License for the specific language governing permissions and
      # limitations under the License.
      ###########################################################################
    
      # Project Info
      # ------------------
      set(PROJECT_NAME hellocount) #INSERT NEW PROJECT NAME
      set(API_NAME hellocount) #INSERT NEW PROJECT NAME
      set(PROJECT_PRETTY_NAME "getting started with app dev") #INSERT PRETTY NAME
      set(PROJECT_DESCRIPTION "getting started with app dev") #INSERT CONCISE PROJECT DESCRIPTION
      set(PROJECT_URL "https://not-relevant") #INSERT VCS
      set(PROJECT_ICON "icon.png")
      set(PROJECT_AUTHOR "Ghosh, Shankho Boron") #INSERT AUTHOR NAME
      set(PROJECT_AUTHOR_MAIL "shankhoghosh123@gmail.com") #INSERT AUTHOR EMAIL
      set(PROJECT_LICENSE "APL2.0")
      set(PROJECT_LANGUAGES "C")
      set(PROJECT_VERSION "1.0.0") #INSERT PROJECT VERSION
    
      # Which directories inspect to find CMakeLists.txt target files
      # set(PROJECT_SRC_DIR_PATTERN "*")
    
      # Where are stored the project configuration files
      # relative to the root project directory
      set(PROJECT_CMAKE_CONF_DIR "conf.d")
    
      # Compilation Mode (DEBUG, RELEASE, COVERAGE or PROFILING)
      # ----------------------------------
      set(BUILD_TYPE "DEBUG") #SELECT BUILD TYPE
      #set(USE_EFENCE 1)
    
      # Kernel selection if needed. You can choose between a
      # mandatory version to impose a minimal version.
      # Or check Kernel minimal version and just print a Warning
      # about missing features and define a preprocessor variable
      # to be used as preprocessor condition in code to disable
      # incompatibles features. Preprocessor define is named
      # KERNEL_MINIMAL_VERSION_OK.
      #
      # NOTE*** FOR NOW IT CHECKS KERNEL Yocto environment and
      # Yocto SDK Kernel version.
      # -----------------------------------------------
      #set (kernel_mandatory_version 4.8)
      #set (kernel_minimal_version 4.8)
    
      # Compiler selection if needed. Impose a minimal version.
      # -----------------------------------------------
      set (gcc_minimal_version 4.9)
    
      # PKG_CONFIG required packages
      # -----------------------------
      set (PKG_REQUIRED_LIST
        json-c
        afb-daemon
      )
    
      # You can also consider to include libsystemd
      # -----------------------------------
      #list (APPEND PKG_REQUIRED_LIST libsystemd>=222)
    
      # Prefix path where will be installed the files
      # Default: /usr/local (need root permission to write in)
      # ------------------------------------------------------
      #set(INSTALL_PREFIX /opt/AGL CACHE PATH "INSTALL PREFIX PATH")
    
      # Customize link option
      # -----------------------------
      #list(APPEND link_libraries -an-option)
    
      # Compilation options definition
      # Use CMake generator expressions to specify only for a specific language
      # Values are prefilled with default options that is currently used.
      # Either separate options with ";", or each options must be quoted separately
      # DO NOT PUT ALL OPTION QUOTED AT ONCE , COMPILATION COULD FAILED !
      # ----------------------------------------------------------------------------
      #set(COMPILE_OPTIONS
      # -Wall
      # -Wextra
      # -Wconversion
      # -Wno-unused-parameter
      # -Wno-sign-compare
      # -Wno-sign-conversion
      # -Werror=maybe-uninitialized
      # -Werror=implicit-function-declaration
      # -ffunction-sections
      # -fdata-sections
      # -fPIC
      # CACHE STRING "Compilation flags")
      #set(C_COMPILE_OPTIONS "" CACHE STRING "Compilation flags for C language.")
      #set(CXX_COMPILE_OPTIONS "" CACHE STRING "Compilation flags for C++ language.")
      #set(PROFILING_COMPILE_OPTIONS
      # -g
      # -O0
      # -pg
      # -Wp,-U_FORTIFY_SOURCE
      # CACHE STRING "Compilation flags for PROFILING build type.")
      #set(DEBUG_COMPILE_OPTIONS
      # -g
      # -ggdb
      # CACHE STRING "Compilation flags for DEBUG build type.")
      #set(COVERAGE_COMPILE_OPTIONS
      # -g
      # -O0
      # --coverage
      # CACHE STRING "Compilation flags for COVERAGE build type.")
      #set(RELEASE_COMPILE_OPTIONS
      # -O2
      # -pipe
      # -D_FORTIFY_SOURCE=2
      # -fstack-protector-strong
      # -Wformat -Wformat-security
      # -Werror=format-security
      # -feliminate-unused-debug-types
      # -Wl,-O1
      # -Wl,--hash-style=gnu
      # -Wl,--as-needed
      # -fstack-protector-strong
      # -Wl,-z,relro,-z,now
      # CACHE STRING "Compilation flags for RELEASE build type.")
    
      # Location for config.xml.in template file.
      #
      # If you keep them commented then it will build with a default minimal widget
      # template which is very simple and it is highly probable that it will not suit
      # to your app.
      # -----------------------------------------
      #set(WIDGET_ICON "conf.d/wgt/${PROJECT_ICON}" CACHE PATH "Path to the widget icon")
      set(WIDGET_CONFIG_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/conf.d/wgt/config.xml.in" CACHE PATH "Path to widget config file template (config.xml.in)") # UNCOMMENT WIDGET_CONFIG_TEMPLATE
      #set(TEST_WIDGET_CONFIG_TEMPLATE "${CMAKE_CURRENT_SOURCE_DIR}/conf.d/wgt/test-config.xml.in" CACHE PATH "Path to the test widget config file template (test-config.xml.in)")
    
      # Mandatory widget Mimetype specification of the main unit
      # --------------------------------------------------------------------------
      # Choose between :
      #- text/html : HTML application,
      #	content.src designates the home page of the application
      #
      #- application/vnd.agl.native : AGL compatible native,
      #	content.src designates the relative path of the binary.
      #
      # - application/vnd.agl.service: AGL service, content.src is not used.
      #
      #- ***application/x-executable***: Native application,
      #	content.src designates the relative path of the binary.
      #	For such application, only security setup is made.
      #
      set(WIDGET_TYPE application/vnd.agl.service)    # UNCOMMENT WIDGET_TYPE
    
      # Mandatory Widget entry point file of the main unit
      # --------------------------------------------------------------
      # This is the file that will be executed, loaded,
      # at launch time by the application framework.
      #
    
      set(WIDGET_ENTRY_POINT testingboron)    # UNCOMMENT WIDGET_ENTRY_POINT
    
      # Optional dependencies order
      # ---------------------------
      #set(EXTRA_DEPENDENCIES_ORDER)
    
      # Optional Extra global include path
      # -----------------------------------
      #set(EXTRA_INCLUDE_DIRS)
    
      # Optional extra libraries
      # -------------------------
      #set(EXTRA_LINK_LIBRARIES)
    
      # Optional force binding Linking flag
      # ------------------------------------
      # set(BINDINGS_LINK_FLAG LinkOptions )
    
      # Optional force package prefix generation, like widget
      # -----------------------------------------------------
      # set(PKG_PREFIX DestinationPath)
    
      # Optional Application Framework security token
      # and port use for remote debugging.
      #------------------------------------------------------------
      set(AFB_TOKEN   ""     CACHE PATH "Default binder security token")
      set(AFB_REMPORT "1234" CACHE PATH "Default binder listening port")
    
      # Print a helper message when every thing is finished
      # ----------------------------------------------------
      set(CLOSING_MESSAGE "Typical binding launch: cd ${CMAKE_BINARY_DIR}/package \\&\\& afb-daemon --port=${AFB_REMPORT} --workdir=. --ldpaths=lib --roothttp=htdocs  --token=\"${AFB_TOKEN}\" --tracereq=common --verbose")
      set(PACKAGE_MESSAGE "Install widget file using in the target : afm-util install ${PROJECT_NAME}.wgt")
    
      # Optional schema validator about now only XML, LUA and JSON
      # are supported
      #------------------------------------------------------------
      #set(LUA_CHECKER "luac" "-p" CACHE STRING "LUA compiler")
      #set(XML_CHECKER "xmllint" CACHE STRING "XML linter")
      #set(JSON_CHECKER "json_verify" CACHE STRING "JSON linter")
    
      include(CMakeAfbTemplates)
    
    # Copy WGT configuration template
    $ mkdir -p conf.d/wgt
    $ cp ${OECORE_NATIVE_SYSROOT}/usr/share/doc/CMakeAfbTemplates/samples.d/config.xml.in.sample conf.d/wgt/config.xml.in
    
    # Run CMAKE and Generate autobuild
    $ mkdir build/
    $ cd build/
    $ cmake ..
    $ make autobuild
    
    # Create app directory
    $ cd ..
    $ mkdir app/
    $ cd app/
    
    ## This app directory holds the C++, qrc, qml code & CMakeLists.txt
    
    $ vim main.cpp
    
    /*
      * Copyright (C) 2021 The Linux Foundation # INSERT YEAR & ORG
      *               
      *
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
      *
      *      http://www.apache.org/licenses/LICENSE-2.0
      *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      * See the License for the specific language governing permissions and
      * limitations under the License.
      */
    
      #include <QGuiApplication>
      #include <QtCore/QCommandLineParser>
      #include <QtCore/QUrlQuery>
      #include <QtGui/QGuiApplication>
      #include <QtQml/QQmlContext>
      #include <QtQml/QQmlApplicationEngine>
      #include <QtQml/qqml.h>
      #include <QDebug>
    
      int main(int argc, char *argv[])
      {
              QGuiApplication app(argc, argv);
              app.setDesktopFileName("Hellocount");
    
          QQmlApplicationEngine engine;
          QQmlContext *context = engine.rootContext();
    
          QCommandLineParser parser;
          parser.addPositionalArgument("port", app.translate("main", "port for binding"));
          parser.addPositionalArgument("secret", app.translate("main", "secret for binding"));
          parser.addHelpOption();
          parser.addVersionOption();
          parser.process(app);
          QStringList positionalArguments = parser.positionalArguments();
    
          if (positionalArguments.length() == 2) {
        int port = positionalArguments.takeFirst().toInt();
        QString secret = positionalArguments.takeFirst();
    
        QUrl bindingAddress;
        QUrlQuery query;
    
        bindingAddress.setScheme(QStringLiteral("ws"));
        bindingAddress.setHost(QStringLiteral("localhost"));
        bindingAddress.setPort(port);
        bindingAddress.setPath(QStringLiteral("/api"));
    
    
        query.addQueryItem(QStringLiteral("token"), secret);
        bindingAddress.setQuery(query);
        context->setContextProperty(QStringLiteral("bindingAddress"), bindingAddress);
          }
    
          engine.load(QUrl(QStringLiteral("qrc:/Hellocount.qml")));
              return app.exec();
    
      }
    
    $ vim Hellocount.qml
    
      /*
      * Copyright 2021 The Linux Foundation # INSERT YEAR & ORG
      *
      * Licensed under the Apache License, Version 2.0 (the "License");
      * you may not use this file except in compliance with the License.
      * You may obtain a copy of the License at
      *
      *      http://www.apache.org/licenses/LICENSE-2.0
      *
      * Unless required by applicable law or agreed to in writing, software
      * distributed under the License is distributed on an "AS IS" BASIS,
      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      * See the License for the specific language governing permissions and
      * limitations under the License.
      */
    
      import QtQuick 2.6
      import QtQuick.Layouts 1.1
      import QtQuick.Controls 2.0
      import AGL.Demo.Controls 1.0
    
      import QtQuick.Window 2.13
    
      ApplicationWindow {
    
          // ----- Setup
          id: root
          width: Window.width * roles.scale
          height: Window.height * roles.scale
    
          // ----- Childs
          Label {
        id: title
        font.pixelSize: 48
        text: "Hello World Counter"
        anchors.horizontalCenter: parent.horizontalCenter
          }
    
      }
    
    $ vim Hellocount.qrc
    
      <RCC>
          <qresource prefix="/">
              <file>Hellocount.qml</file>
          </qresource>
      </RCC>
    
    $ vim CMakeLists.txt
    
      set(CMAKE_INCLUDE_CURRENT_DIR ON)
      set(CMAKE_AUTOMOC ON)
      set(CMAKE_AUTORCC ON)
      set(CMAKE_CXX_STANDARD 14)
      set(CMAKE_CXX_STANDARD_REQUIRED ON)
      set(OE_QMAKE_PATH_EXTERNAL_HOST_BINS $ENV{OE_QMAKE_PATH_HOST_BINS})
    
      find_package(Qt5 COMPONENTS Core Gui QuickControls2 QuickWidgets WebSockets REQUIRED)
    
      PROJECT_TARGET_ADD(hellocount)
    
      add_executable(hellocount
          "main.cpp"
          "Hellocount.qrc"
      )
    
      set_target_properties(hellocount PROPERTIES
          LABELS "EXECUTABLE"
          PREFIX ""
          COMPILE_FLAGS " -DFOR_AFB_BINDING"
          LINK_FLAGS "${BINDINGS_LINK_FLAG}"
          OUTPUT_NAME "${TARGET_NAME}"
      )
    
      target_link_libraries(hellocount
          Qt5::WebSockets
          Qt5::QuickWidgets
          Qt5::QuickControls2
          json-c
          libafb-helpers-qt.a
      )
    
    # Build and Package wgt using autobuild
    $ cd ..
    $ ./autobuild/agl/autobuild build
    $ ./autobuild/agl/autobuild package
    ## The hellocount-debug.wgt file is packaged and available at ~/Documents/agl-app/newtestapp/build.
    
  • We need the agl-demo-image (with core dependencies for ROS2 + YDLIDAR) instead of agl-weston-image due to presence of app-framework and qt peripherals.