From: Jan-Simon Möller Date: Fri, 21 Feb 2020 15:21:35 +0000 (+0100) Subject: Merge remote-tracking branch 'agl/next' X-Git-Tag: 9.99.1~27 X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?p=AGL%2Fmeta-agl-demo.git;a=commitdiff_plain;h=21459a102cf0212bbfa6647a246ff8d6d64479ad;hp=c31ab6c3d0d9198a958d388c3698c731ed8ad651 Merge remote-tracking branch 'agl/next' * agl/next: packagegroup-agl-demo: replace udisks with udisk2 vboxguestdrivers: upgrade to 6.1.2 qtlocation: remove local patch Declare layer compatibility with zeus Change-Id: Iac02f582ee0808329b343f80666d74fc5385af90 --- diff --git a/.gitreview b/.gitreview index 883d5abcb..76d2b295e 100644 --- a/.gitreview +++ b/.gitreview @@ -2,3 +2,4 @@ host=gerrit.automotivelinux.org port=29418 project=AGL/meta-agl-demo +defaultbranch=master diff --git a/recipes-config/cluster-demo-simulator/cluster-demo-simulator.bb b/recipes-config/cluster-demo-simulator/cluster-demo-simulator.bb new file mode 100644 index 000000000..171ea1677 --- /dev/null +++ b/recipes-config/cluster-demo-simulator/cluster-demo-simulator.bb @@ -0,0 +1,31 @@ +DESCRIPTION = "Simulate can messages of a driving car" +LICENSE = "GPLv2" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/GPL-2.0;md5=801f80980d171dd6425610833a22dbe6" + +SRC_URI = "\ + file://cluster-demo-simulator.service \ + file://simple_can_simulator.py \ +" + +inherit systemd + +SYSTEMD_PACKAGES = "${PN}" +SYSTEMD_SERVICE_${PN} = "cluster-demo-simulator.service" +SYSTEMD_AUTO_ENABLE_${PN} = "enable" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -d ${D}${systemd_system_unitdir} + install -m 0644 ${WORKDIR}/cluster-demo-simulator.service ${D}${systemd_system_unitdir} + install -d ${D}${sbindir} + install -m 0755 ${WORKDIR}/simple_can_simulator.py ${D}${sbindir} +} + +FILES_${PN} += "${systemd_system_unitdir}" + +RDEPENDS_${PN} = " \ + can-utils \ + python3 \ +" diff --git a/recipes-config/cluster-demo-simulator/files/cluster-demo-simulator.service b/recipes-config/cluster-demo-simulator/files/cluster-demo-simulator.service new file mode 100644 index 000000000..04d41c6cf --- /dev/null +++ b/recipes-config/cluster-demo-simulator/files/cluster-demo-simulator.service @@ -0,0 +1,13 @@ +[Unit] +Description=Cluster demo driving simulator +After=sllin-demo.service sllin-demo-virtual.service cluster-lin-bridging.service +Requires=sllin-demo.service sllin-demo-virtual.service cluster-lin-bridging.service + +[Service] +Type=simple +Restart=always +RestartSec=1 +ExecStart=/usr/bin/python3 /usr/sbin/simple_can_simulator.py + +[Install] +WantedBy=multi-user.target diff --git a/recipes-config/cluster-demo-simulator/files/simple_can_simulator.py b/recipes-config/cluster-demo-simulator/files/simple_can_simulator.py new file mode 100755 index 000000000..83f88706e --- /dev/null +++ b/recipes-config/cluster-demo-simulator/files/simple_can_simulator.py @@ -0,0 +1,381 @@ +#!/usr/bin/env python3 +# Copyright (c) 2016 Alex Bencz +# Copyright (c) 2019 Konsulko Group, smurray@konsulko.com +# Copyright (c) 2020 The Linux Foundation, jsmoeller@linuxfoundation.org +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + +# +# CANSocket from: +# +# https://github.com/abencz/python_socketcan/blob/master/python_socketcan_example.py +# + +import sys +import socket +import argparse +import struct +import errno +import threading +import time + +class CANSocket(object): + FORMAT = "= self.vehicle_speed: + return + v = (self.vehicle_speed - target_speed) / (duration * self.freq) + r = (self.engine_speed - target_rpm) / (duration * self.freq) + while self.vehicle_speed > target_speed and (not self.CRUISEACTIVE or bycruise): + with self.lock: + self.vehicle_speed -= v; + self.engine_speed -= r; + time.sleep(1 / self.freq) + + def increase(self, bycruise = True): + if self.CRUISEACTIVE: + target_speed = self.vehicle_speed + 5 + target_rpm = self.engine_speed * 1.1 + self.accelerate(target_speed, target_rpm, 2, bycruise) + + def decrease(self, bycruise = True): + if self.CRUISEACTIVE: + target_speed = self.vehicle_speed - 5 + target_rpm = self.engine_speed * 0.9 + self.brake(target_speed, target_rpm, 2, bycruise) + + def resume(self, bycruise = True): + target_speed = self.CRUISESPEED + target_rpm = self.CRUISERPM + current_speed = self.get_vehicle_speed() + if target_speed > current_speed: + self.accelerate(target_speed, target_rpm, 2, bycruise) + else: + self.brake(target_speed, target_rpm, 2, bycruise) + + def run(self): + while True: + if not self.CRUISEACTIVE: + self.accelerate(80, 3000, 5) + self.accelerate(104, 4000, 3) + self.brake(80, 3000, 3) + self.accelerate(104, 4000, 6) + self.brake(40, 2000, 4) + self.accelerate(90, 3000, 5) + self.brake(1, 650, 5) + if not self.CRUISEACTIVE: + self.reset() + time.sleep(5) + +class DiagnosticMessageHandler(object): + def __init__(self, can_sock, simulator, verbose=False): + self.can_sock = can_sock + self.simulator = simulator + self.verbose = verbose + self.thread = threading.Thread(target=self.run, daemon=True) + + def start(self): + self.thread.start() + + def run(self): + while True: + can_id, data = self.can_sock.recv() + #print('%03X#%s' % (can_id, ''.join(format(x, '02X') for x in data))) + if can_id == 0x7df: + # OBD-II request + if data[1] == 0x01 and data[2] == 0x0C: + # Engine speed + speed = self.simulator.get_engine_speed() + #print('engine speed = %d' % speed) + if speed > 16383.75: + speed = 16383.75 + reply = [ 0x04, 0x41, 0x0C ] + reply.append(4 * speed // 256) + reply.append(4 * speed % 256) + # pad remaining bytes to make 8 + reply.append(0) + reply.append(0) + reply.append(0) + self.can_sock.send(0x7e8, bytes(reply), 0) + elif data[1] == 0x01 and data[2] == 0x0D: + # Vehicle speed + speed = int(self.simulator.get_vehicle_speed()) % 256 + #print('vehicle speed = %d' % speed) + reply = [ 0x03, 0x41, 0x0D ] + reply.append(speed) + # pad remaining bytes to make 8 + reply.append(0) + reply.append(0) + reply.append(0) + reply.append(0) + self.can_sock.send(0x7e8, bytes(reply), 0) + +class SteeringWheelMessageHandler(object): + def __init__(self, can_sock, simulator, verbose=False): + self.can_sock = can_sock + self.simulator = simulator + self.verbose = verbose + self.thread = threading.Thread(target=self.run, daemon=True) + self.buttonpressed = False + self.buttonenabled = False + self.buttoncancel = False + self.buttondec = False + self.buttoninc = False + self.cruisemode = False + self.cruiseactive = False + + def start(self): + self.thread.start() + + def run(self): + while True: + can_id, data = self.can_sock.recv() + #print('%03X#%s' % (can_id, ''.join(format(x, '02X') for x in data))) + if can_id == 0x21: + #print('%03X#%s' % (can_id, ''.join(format(x, '02X') for x in data))) + if data: + #if data[6]: + #print('data6: %02X' % (data[6])) + if data[6] == 0x80 and not self.buttonpressed: + # we do skip any further lin messages + # two buttons at the same time won't work + # (aka unlikely w/o twisting fingers) + self.buttonpressed = True + self.buttonenabled = True + if data[6] == 0x08 and not self.buttonpressed: + self.buttonpressed = True + self.buttoncancel = True + if data[6] == 0x10 and not self.buttonpressed: + self.buttonpressed = True + self.buttondec = True + if data[6] == 0x40 and not self.buttonpressed: + self.buttonpressed = True + self.buttoninc = True + if data[6] == 0x00 and self.buttonpressed: + #now handle it as the button was released + if self.buttonenabled: + self.buttonenabled = False + self.cruisemode = not self.cruisemode + #print("set cruisemode to %s" % self.cruisemode) + self.simulator.CRUISEMODE = self.cruisemode + # disable/reset all if going off + if not self.cruisemode: + self.cruiseactive = False + self.simulator.CRUISEACTIVE = self.cruiseactive + self.simulator.CRUISESPEED = 0 + self.simulator.CRUISERPM = 0 + #print("set cruiseactive to %s" % self.cruiseactive) + if self.buttoncancel: + self.buttoncancel = False + self.simulator.CRUISESPEED = self.simulator.get_vehicle_speed() + self.simulator.CRUISERPM = self.simulator.get_engine_speed() + #print("set cruisespeed to %d" % self.simulator.CRUISESPEED ) + #print("set cruiserpm to %d" % self.simulator.CRUISERPM ) + self.cruiseactive = False + #print("set cruiseactive to %s" % self.cruiseactive ) + self.simulator.CRUISEACTIVE = self.cruiseactive + if self.buttondec: + self.buttondec = False + if self.cruiseactive: + #print("decrease") + self.simulator.decrease() + else: + # set speed + #print("set speed") + self.simulator.CRUISESPEED = self.simulator.get_vehicle_speed() + self.simulator.CRUISERPM = self.simulator.get_engine_speed() + #print("set cruisespeed to %d" % self.simulator.CRUISESPEED ) + #print("set cruiserpm to %d" % self.simulator.CRUISERPM ) + self.cruiseactive = not self.cruiseactive + #print("set cruiseactive to %s" % self.cruiseactive ) + self.simulator.CRUISEACTIVE = self.cruiseactive + if self.buttoninc: + self.buttoninc = False + if self.cruiseactive: + #print("increase") + self.simulator.increase() + else: + if self.simulator.CRUISESPEED > 0: + # resume + self.cruiseactive = not self.cruiseactive + self.simulator.CRUISEACTIVE = self.cruiseactive + #print("set cruiseactive to %s" % self.cruiseactive ) + #print("resume") + self.simulator.resume() + self.buttonpressed = False + + +class StatusMessageSender(object): + def __init__(self, can_sock, simulator, verbose=False): + self.can_sock = can_sock + self.simulator = simulator + self.verbose = verbose + self.thread = threading.Thread(target=self.run, daemon=True) + + def start(self): + self.thread.start() + + def run(self): + while True: + # Engine speed + speed = self.simulator.get_engine_speed() + if self.verbose: + print('engine speed = %d' % speed) + if speed > 16383.75: + speed = 16383.75 + # Message is 1 byte unknown, 1 byte fuel level, 2 bytes engine speed (4x), fuel low @ bit 55 + msg = [ 0, 0 ] + speed *= 4 + msg.append(speed // 256) + msg.append(speed % 256) + # pad remaining bytes to make 8 + msg.append(0) + msg.append(0) + msg.append(0) + msg.append(0) + self.can_sock.send(0x3d9, bytes(msg), 0) + + # Vehicle speed + speed = int(self.simulator.get_vehicle_speed()) % 256 + if self.verbose: + print('vehicle speed = %d' % speed) + # Message is 15 bits speed (64x), left aligned + msg = [ ] + # Note: extra 2x to yield required left-alignment + speed *= 128 + msg.append(speed // 256) + msg.append(speed % 256) + # pad remaining bytes to make 8 + msg.append(0) + msg.append(0) + msg.append(0) + msg.append(0) + msg.append(0) + msg.append(0) + self.can_sock.send(0x3e9, bytes(msg), 0) + + # Sleep 100 ms + time.sleep(0.1) + +def main(): + parser = argparse.ArgumentParser(description='Simple CAN vehicle simulator.') + parser.add_argument('interface', type=str, help='interface name (e.g. vcan0)') + parser.add_argument('-v', '--verbose', help='increase output verbosity', action='store_true') + args = parser.parse_args() + + try: + can_sock = CANSocket(args.interface) + diag_can_sock = CANSocket(args.interface) + steeringwheel_can_sock = CANSocket(args.interface) + except OSError as e: + sys.stderr.write('Could not listen on interface {0}\n'.format(args.interface)) + sys.exit(e.errno) + + print('Using {0}'.format(args.interface)) + sim = VehicleSimulator() + status_sender = StatusMessageSender(can_sock, sim, args.verbose) + diag_handler = DiagnosticMessageHandler(diag_can_sock, sim, args.verbose) + steeringwheel_handler = SteeringWheelMessageHandler(steeringwheel_can_sock, sim, args.verbose) + sim.start() + status_sender.start() + diag_handler.start() + steeringwheel_handler.start() + try: + while True: + time.sleep(60) + except (KeyboardInterrupt, SystemExit): + #sim.stop() + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/recipes-demo-hmi/html5-dashboard/html5-dashboard_git.bb b/recipes-demo-hmi/html5-dashboard/html5-dashboard_git.bb new file mode 100644 index 000000000..534bd2d38 --- /dev/null +++ b/recipes-demo-hmi/html5-dashboard/html5-dashboard_git.bb @@ -0,0 +1,25 @@ +SUMMARY = "AGL HTML5 dashboard Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-dashboard/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git/" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-dashboard;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "${AGL_APP_REVISION}" + +DEPENDS += " nodejs-native" + +inherit aglwgt + +do_configure() { + cd ${B} + npm install +} + +do_aglwgt_package() { + cd ${B} + npm run build +} diff --git a/recipes-demo-hmi/html5-homescreen/html5-homescreen_git.bb b/recipes-demo-hmi/html5-homescreen/html5-homescreen_git.bb new file mode 100644 index 000000000..68956263f --- /dev/null +++ b/recipes-demo-hmi/html5-homescreen/html5-homescreen_git.bb @@ -0,0 +1,25 @@ +SUMMARY = "AGL HTML5 Homescreen Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-homescreen/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git/" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-homescreen;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "${AGL_APP_REVISION}" + +DEPENDS += " nodejs-native" + +inherit aglwgt + +do_configure() { + cd ${B} + npm install +} + +do_aglwgt_package() { + cd ${B} + npm run build +} diff --git a/recipes-demo-hmi/html5-mediaplayer/html5-mediaplayer_git.bb b/recipes-demo-hmi/html5-mediaplayer/html5-mediaplayer_git.bb new file mode 100644 index 000000000..2b1437669 --- /dev/null +++ b/recipes-demo-hmi/html5-mediaplayer/html5-mediaplayer_git.bb @@ -0,0 +1,25 @@ +SUMMARY = "AGL HTML5 Mediaplayer Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-mediaplayer/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git/" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-mediaplayer;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "${AGL_APP_REVISION}" + +DEPENDS += " nodejs-native" + +inherit aglwgt + +do_configure() { + cd ${B} + npm install +} + +do_aglwgt_package() { + cd ${B} + npm run build +} diff --git a/recipes-demo-hmi/html5-mixer/html5-mixer_git.bb b/recipes-demo-hmi/html5-mixer/html5-mixer_git.bb new file mode 100644 index 000000000..babef57c8 --- /dev/null +++ b/recipes-demo-hmi/html5-mixer/html5-mixer_git.bb @@ -0,0 +1,25 @@ +SUMMARY = "AGL HTML5 Mixer Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-mixer/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git/" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-mixer;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "${AGL_APP_REVISION}" + +DEPENDS += " nodejs-native" + +inherit aglwgt + +do_configure() { + cd ${B} + npm install +} + +do_aglwgt_package() { + cd ${B} + npm run build +} diff --git a/recipes-demo-hmi/html5-settings/html5-settings_git.bb b/recipes-demo-hmi/html5-settings/html5-settings_git.bb new file mode 100644 index 000000000..dea1ec35b --- /dev/null +++ b/recipes-demo-hmi/html5-settings/html5-settings_git.bb @@ -0,0 +1,25 @@ +SUMMARY = "AGL HTML5 Settings Application" +HOMEPAGE = "https://git.automotivelinux.org/apps/html5-settings/" +SECTION = "apps" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=3b83ef96387f14655fc854ddc3c6bd57" + +PV = "1.0+git${SRCPV}" +S = "${WORKDIR}/git/" + +SRC_URI = "git://gerrit.automotivelinux.org/gerrit/apps/html5-settings;protocol=https;branch=${AGL_BRANCH}" +SRCREV = "${AGL_APP_REVISION}" + +DEPENDS += " nodejs-native" + +inherit aglwgt + +do_configure() { + cd ${B} + npm install +} + +do_aglwgt_package() { + cd ${B} + npm run build +} diff --git a/recipes-demo-hmi/low-can-demo/low-can-demo_git.bb b/recipes-demo-hmi/low-can-demo/low-can-demo_git.bb index 4edcdd89e..707cdde82 100644 --- a/recipes-demo-hmi/low-can-demo/low-can-demo_git.bb +++ b/recipes-demo-hmi/low-can-demo/low-can-demo_git.bb @@ -6,7 +6,7 @@ LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "gitsm://github.com/iotbzh/low-can-demo.git;protocol=https" -SRCREV = "1ede0d61cf935a1739d3ba184896a71f4afdce1a" +SRCREV = "9f0973a50c4d0c797cd63d6dccb8f865ef398b11" PV = "4.0+git${SRCPV}" S = "${WORKDIR}/git" diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb b/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb index afedf07a2..6ec717bd0 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-demo-platform-html5.bb @@ -18,8 +18,13 @@ RDEPENDS_${PN} += "\ " AGL_APPS = " \ + html5-homescreen \ html5-launcher \ html5-hvac \ + html5-settings \ + html5-mixer \ + html5-mediaplayer \ + html5-dashboard \ " RDEPENDS_${PN}_append = " \ diff --git a/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb b/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb index 944b34bdc..28777e2b1 100644 --- a/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb +++ b/recipes-platform/packagegroups/packagegroup-agl-demo-platform.bb @@ -59,14 +59,16 @@ CLUSTER_SUPPORT_PACKAGES = " \ ${MAPVIEWER} \ cluster-demo-network-config \ cluster-lin-bridging-config \ + cluster-demo-simulator \ " CLUSTER_SUPPORT = "${@bb.utils.contains("DISTRO_FEATURES", "agl-cluster-demo-support", "${CLUSTER_SUPPORT_PACKAGES}", "",d)}" +DEMO_UNIT_CONF ?= "" # Hook for demo platform configuration # ATM used for: # 1) Adding udev configuration and scripts for supporting USB attached # I2C devices for RTC and HVAC LED support. -DEMO_PLATFORM_CONF = " demo-i2c-udev-conf " +DEMO_UNIT_CONF += " demo-i2c-udev-conf " # Preload poi API key for demo if requested, and potentially maps for older # navigation application if it is configured. @@ -74,7 +76,7 @@ DEMO_MAPS_LOCALE ?= "uk" DEMO_PRELOAD_MAPS = "${@bb.utils.contains("PREFERRED_RPROVIDER_virtual/navigation", "navigation", " navigation-maps-${DEMO_MAPS_LOCALE}", "",d)}" # Preload only if agl-demo-preload is set -DEMO_PRELOAD = "${@bb.utils.contains("DISTRO_FEATURES", "agl-demo-preload", " ${DEMO_PRELOAD_MAPS} ${DEMO_PLATFORM_CONF} poiapp-api-key", "",d)}" +DEMO_PRELOAD = "${@bb.utils.contains("DISTRO_FEATURES", "agl-demo-preload", " ${DEMO_PRELOAD_MAPS} ${DEMO_UNIT_CONF} poiapp-api-key", "",d)}" RDEPENDS_${PN}_append = " \