From 2b54cb6f5797df36d14df55cd685a0d61ccd7001 Mon Sep 17 00:00:00 2001 From: zheng_wenlong Date: Tue, 9 Apr 2019 10:38:35 +0900 Subject: Add demo3 tachometer source code Add demo3 tachometer source code for cluster mode. [Patch Set 2] Update LICENSE file. Change-Id: Icac1ec8a08056988b519982d77d15a1eb5da8169 BUG-AGL: SPEC-2261 Signed-off-by: zheng_wenlong --- .gitignore | 4 + .gitreview | 6 + LICENSE | 204 +++++ README.md | 69 ++ app/Mid.qml | 34 + app/Shift.qml | 52 ++ app/Speed.qml | 91 ++ app/Tacho.qml | 101 +++ app/app.pri | 20 + app/app.pro | 21 + app/camera.cpp | 130 +++ app/camera.h | 67 ++ app/images/camera/camera_bg.svg | 484 +++++++++++ app/images/camera/camerainfo_bg.svg | 93 ++ app/images/homescreen/homebg_bottom.svg | 1397 +++++++++++++++++++++++++++++++ app/images/images.qrc | 40 + app/images/meters/speed_0.svg | 102 +++ app/images/meters/speed_1.svg | 62 ++ app/images/meters/speed_2.svg | 94 +++ app/images/meters/speed_3.svg | 138 +++ app/images/meters/speed_4.svg | 78 ++ app/images/meters/speed_5.svg | 104 +++ app/images/meters/speed_6.svg | 119 +++ app/images/meters/speed_7.svg | 102 +++ app/images/meters/speed_8.svg | 164 ++++ app/images/meters/speed_9.svg | 143 ++++ app/images/meters/speed_center.svg | 391 +++++++++ app/images/meters/speed_kmh.svg | 63 ++ app/images/meters/speed_limit_none.svg | 156 ++++ app/images/meters/speed_mph.svg | 63 ++ app/images/meters/tacho_center.svg | 246 ++++++ app/images/meters/tacho_frame.svg | 213 +++++ app/images/meters/tacho_hand.svg | 189 +++++ app/images/meters/tacho_scale.svg | 876 +++++++++++++++++++ app/images/meters/tacho_shift_1.svg | 46 + app/images/meters/tacho_shift_2.svg | 63 ++ app/images/meters/tacho_shift_3.svg | 69 ++ app/images/meters/tacho_shift_4.svg | 56 ++ app/images/meters/tacho_shift_5.svg | 67 ++ app/images/meters/tacho_shift_6.svg | 72 ++ app/images/meters/tacho_shift_B.svg | 82 ++ app/images/meters/tacho_shift_D.svg | 67 ++ app/images/meters/tacho_shift_N.svg | 66 ++ app/images/meters/tacho_shift_P.svg | 88 ++ app/images/meters/tacho_shift_R.svg | 70 ++ app/images/mid/mid_S_normal.svg | 1171 ++++++++++++++++++++++++++ app/images/mid/mid_other.svg | 123 +++ app/images/mid/recirc_inter.svg | 339 ++++++++ app/images/mid/recirc_outer.svg | 339 ++++++++ app/main.cpp | 129 +++ app/main.qml | 277 ++++++ app/main.qrc | 9 + package/config.xml | 20 + package/icon.svg | 892 ++++++++++++++++++++ package/package.pro | 19 + tachometer.pro | 3 + 56 files changed, 10183 insertions(+) create mode 100644 .gitignore create mode 100644 .gitreview create mode 100644 LICENSE create mode 100644 README.md create mode 100644 app/Mid.qml create mode 100644 app/Shift.qml create mode 100644 app/Speed.qml create mode 100644 app/Tacho.qml create mode 100644 app/app.pri create mode 100644 app/app.pro create mode 100644 app/camera.cpp create mode 100644 app/camera.h create mode 100644 app/images/camera/camera_bg.svg create mode 100644 app/images/camera/camerainfo_bg.svg create mode 100644 app/images/homescreen/homebg_bottom.svg create mode 100644 app/images/images.qrc create mode 100644 app/images/meters/speed_0.svg create mode 100644 app/images/meters/speed_1.svg create mode 100644 app/images/meters/speed_2.svg create mode 100644 app/images/meters/speed_3.svg create mode 100644 app/images/meters/speed_4.svg create mode 100644 app/images/meters/speed_5.svg create mode 100644 app/images/meters/speed_6.svg create mode 100644 app/images/meters/speed_7.svg create mode 100644 app/images/meters/speed_8.svg create mode 100644 app/images/meters/speed_9.svg create mode 100644 app/images/meters/speed_center.svg create mode 100644 app/images/meters/speed_kmh.svg create mode 100644 app/images/meters/speed_limit_none.svg create mode 100644 app/images/meters/speed_mph.svg create mode 100644 app/images/meters/tacho_center.svg create mode 100644 app/images/meters/tacho_frame.svg create mode 100644 app/images/meters/tacho_hand.svg create mode 100644 app/images/meters/tacho_scale.svg create mode 100644 app/images/meters/tacho_shift_1.svg create mode 100644 app/images/meters/tacho_shift_2.svg create mode 100644 app/images/meters/tacho_shift_3.svg create mode 100644 app/images/meters/tacho_shift_4.svg create mode 100644 app/images/meters/tacho_shift_5.svg create mode 100644 app/images/meters/tacho_shift_6.svg create mode 100644 app/images/meters/tacho_shift_B.svg create mode 100644 app/images/meters/tacho_shift_D.svg create mode 100644 app/images/meters/tacho_shift_N.svg create mode 100644 app/images/meters/tacho_shift_P.svg create mode 100644 app/images/meters/tacho_shift_R.svg create mode 100644 app/images/mid/mid_S_normal.svg create mode 100644 app/images/mid/mid_other.svg create mode 100644 app/images/mid/recirc_inter.svg create mode 100644 app/images/mid/recirc_outer.svg create mode 100644 app/main.cpp create mode 100644 app/main.qml create mode 100644 app/main.qrc create mode 100644 package/config.xml create mode 100644 package/icon.svg create mode 100644 package/package.pro create mode 100644 tachometer.pro diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0358002 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +build +*.pro.user +app/config.tests +.vscode \ No newline at end of file diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000..c46e7c9 --- /dev/null +++ b/.gitreview @@ -0,0 +1,6 @@ +[gerrit] +host=gerrit.automotivelinux.org +port=29418 +project=apps/demo3-tachometer +defaultbranch=master + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b3201ab --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don`t include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..89807ca --- /dev/null +++ b/README.md @@ -0,0 +1,69 @@ +Information +==== +
This is sample application for af-steering-wheel-binding. +
At above of the screen will display usb-camera(UVC camera) video. +
At bottom of this screen will display the can information. +
Right now it can get VehicleSpeed,EngineSpeed,TransmissionMode information from af-steering-wheel-binding. +
Or you can change to use low-level-can-servcie. + +* Hardware: Renesas m3ulcb +* Software: Daring Dab 4.0.0 +* Application name: tachometer +* Test Device: Logitech c920r + +How to compile and install +==== +
These is a sample recipe for tachometer, you can just add that recipes into your project and bitbake. +
Sample Recipes: tachometer_git.bb + +How to use +==== +
1, If the camera has been connected, you can select the camera corresponding to the device ID, and set FPS , +
pixel parameters, open ON/OFF switch on the right, you can see the camera display content. +
2, operation steering-wheel device corresponding function, you can see vehicle speed, engine speed, transmission mode changes. + +Kernel configure +==== +
You need to enable some kernel configure to enable usb camera. +* CONFIG_VIDEOBUF2_VMALLOC=y +* CONFIG_MEDIA_USB_SUPPORT=y +* CONFIG_USB_VIDEO_CLASS=y +* CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y + +CAN data +==== +* engine.speed +
canid: 1C4 +
offset: 0 +
bitsize: 16 +
sample: cansend vcan0 1C4#FFFF000000000000 + +* vehicle.average.speed +
canid: 0B4 +
offset: 40 +
bitsize: 16 +
sample: cansend vcan0 0B4#0000000000FFFF00 + +* fuel.level +
canid: 612 +
offset: 40 +
bitsize: 8 +
sample: cansend vcan0 612#0000000000FF0000 + +* Transmission.SiftPosition.neutral +
canid: 3BC +
offset: 12 +
bitsize: 1 +
sample: cansend vcan0 3BC#0008000000000000 + +* Transmission.SiftPosition.driving +
canid: 3BC +
offset: 40 +
bitsize: 1 +
sample: cansend vcan0 3BC#0000000000800000 + +* Transmission.SiftPosition.parking +
canid: 3BC +
offset: 10 +
bitsize: 1 +
sample: cansend vcan0 3BC#0020000000000000 diff --git a/app/Mid.qml b/app/Mid.qml new file mode 100644 index 0000000..81cb672 --- /dev/null +++ b/app/Mid.qml @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION + * + * 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.Controls 2.0 +import QtQuick.Layouts 1.0 + +Item { + property real imgwidth: 384 + property real imgheight: 384 + + Image { + id: midimg + width: imgwidth + height: imgheight + fillMode: Image.PreserveAspectFit + asynchronous: true + smooth: true + source: "images/mid/mid_S_normal.svg" + } +} diff --git a/app/Shift.qml b/app/Shift.qml new file mode 100644 index 0000000..c27025b --- /dev/null +++ b/app/Shift.qml @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION + * + * 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.0 +import QtWebSockets 1.0 + +Row { + property real percent: 1 + property var carshift: [ + "images/meters/tacho_shift_N.svg", "images/meters/tacho_shift_D.svg", + "images/meters/tacho_shift_P.svg", "images/meters/tacho_shift_R.svg" + ] + + property var wheelshift: [ + "images/meters/tacho_shift_1.svg", "images/meters/tacho_shift_2.svg", + "images/meters/tacho_shift_3.svg", "images/meters/tacho_shift_4.svg", + "images/meters/tacho_shift_5.svg", "images/meters/tacho_shift_6.svg" + ] + + Image { + width: percent*sourceSize.width + height: percent*sourceSize.height + fillMode: Image.PreserveAspectFit + smooth: true + asynchronous: true + source: wshift == "N" ? carshift[0] : ( wshift == "P" ? carshift[2] : ( wshift == "R" ? carshift[3] : carshift[1])) + } + + Image { + visible: (wshift == "D1" || wshift == "D2"||wshift == "D3"||wshift == "D4"||wshift == "D5"||wshift == "D6") + width: percent*sourceSize.width + height: percent*sourceSize.height + fillMode: Image.PreserveAspectFit + smooth: true + asynchronous: true + source: (wshift == "D1") ? wheelshift[0] : ((wshift == "D2") ? wheelshift[1] : ((wshift == "D3") ? wheelshift[2] : ((wshift == "D4") ? wheelshift[3] : ((wshift == "D5") ? wheelshift[4] : wheelshift[5] )))) + } +} diff --git a/app/Speed.qml b/app/Speed.qml new file mode 100644 index 0000000..5d9b349 --- /dev/null +++ b/app/Speed.qml @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION + * + * 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.3 +import QtWebSockets 1.0 + +Item { + property real imgwidth: 360 + property real imgheight: 360 + property var spdlist: [ + "images/meters/speed_0.svg", "images/meters/speed_1.svg", + "images/meters/speed_2.svg", "images/meters/speed_3.svg", + "images/meters/speed_4.svg", "images/meters/speed_5.svg", + "images/meters/speed_6.svg", "images/meters/speed_7.svg", + "images/meters/speed_8.svg", "images/meters/speed_9.svg" + ] + property var spdlimit: [ "images/meters/speed_limit_none.svg" ] + + Image { + width: 336 + height: 336 + anchors.top: parent.top + anchors.topMargin: 17 + anchors.horizontalCenter: parent.horizontalCenter + fillMode: Image.PreserveAspectFit + asynchronous: true + smooth: true + source: "images/meters/speed_center.svg" + } + + Image { + width: imgwidth + height: imgheight + smooth: true + asynchronous: true + source: spdlimit[0] + } + + Row { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + Image { + width: imgwidth*sourceSize.width/480 + height: imgheight*sourceSize.height/480 + fillMode: Image.PreserveAspectFit + asynchronous: true + smooth: true + visible: vehiclespeed > 99 + source: ((vehiclespeed - vehiclespeed%100)/100%10 < spdlist.length) ? spdlist[(vehiclespeed - vehiclespeed%100)/100%10] : spdlist[0] + } + Image { + width: imgwidth*sourceSize.width/480 + height: imgheight*sourceSize.height/480 + fillMode: Image.PreserveAspectFit + asynchronous: true + smooth: true + visible: vehiclespeed > 9 + source: ((vehiclespeed - vehiclespeed%10)/10%10 < spdlist.length) ? spdlist[(vehiclespeed - vehiclespeed%10)/10%10] : spdlist[0] + } + Image { + width: imgwidth*sourceSize.width/480 + height: imgheight*sourceSize.height/480 + fillMode: Image.PreserveAspectFit + asynchronous: true + smooth: true + source: (vehiclespeed%10 < spdlist.length) ? spdlist[vehiclespeed%10] : spdlist[0] + } + } + Image { + width: imgwidth + height: imgheight + fillMode: Image.PreserveAspectFit + asynchronous: true + smooth: true + source: "images/meters/speed_mph.svg" + } +} diff --git a/app/Tacho.qml b/app/Tacho.qml new file mode 100644 index 0000000..a345de9 --- /dev/null +++ b/app/Tacho.qml @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION + * + * 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 QtWebSockets 1.0 + +Item { + property real imgwidth: 500 + property real imgheight: 500 + + property real tacho: enginespeed === undefined ? 0 : (enginespeed > 9000 ? 9 : enginespeed*9/9000) + + Image { + width: imgwidth + height: imgheight + fillMode: Image.PreserveAspectFit + smooth: true + asynchronous: true + source: "images/meters/tacho_center.svg" + } + Image { + width: imgwidth + height: imgheight + fillMode: Image.PreserveAspectFit + smooth: true + asynchronous: true + source: "images/meters/tacho_frame.svg" + } + Image { + width: imgwidth + height: imgheight + fillMode: Image.PreserveAspectFit + smooth: true + asynchronous: true + source: "images/meters/tacho_scale.svg" + } + Shift { + percent: imgwidth/480 + anchors.right: parent.right + anchors.rightMargin: (wshift == "N" || wshift == "P" ||wshift == "R" )? (imgwidth-width)/2+25 : (imgwidth-width)/2-5 + anchors.bottom: parent.bottom + anchors.bottomMargin: 100 + spacing: -10 + } + Canvas { + id: canvas + property real engleoffset: Math.PI*3/2.04 + property int linewidth: 90 + anchors.centerIn: parent + width: 420 + height: 420 + visible: tacho >= 0.05 + rotation: 135 + opacity: 0.5 + onPaint: { + var ctx = getContext("2d") + var gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height) + gradient.addColorStop(0.0, Qt.rgba(1.0, 1.0, 1.0, 1.0)) + gradient.addColorStop(1.0, Qt.rgba(1.0, 1.0, 1.0, 0.0)) + + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.beginPath(); + ctx.lineWidth = linewidth; + ctx.strokeStyle = gradient + ctx.arc(canvas.width/2, + canvas.height/2, + (canvas.width-ctx.lineWidth)/2, + 0.1, + engleoffset*(tacho/9) + (tacho < 3 ? 0.1 : (tacho < 7 ? 0.05 : 0.0)), + false) + ctx.stroke() + ctx.closePath() + } + } + Image { + width: imgwidth + height: imgheight + fillMode: Image.PreserveAspectFit + smooth: true + asynchronous: true + rotation: 28.8*tacho + source: "images/meters/tacho_hand.svg" + } + + onTachoChanged: { + canvas.requestPaint() + } +} diff --git a/app/app.pri b/app/app.pri new file mode 100644 index 0000000..590c154 --- /dev/null +++ b/app/app.pri @@ -0,0 +1,20 @@ +TEMPLATE = app + +load(configure) + +qtCompileTest(libhomescreen) +qtCompileTest(qlibwindowmanager) + +config_libhomescreen { + CONFIG += link_pkgconfig + PKGCONFIG += libhomescreen + DEFINES += HAVE_LIBHOMESCREEN +} + +config_qlibwindowmanager { + CONFIG += link_pkgconfig + PKGCONFIG += qlibwindowmanager + DEFINES += HAVE_QLIBWINDOWMANAGER +} + +DESTDIR = $${OUT_PWD}/../package/root/bin diff --git a/app/app.pro b/app/app.pro new file mode 100644 index 0000000..d0b2961 --- /dev/null +++ b/app/app.pro @@ -0,0 +1,21 @@ +TARGET = tachometer +QT = quickcontrols2 + +equals(QT_ARCH, "arm") { + QMAKE_CXXFLAGS += -mfp16-format=ieee +} + +HEADERS += \ + camera.h + +SOURCES += \ + main.cpp \ + camera.cpp + +LIBS += -lopencv_core -lopencv_highgui -lopencv_videoio + +RESOURCES += \ + main.qrc \ + images/images.qrc + +include(app.pri) diff --git a/app/camera.cpp b/app/camera.cpp new file mode 100644 index 0000000..f935f22 --- /dev/null +++ b/app/camera.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2017 TOYOTA MOTOR CORPORATION + * + * 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 "camera.h" +#include +#include + +#include +#include +#include +#include + +using namespace cv; + +Camera::Camera() { + running = false; + timer = new QTimer(this); + capture = new VideoCapture(); + + connect(timer, SIGNAL(timeout()), this, SLOT(grab())); +} + +Camera::~Camera() { + if (timer->isActive()) + timer->stop(); + if (capture && capture->isOpened()) + capture->release(); + delete timer; + delete capture; +} + +void Camera::paint(QPainter *painter) { + painter->drawImage(0, 0, image); +} + +void Camera::enumerateCameras() { + int maxID = 20; + for (int idx = 2; idx " << (char*)(cap.card) << ">" << (char*)(cap.bus_info);// << (cap.version>>16)&0xFF << (cap.version>>8)&0XFF << cap.version&0xFF; + cam_arr.push_back(idx); // vector of all available cameras + } + } + close(fd); + } + } + + camcnt = cam_arr.length(); +} + +void Camera::start(int no, int fps, QString res) { + int retryCount = 0; + while(!capture->open(no)){ + if(retryCount++==5){ + qDebug()<< "Try to open camera for 5 times failed, give up."; + return; + }else{ + qDebug()<< "open camera failed, retry " << retryCount; + usleep(200000); + } + } + + capture->set(CAP_PROP_FRAME_WIDTH, res.section("*", 0, 0).toInt()); + capture->set(CAP_PROP_FRAME_HEIGHT, res.section("*", 1, 1).toInt()); + + if (fps > 0){ + timer->start(1000/fps); + running = true; + emit isrunningChanged(running); + } +} + +void Camera::stop() { + if (timer->isActive()) + timer->stop(); + if (capture->isOpened()){ + qDebug()<< "release camera."; + capture->release(); + } + image = QImage(); + update(); + running = false; + emit isrunningChanged(running); +} + +QVariantList Camera::camranum() const{ + return cam_arr; +} + +int Camera::cameraCnt() { + return camcnt; +} + +bool Camera::isrunning() const{ + return running; +} + +void Camera::grab() { + if (capture && capture->isOpened()){ + Mat frame; + capture->read(frame); + + if (!frame.empty()){ + image = QImage((const uchar*)(frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888).rgbSwapped(); + image = image.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + update(); + } + } +} diff --git a/app/camera.h b/app/camera.h new file mode 100644 index 0000000..6890745 --- /dev/null +++ b/app/camera.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION + * + * 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. + */ + +#ifndef CAMERA_H +#define CAMERA_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +static QVariantList cam_arr_bak; + +class Camera : public QQuickPaintedItem +{ + Q_OBJECT + Q_PROPERTY(bool isrunning READ isrunning NOTIFY isrunningChanged) +public: + Camera(); + ~Camera(); + void paint(QPainter *painter); + bool isrunning() const; + Q_INVOKABLE QVariantList camranum() const; + + Q_INVOKABLE void start(int no, int fps, QString res); + Q_INVOKABLE void stop(); + + Q_INVOKABLE void enumerateCameras(); + Q_INVOKABLE int cameraCnt(); + +signals: + void isrunningChanged(const bool& isrunning); + +public slots: + void grab(); + +private: + bool running; + QImage image; + QTimer* timer; + cv::VideoCapture* capture; + + QVariantList cam_arr; + int camcnt; +}; + +#endif // CAMERA_H diff --git a/app/images/camera/camera_bg.svg b/app/images/camera/camera_bg.svg new file mode 100644 index 0000000..458f81c --- /dev/null +++ b/app/images/camera/camera_bg.svg @@ -0,0 +1,484 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/camera/camerainfo_bg.svg b/app/images/camera/camerainfo_bg.svg new file mode 100644 index 0000000..4251412 --- /dev/null +++ b/app/images/camera/camerainfo_bg.svg @@ -0,0 +1,93 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/app/images/homescreen/homebg_bottom.svg b/app/images/homescreen/homebg_bottom.svg new file mode 100644 index 0000000..78bf678 --- /dev/null +++ b/app/images/homescreen/homebg_bottom.svg @@ -0,0 +1,1397 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/images.qrc b/app/images/images.qrc new file mode 100644 index 0000000..2c6c904 --- /dev/null +++ b/app/images/images.qrc @@ -0,0 +1,40 @@ + + + meters/speed_3.svg + meters/speed_7.svg + meters/speed_8.svg + meters/speed_9.svg + meters/tacho_hand.svg + meters/tacho_shift_P.svg + meters/tacho_shift_R.svg + meters/speed_center.svg + meters/tacho_shift_N.svg + meters/tacho_center.svg + meters/tacho_scale.svg + meters/speed_5.svg + meters/speed_4.svg + meters/speed_6.svg + meters/speed_2.svg + meters/tacho_shift_D.svg + meters/speed_0.svg + meters/speed_limit_none.svg + meters/tacho_frame.svg + meters/speed_1.svg + meters/speed_kmh.svg + meters/speed_mph.svg + homescreen/homebg_bottom.svg + camera/camera_bg.svg + camera/camerainfo_bg.svg + mid/mid_S_normal.svg + mid/recirc_inter.svg + mid/recirc_outer.svg + meters/tacho_shift_B.svg + meters/tacho_shift_1.svg + meters/tacho_shift_2.svg + meters/tacho_shift_3.svg + meters/tacho_shift_4.svg + meters/tacho_shift_5.svg + meters/tacho_shift_6.svg + mid/mid_other.svg + + diff --git a/app/images/meters/speed_0.svg b/app/images/meters/speed_0.svg new file mode 100644 index 0000000..f3fb4ad --- /dev/null +++ b/app/images/meters/speed_0.svg @@ -0,0 +1,102 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_1.svg b/app/images/meters/speed_1.svg new file mode 100644 index 0000000..05d48b4 --- /dev/null +++ b/app/images/meters/speed_1.svg @@ -0,0 +1,62 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_2.svg b/app/images/meters/speed_2.svg new file mode 100644 index 0000000..dd97941 --- /dev/null +++ b/app/images/meters/speed_2.svg @@ -0,0 +1,94 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_3.svg b/app/images/meters/speed_3.svg new file mode 100644 index 0000000..67a987c --- /dev/null +++ b/app/images/meters/speed_3.svg @@ -0,0 +1,138 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/meters/speed_4.svg b/app/images/meters/speed_4.svg new file mode 100644 index 0000000..c9b2364 --- /dev/null +++ b/app/images/meters/speed_4.svg @@ -0,0 +1,78 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_5.svg b/app/images/meters/speed_5.svg new file mode 100644 index 0000000..2768361 --- /dev/null +++ b/app/images/meters/speed_5.svg @@ -0,0 +1,104 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_6.svg b/app/images/meters/speed_6.svg new file mode 100644 index 0000000..ba4dcd0 --- /dev/null +++ b/app/images/meters/speed_6.svg @@ -0,0 +1,119 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_7.svg b/app/images/meters/speed_7.svg new file mode 100644 index 0000000..2537843 --- /dev/null +++ b/app/images/meters/speed_7.svg @@ -0,0 +1,102 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/meters/speed_8.svg b/app/images/meters/speed_8.svg new file mode 100644 index 0000000..656205f --- /dev/null +++ b/app/images/meters/speed_8.svg @@ -0,0 +1,164 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_9.svg b/app/images/meters/speed_9.svg new file mode 100644 index 0000000..96a6e87 --- /dev/null +++ b/app/images/meters/speed_9.svg @@ -0,0 +1,143 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/meters/speed_center.svg b/app/images/meters/speed_center.svg new file mode 100644 index 0000000..b9f9f60 --- /dev/null +++ b/app/images/meters/speed_center.svg @@ -0,0 +1,391 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_kmh.svg b/app/images/meters/speed_kmh.svg new file mode 100644 index 0000000..2602845 --- /dev/null +++ b/app/images/meters/speed_kmh.svg @@ -0,0 +1,63 @@ + + + + + + + + + image/svg+xml + + + + + + km/h + diff --git a/app/images/meters/speed_limit_none.svg b/app/images/meters/speed_limit_none.svg new file mode 100644 index 0000000..dde91bf --- /dev/null +++ b/app/images/meters/speed_limit_none.svg @@ -0,0 +1,156 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/speed_mph.svg b/app/images/meters/speed_mph.svg new file mode 100644 index 0000000..0114aed --- /dev/null +++ b/app/images/meters/speed_mph.svg @@ -0,0 +1,63 @@ + + + + + + + + + image/svg+xml + + + + + + mph + diff --git a/app/images/meters/tacho_center.svg b/app/images/meters/tacho_center.svg new file mode 100644 index 0000000..46086d9 --- /dev/null +++ b/app/images/meters/tacho_center.svg @@ -0,0 +1,246 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_frame.svg b/app/images/meters/tacho_frame.svg new file mode 100644 index 0000000..84a854f --- /dev/null +++ b/app/images/meters/tacho_frame.svg @@ -0,0 +1,213 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_hand.svg b/app/images/meters/tacho_hand.svg new file mode 100644 index 0000000..90ec605 --- /dev/null +++ b/app/images/meters/tacho_hand.svg @@ -0,0 +1,189 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/meters/tacho_scale.svg b/app/images/meters/tacho_scale.svg new file mode 100644 index 0000000..035b603 --- /dev/null +++ b/app/images/meters/tacho_scale.svg @@ -0,0 +1,876 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_1.svg b/app/images/meters/tacho_shift_1.svg new file mode 100644 index 0000000..8e3ce67 --- /dev/null +++ b/app/images/meters/tacho_shift_1.svg @@ -0,0 +1,46 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_2.svg b/app/images/meters/tacho_shift_2.svg new file mode 100644 index 0000000..8342580 --- /dev/null +++ b/app/images/meters/tacho_shift_2.svg @@ -0,0 +1,63 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_3.svg b/app/images/meters/tacho_shift_3.svg new file mode 100644 index 0000000..9c8e804 --- /dev/null +++ b/app/images/meters/tacho_shift_3.svg @@ -0,0 +1,69 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_4.svg b/app/images/meters/tacho_shift_4.svg new file mode 100644 index 0000000..5fb9296 --- /dev/null +++ b/app/images/meters/tacho_shift_4.svg @@ -0,0 +1,56 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_5.svg b/app/images/meters/tacho_shift_5.svg new file mode 100644 index 0000000..f4e9838 --- /dev/null +++ b/app/images/meters/tacho_shift_5.svg @@ -0,0 +1,67 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_6.svg b/app/images/meters/tacho_shift_6.svg new file mode 100644 index 0000000..da2f200 --- /dev/null +++ b/app/images/meters/tacho_shift_6.svg @@ -0,0 +1,72 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_B.svg b/app/images/meters/tacho_shift_B.svg new file mode 100644 index 0000000..3dcbe56 --- /dev/null +++ b/app/images/meters/tacho_shift_B.svg @@ -0,0 +1,82 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_D.svg b/app/images/meters/tacho_shift_D.svg new file mode 100644 index 0000000..3c824c4 --- /dev/null +++ b/app/images/meters/tacho_shift_D.svg @@ -0,0 +1,67 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_N.svg b/app/images/meters/tacho_shift_N.svg new file mode 100644 index 0000000..3b41db7 --- /dev/null +++ b/app/images/meters/tacho_shift_N.svg @@ -0,0 +1,66 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/meters/tacho_shift_P.svg b/app/images/meters/tacho_shift_P.svg new file mode 100644 index 0000000..3847b14 --- /dev/null +++ b/app/images/meters/tacho_shift_P.svg @@ -0,0 +1,88 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/meters/tacho_shift_R.svg b/app/images/meters/tacho_shift_R.svg new file mode 100644 index 0000000..9007e01 --- /dev/null +++ b/app/images/meters/tacho_shift_R.svg @@ -0,0 +1,70 @@ + + + + + + + + image/svg+xml + + + + + + + diff --git a/app/images/mid/mid_S_normal.svg b/app/images/mid/mid_S_normal.svg new file mode 100644 index 0000000..5aaa6ab --- /dev/null +++ b/app/images/mid/mid_S_normal.svg @@ -0,0 +1,1171 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/mid/mid_other.svg b/app/images/mid/mid_other.svg new file mode 100644 index 0000000..7c5b0ad --- /dev/null +++ b/app/images/mid/mid_other.svg @@ -0,0 +1,123 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/mid/recirc_inter.svg b/app/images/mid/recirc_inter.svg new file mode 100644 index 0000000..64e0ec8 --- /dev/null +++ b/app/images/mid/recirc_inter.svg @@ -0,0 +1,339 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/images/mid/recirc_outer.svg b/app/images/mid/recirc_outer.svg new file mode 100644 index 0000000..bd72e5c --- /dev/null +++ b/app/images/mid/recirc_outer.svg @@ -0,0 +1,339 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/app/main.cpp b/app/main.cpp new file mode 100644 index 0000000..0330858 --- /dev/null +++ b/app/main.cpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION + * Copyright (C) 2016 The Qt Company Ltd. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "camera.h" + +#include + +#ifdef HAVE_LIBHOMESCREEN +#include +#endif +#ifdef HAVE_QLIBWINDOWMANAGER +#include +#endif + +int main(int argc, char *argv[]) +{ + QString myname = QString("tachometer"); + + QGuiApplication app(argc, argv); + app.setApplicationName(myname); + app.setApplicationVersion(QStringLiteral("0.1.0")); + app.setOrganizationDomain(QStringLiteral("automotivelinux.org")); + app.setOrganizationName(QStringLiteral("AutomotiveGradeLinux")); + + QQuickStyle::setStyle("AGL"); + + 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(); + + qmlRegisterType("Camera", 1, 0, "Camera"); + + QQmlApplicationEngine engine; + QQmlContext *context = engine.rootContext(); + QUrl bindingAddress; + int port = 0; + QString secret; + if (positionalArguments.length() == 2) { + port = positionalArguments.takeFirst().toInt(); + secret = positionalArguments.takeFirst(); + bindingAddress.setScheme(QStringLiteral("ws")); + bindingAddress.setHost(QStringLiteral("localhost")); + bindingAddress.setPort(port); + bindingAddress.setPath(QStringLiteral("/api")); + QUrlQuery query; + query.addQueryItem(QStringLiteral("token"), secret); + bindingAddress.setQuery(query); + context->setContextProperty(QStringLiteral("bindingAddress"), bindingAddress); + } else { + context->setContextProperty(QStringLiteral("bindingAddress"), bindingAddress); + } + +#ifdef HAVE_QLIBWINDOWMANAGER + // WindowManager + QLibWindowmanager* qwm = new QLibWindowmanager(); + if(qwm->init(port,secret) != 0){ + exit(EXIT_FAILURE); + } + // Request a surface as described in layers.json windowmanager’s file + if (qwm->requestSurface(myname) != 0) { + exit(EXIT_FAILURE); + } + // Create an event callback against an event type. Here a lambda is called when SyncDraw event occurs + qwm->set_event_handler(QLibWindowmanager::Event_SyncDraw, [qwm, myname](json_object *object) { + fprintf(stderr, "Surface got syncDraw!\n"); + qwm->endDraw(myname); + }); +#endif + +#ifdef HAVE_LIBHOMESCREEN + // HomeScreen + LibHomeScreen* hs = new LibHomeScreen(); + std::string token = secret.toStdString(); + hs->init(port, token.c_str()); + // Set the event handler for Event_TapShortcut which will activate the surface for windowmanager + hs->set_event_handler(LibHomeScreen::Event_TapShortcut, [qwm, myname](json_object *object){ + qwm->activateSurface(myname, "split.main"); + }); +#endif + engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); + + QObject *root = engine.rootObjects().first(); + QQuickWindow *window = qobject_cast(root); +#ifdef HAVE_QLIBWINDOWMANAGER +// QObject::connect(window, SIGNAL(frameSwapped()), qwm, SLOT(slotActivateSurface())); + + qwm->set_event_handler(QLibWindowmanager::Event_Visible, [qwm, root](json_object *object) { + fprintf(stderr, "Surface got Visible!\n"); + QMetaObject::invokeMethod(root, "changeVisible", Q_ARG(QVariant, true)); + }); + + qwm->set_event_handler(QLibWindowmanager::Event_Invisible, [qwm, root](json_object *object) { + fprintf(stderr, "Surface got Invisible!\n"); + QMetaObject::invokeMethod(root, "changeVisible", Q_ARG(QVariant, false)); + }); +#else + window->resize(1280, 720); + window->setVisible(true); +#endif + + return app.exec(); +} diff --git a/app/main.qml b/app/main.qml new file mode 100644 index 0000000..15ce24d --- /dev/null +++ b/app/main.qml @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2017-2019 TOYOTA MOTOR CORPORATION + * + * 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.3 +import QtQuick.Controls 2.0 +import QtQuick.Window 2.2 +import Camera 1.0 +import QtWebSockets 1.0 + +ApplicationWindow { + id: root + width: 1280 + height: 720 + + property string request_str: "" + property string api_str: "low-can" + property var msgid_enu: { "call":2, "retok":3, "reterr":4, "event":5 } + property int recirc:0 + property int vehiclespeed: 0 + property real enginespeed: 0 + property int fuellevel: 0 + property string transmissionMode: 'MT' + property bool isAutoMode: false + property bool isSport: false + property string wshift: "D" + + WebSocket { + id: websocket + url: bindingAddress + + onStatusChanged: { + if (websocket.status === WebSocket.Error){ + console.log ("Error: " + websocket.errorString) + websocket.active = false + countdown.start() + }else if (websocket.status === WebSocket.Open){ + console.log ("Socket Open") + do_subscribe() + }else if (websocket.status === WebSocket.Closed){ + console.log ("Socket closed") + } + } + + onTextMessageReceived: { + var message_json = JSON.parse(message); + + if (message_json[0] === msgid_enu.event){ + var propertyName = message_json[2].event.split("/")[1] + if (propertyName === "messages.vehicle.average.speed"){ + vehiclespeed = message_json[2].data.value + }else if (propertyName === "messages.engine.speed"){ + enginespeed = message_json[2].data.value + }else if ( message.indexOf("messages.fuel.level") > 0 ){ + fuellevel = message_json[2].data.value + }else if (propertyName === "messages.transmission.gearinfo"){ + if (transmissionMode === "MT" && isAutoMode === false){ + if( message_json[2].data.value === 0){ + wshift = 'N' + }else{ + wshift = 'D'+message_json[2].data.value + } + } + }else if (propertyName === "messages.transmission.mode"){ + transmissionMode = message_json[2].data.value + }else if (propertyName === "messages.DriveMode"){ + if( message_json[2].data.value === "sport"){ + wshift = 'S1' + isSport = true + isAutoMode = true + }else if( message_json[2].data.value === "eco"){ + isSport = false + wshift = 'E' + isAutoMode = true + }else if( message_json[2].data.value === "winter"){ + isSport = false + wshift = 'W' + isAutoMode = true + } + }else if ( (propertyName === "messages.transmission.shift.gear") ){ + if (isSport === true){ + if(message_json[2].data.value != '0'){ + wshift = 'S' + message_json[2].data.value + }else if(message_json[2].data.value == '0'){ + wshift = 'D' + } + + } + }else if (propertyName === "messages.Transmission.SiftPosition.neutral"){ + if( message_json[2].data.value === true){ + wshift = 'N' + isAutoMode = true + } + }else if (propertyName === "messages.Transmission.SiftPosition.driving"){ + if( message_json[2].data.value === true){ + wshift = 'D' + isAutoMode = true + } + }else if (propertyName === "messages.Transmission.SiftPosition.parking"){ + if( message_json[2].data.value === true){ + wshift = 'P' + isAutoMode = true + } + }else if (propertyName === "messages.Transmission.SiftPosition.reverse"){ + if( message_json[2].data.value === true){ + wshift = 'R' + isAutoMode = true + } + }else if (propertyName === "messages.Transmission.SiftPosition.B"){ + if( message_json[2].data.value === true){ + wshift = 'B' + isAutoMode = true + } + } + }else if (message_json[0] === msgid_enu.retok){ + console.log ("Response is OK!") + }else{ + console.log ("Event type error:", message_json[0]) + } + } + + active: false + } + + Timer { + id: countdown + repeat: false + interval: 3000 + triggeredOnStart: false + onTriggered: { + websocket.active = true + } + } + + Item { + id: bottomscreen + width: root.width + height: root.height + anchors.bottom: parent.bottom + Image { + width: parent.width + height: parent.height + asynchronous: true + fillMode: Image.TileHorizontally + smooth: true + source: "images/homescreen/homebg_bottom.svg" + } + RowLayout { + id: smtparts + anchors.left: parent.left + anchors.right: parent.right + Speed { + id: speedparts + anchors.left: parent.left + anchors.leftMargin: 10 + anchors.bottom: parent.bottom + anchors.bottomMargin: 30 + width: imgwidth + height: imgheight + } + ColumnLayout { + id: tachoparts + anchors.horizontalCenter: parent.horizontalCenter + Tacho { + anchors.top: parent.top + anchors.topMargin: -40 + anchors.horizontalCenter: parent.horizontalCenter + width: imgwidth + height: imgheight + } + + Item { + id: camarea + anchors.bottom: parent.bottom + anchors.bottomMargin: 80 + anchors.horizontalCenter: parent.horizontalCenter + + width: 320 + height: 180 + + Camera { + id: camdev + width: camarea.width + height: camarea.height + onIsrunningChanged: { + camerabg_up.visible = !isrunning + } + Image { + id: camerabg_up + anchors.centerIn: parent + width: 200 + height: 200 + source: "images/camera/camera_bg.svg" + } + } + Component.onCompleted: { + camdev.enumerateCameras(); + } + } + } + Mid { + id: midparts + anchors.right: parent.right + anchors.rightMargin: 5 + anchors.bottom: parent.bottom + anchors.bottomMargin: 15 + width: imgwidth + height: imgheight + } + } + } + + function changeVisible(visible) { + if (visible){ + if (!websocket.active){ + websocket.active = true + }else{ + do_subscribe() + } + var number = camdev.camranum(); + console.log("tachometer visible is " + visible) + camdev.start(number[0], "30", "640*480") + }else{ + do_subscribe() + console.log("tachometer visible is " + visible) + camdev.stop() + } + } + + function do_call(binding, verb, event_name) { + request_str = '[' + msgid_enu.call + ',"99999","' + binding+'/'+verb + '", {"event":"' + event_name + '"} ]' + websocket.sendTextMessage (request_str) + } + + function do_subscribe() { + do_call(api_str, "subscribe", "vehicle.average.speed") + do_call(api_str, "subscribe", "engine.speed") + do_call(api_str, "subscribe", "fuel.level") + do_call(api_str, "subscribe", "transmission.gearinfo") + do_call(api_str, "subscribe", "transmission.mode") + do_call(api_str, "subscribe", "DriveMode") + do_call(api_str, "subscribe", "transmission.shift.gear") + do_call(api_str, "subscribe", "Transmission.SiftPosition.neutral") + do_call(api_str, "subscribe", "Transmission.SiftPosition.driving") + do_call(api_str, "subscribe", "Transmission.SiftPosition.parking") + do_call(api_str, "subscribe", "Transmission.SiftPosition.reverse") + do_call(api_str, "subscribe", "Transmission.SiftPosition.B") + } + + function do_unsubscribe() { + do_call(api_str, "unsubscribe", "vehicle.average.speed") + do_call(api_str, "unsubscribe", "engine.speed") + do_call(api_str, "unsubscribe", "fuel.level") + do_call(api_str, "unsubscribe", "transmission.gearinfo") + do_call(api_str, "unsubscribe", "transmission.mode") + do_call(api_str, "unsubscribe", "DriveMode") + do_call(api_str, "unsubscribe", "transmission.shift.gear") + do_call(api_str, "unsubscribe", "Transmission.SiftPosition.neutral") + do_call(api_str, "unsubscribe", "Transmission.SiftPosition.driving") + do_call(api_str, "unsubscribe", "Transmission.SiftPosition.parking") + do_call(api_str, "unsubscribe", "Transmission.SiftPosition.reverse") + do_call(api_str, "unsubscribe", "Transmission.SiftPosition.B") + } +} diff --git a/app/main.qrc b/app/main.qrc new file mode 100644 index 0000000..ad91978 --- /dev/null +++ b/app/main.qrc @@ -0,0 +1,9 @@ + + + main.qml + Speed.qml + Mid.qml + Tacho.qml + Shift.qml + + diff --git a/package/config.xml b/package/config.xml new file mode 100644 index 0000000..08fd98c --- /dev/null +++ b/package/config.xml @@ -0,0 +1,20 @@ + + + tachometer + + + This is a demo application + TOYOTA + APL 2.0 + + + + + + + + + + + + diff --git a/package/icon.svg b/package/icon.svg new file mode 100644 index 0000000..0004e6b --- /dev/null +++ b/package/icon.svg @@ -0,0 +1,892 @@ + + + + + + + + image/svg+xml + + + + + + + + + diff --git a/package/package.pro b/package/package.pro new file mode 100644 index 0000000..491a1b0 --- /dev/null +++ b/package/package.pro @@ -0,0 +1,19 @@ + +DISTFILES = icon.svg config.xml + +copy_icon.target = $$OUT_PWD/root/icon.svg +copy_icon.depends = $$_PRO_FILE_PWD_/icon.svg +copy_icon.commands = $(COPY_FILE) \"$$replace(copy_icon.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_icon.target, /, $$QMAKE_DIR_SEP)\" +QMAKE_EXTRA_TARGETS += copy_icon +PRE_TARGETDEPS += $$copy_icon.target + +copy_config.target = $$OUT_PWD/root/config.xml +copy_config.depends = $$_PRO_FILE_PWD_/config.xml +copy_config.commands = $(COPY_FILE) \"$$replace(copy_config.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_config.target, /, $$QMAKE_DIR_SEP)\" +QMAKE_EXTRA_TARGETS += copy_config +PRE_TARGETDEPS += $$copy_config.target + +wgt.target = package +wgt.commands = wgtpkg-pack -f -o tachometer.wgt root + +QMAKE_EXTRA_TARGETS += wgt diff --git a/tachometer.pro b/tachometer.pro new file mode 100644 index 0000000..579a952 --- /dev/null +++ b/tachometer.pro @@ -0,0 +1,3 @@ +TEMPLATE = subdirs +SUBDIRS = app package +package.depends += app -- cgit 1.2.3-korg