diff options
Diffstat (limited to 'CanController')
79 files changed, 5918 insertions, 0 deletions
diff --git a/CanController/Button.qml b/CanController/Button.qml new file mode 100644 index 0000000..01f8a7f --- /dev/null +++ b/CanController/Button.qml @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: buttonMainRect + width: 80 + height: 50 + radius: 5 + border.width: 2 + + property color blinkColor: "#26282a" + property color textBlinkColor: "#d6d6d6" + + // color: (buttonMainRect.blink ? "pink" : "white") + + property alias text: buttonText.text + property alias textColor: buttonText.color + property alias fontPixelSize: buttonText.font.pixelSize + property string icon + property string iconPressed + property bool pressed: false + property bool blink: false + property bool blinkingEnabled: false + property alias mouseEnabled: buttonMouse.enabled + function synchronize() { + blinkTimer.restart() + } + + onPressedChanged: { + if (buttonMainRect.pressed) { + if (buttonMainRect.blinkingEnabled) { + blinkTimer.start() + } else { + buttonMainRect.color = buttonMainRect.blinkColor + buttonText.color = buttonMainRect.textBlinkColor + } + } + else { + if (buttonMainRect.blinkingEnabled) + blinkTimer.stop() + buttonMainRect.color = blinkTimer.baseColor + buttonText.color = blinkTimer.textBaseColor + } + } + + Text { + id: buttonText + anchors.centerIn: parent + visible: !buttonImage.visible + horizontalAlignment: Text.AlignHCenter + font.pixelSize: 14 + color: "#26282a" + } + + Image { + id: buttonImage + visible: (buttonImage.source != "") + anchors.centerIn: parent + source: (buttonMainRect.pressed ? buttonMainRect.iconPressed : buttonMainRect.icon) + } + + MouseArea { + id: buttonMouse + anchors.fill: parent + onClicked: buttonMainRect.pressed = !buttonMainRect.pressed + } + + Timer { + id: blinkTimer + repeat: true + onRunningChanged: { + if (!blinkTimer.running && buttonMainRect.blink) + buttonMainRect.blink = false + } + property color baseColor + property color textBaseColor + Component.onCompleted: { + blinkTimer.baseColor = buttonMainRect.color + blinkTimer.textBaseColor = buttonText.color + } + interval: 300 + onTriggered: { + buttonMainRect.blink = !buttonMainRect.blink + if (buttonMainRect.blink) { + buttonMainRect.color = buttonMainRect.blinkColor + buttonText.color = buttonMainRect.textBlinkColor + } else { + buttonMainRect.color = blinkTimer.baseColor + buttonText.color = blinkTimer.textBaseColor + } + } + } +} diff --git a/CanController/ButtonHolder.qml b/CanController/ButtonHolder.qml new file mode 100644 index 0000000..9959215 --- /dev/null +++ b/CanController/ButtonHolder.qml @@ -0,0 +1,58 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + width: 80 + height: 85 + property alias icon: buttonHolderButton.icon + property alias iconPressed: buttonHolderButton.iconPressed + property alias text: buttonHolderText.text + property alias blinkingEnabled: buttonHolderButton.blinkingEnabled + property alias pressed: buttonHolderButton.pressed + property alias mouseEnabled: buttonHolderButton.mouseEnabled + + function synchronize() { + buttonHolderButton.synchronize() + } + + Button { + id: buttonHolderButton + } + + Text { + id: buttonHolderText + anchors { + top: buttonHolderButton.bottom + topMargin: 7 + horizontalCenter: parent.horizontalCenter + } + font.pixelSize: 12 + } +} diff --git a/CanController/CanController.pro b/CanController/CanController.pro new file mode 100644 index 0000000..bf271bc --- /dev/null +++ b/CanController/CanController.pro @@ -0,0 +1,39 @@ +QT = core gui quick qml +DISTFILES += \ + CarUI.qml \ + Button.qml \ + Slide.qml \ + Blinks.qml \ + Car.qml \ + Gear.qml \ + GearAutomatic.qml \ + ButtonHolder.qml \ + SlideHolder.qml \ + ViewChange.qml + +DEFINES += TCPCLUSTERDATACONNECTION +SOURCES += \ + tcpclusterdatacontrol.cpp +HEADERS += \ + tcpclusterdatacontrol.h + +SOURCES += \ + main.cpp \ + gpssender.cpp \ + nmea.cpp + +HEADERS += \ + clusterdatacontrolinterface.h \ + gpssender.h \ + nmea.h \ + valuetypes.h + +RESOURCES += carui.qrc + +DEFINES += MAIN_QML_FILE_NAME=\\\"qrc:/CarUI.qml\\\" DEFAULT_ROUTE_FILE=\\\":/route.txt\\\" + +TEMPLATE = app +TARGET = carui + +target.path = /data/user/qt/$$TARGET +INSTALLS += target diff --git a/CanController/Car.qml b/CanController/Car.qml new file mode 100644 index 0000000..8036cb2 --- /dev/null +++ b/CanController/Car.qml @@ -0,0 +1,140 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + id: carFrame + + width: electricCar ? carShapeElectric.width : carShape.width + height: electricCar ? carShapeElectric.height : carShape.height + + property bool electricCar: false + + property bool headLight: false + property bool leftBlink: false + property bool rightBlink: false + property bool breakLight: false + + property bool leftFrontDoorOpen: false + property bool leftBackDoorOpen: false + property bool rightFrontDoorOpen: false + property bool rightBackDoorOpen: false + property bool bootDoorOpen: false + property bool hoodDoorOpen: false + + // Sports Car + Image { + id: carShape + visible: !electricCar + source: "qrc:/S-Car_Shape.png" + } + Image { + visible: !electricCar + source: breakLight ? "qrc:/S-Car_BrakesON.png" : "qrc:/S-Car_BrakesOFF.png" + } + Image { + visible: !electricCar + source: leftFrontDoorOpen ? "qrc:/S-Car_DoorLeftON.png" : "qrc:/S-Car_DoorLeftOFF.png" + } + Image { + visible: !electricCar + source: rightFrontDoorOpen ? "qrc:/S-Car_DoorRightON.png" : "qrc:/S-Car_DoorRightOFF.png" + } + Image { + visible: !electricCar + source: hoodDoorOpen ? "qrc:/S-Car_HoodON.png" : "qrc:/S-Car_HoodOFF.png" + } + Image { + visible: !electricCar + source: headLight ? "qrc:/S-Car_LowBeamsON.png" : "qrc:/S-Car_LowBeamsOFF.png" + } + Image { + visible: !electricCar + source: bootDoorOpen ? "qrc:/S-Car_TrunkON.png" : "qrc:/S-Car_TrunkOFF.png" + } + Image { + visible: !electricCar + source: leftBlink ? "qrc:/S-Car_TurnLeftON.png" : "qrc:/S-Car_TurnLeftOFF.png" + } + Image { + visible: !electricCar + source: rightBlink ? "qrc:/S-Car_TurnRightON.png" : "qrc:/S-Car_TurnRightOFF.png" + } + + // Electric Car + Image { + id: carShapeElectric + visible: electricCar + source: "qrc:/E-Car_Shape.png" + } + Image { + visible: electricCar + source: breakLight ? "qrc:/E-Car_BrakesON.png" : "qrc:/E-Car_BrakesOFF.png" + } + Image { + visible: electricCar + source: leftFrontDoorOpen ? "qrc:/E-Car_FrontDoorLeftON.png" + : "qrc:/E-Car_FrontDoorLeftOFF.png" + } + Image { + visible: electricCar + source: rightFrontDoorOpen ? "qrc:/E-Car_FrontDoorRightON.png" + : "qrc:/E-Car_FrontDoorRightOFF.png" + } + Image { + visible: electricCar + source: leftBackDoorOpen ? "qrc:/E-Car_BackDoorLeftON.png" + : "qrc:/E-Car_BackDoorLeftOFF.png" + } + Image { + visible: electricCar + source: rightBackDoorOpen ? "qrc:/E-Car_BackDoorRightON.png" + : "qrc:/E-Car_BackDoorRightOFF.png" + } + Image { + visible: electricCar + source: hoodDoorOpen ? "qrc:/E-Car_HoodON.png" : "qrc:/E-Car_HoodOFF.png" + } + Image { + visible: electricCar + source: headLight ? "qrc:/E-Car_LowBeamsON.png" : "qrc:/E-Car_LowBeamsOFF.png" + } + Image { + visible: electricCar + source: bootDoorOpen ? "qrc:/E-Car_TrunkON.png" : "qrc:/E-Car_TrunkOFF.png" + } + Image { + visible: electricCar + source: leftBlink ? "qrc:/E-Car_TurnLeftON.png" : "qrc:/E-Car_TurnLeftOFF.png" + } + Image { + visible: electricCar + source: rightBlink ? "qrc:/E-Car_TurnRightON.png" : "qrc:/E-Car_TurnRightOFF.png" + } +} diff --git a/CanController/CarUI.qml b/CanController/CarUI.qml new file mode 100644 index 0000000..b948515 --- /dev/null +++ b/CanController/CarUI.qml @@ -0,0 +1,462 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + width: 1024 + height: 768 + + property int carNumber: 2 + + Rectangle { + id: leftBackgroundRect + anchors { + top: parent.top + left: parent.left + bottom: parent.bottom + } + width: 353 + color: "#484950" + + Car { + id: car + anchors { + top: parent.top + topMargin: 20 + horizontalCenter: parent.horizontalCenter + } + + electricCar: carNumber === 0 + headLight: clusterDataControl.headLight + //breakLight: brakeLights.pressed + + leftFrontDoorOpen: clusterDataControl.frontLeftDoorOpen + leftBackDoorOpen: clusterDataControl.rearLeftDoorOpen + rightFrontDoorOpen: clusterDataControl.frontRightDoorOpen + rightBackDoorOpen: clusterDataControl.rearRightDoorOpen + bootDoorOpen: bootDoorButton.pressed//clusterDataControl.trunkOpen + hoodDoorOpen: clusterDataControl.hoodOpen + leftBlink: clusterDataControl.leftTurnLight + rightBlink: clusterDataControl.rightTurnLight + } + + Gear { + id: gearController + visible: carNumber === 1 + gear: 1 + anchors { + top: car.bottom + topMargin: 33 + horizontalCenter: parent.horizontalCenter + } + onGearChanged: clusterDataControl.gear = gearController.gear + } + + GearAutomatic { + id: gearControllerAutomatic + visible: carNumber !== 1 + gear: 1 + anchors { + top: car.bottom + topMargin: 33 + horizontalCenter: parent.horizontalCenter + } + onGearChanged: { + if (gear !== 0 && brakeLights.pressed) + brakeLights.pressed = false + clusterDataControl.gear = gearControllerAutomatic.gear + } + } + + Button { + id: carID + visible: false + anchors { + top: (carNumber === 1) ? gearController.bottom : gearControllerAutomatic.bottom + topMargin: 33 + horizontalCenter: parent.horizontalCenter + } + width: 240 + height: 70 + radius: 6 + color: "#d6d6d6" + textColor: "#26282a" + textBlinkColor: "#26282a" + blinkColor: "#d6d6d6" + fontPixelSize: 23 + text: "Sports Car" + onPressedChanged: { + if (++carNumber > 2) + carNumber = 0 + resetButtonStates() + clusterDataControl.carId = carNumber + if (carNumber === 0) + text = "Electric Car" + else if (carNumber === 1) + text = "Sports Car" + else + text = "Hybrid Car" + } + } + + Button { + id: demoMode + anchors { + top: carID.bottom + topMargin: 10 + horizontalCenter: parent.horizontalCenter + } + width: 240 + height: 35 + radius: 6 + color: "#d6d6d6" + textColor: "#26282a" + textBlinkColor: "#d6d6d6" + blinkColor: "#26282a" + fontPixelSize: 14 + text: "Automatic Demo Mode" + onPressedChanged: { + clusterDataControl.parkLight = demoMode.pressed + } + } + } + + Rectangle { + id: rightBackgroundRect + anchors { + top: parent.top + left: leftBackgroundRect.right + right: parent.right + bottom: parent.bottom + } + width: 353 + color: "#ffffff" + + Grid { + id: buttonGrid + anchors { + top: parent.top + topMargin: 42 + left: parent.left + leftMargin: 42 + right: parent.right + rightMargin: 42 + } + spacing: 10 + + columns: 7 + rows: 3 + + // 1st row + ButtonHolder { + id: leftSignalButton + icon: "qrc:/Icon_TurnLeft_OFF.png" + iconPressed: "qrc:/Icon_TurnLeft_ON.png" + text: "Turn Left" + blinkingEnabled: false + onPressedChanged: { + if (!hazardButton.pressed) { + if (leftSignalButton.pressed && rightSignalButton.pressed) { + rightSignalButton.pressed = false + car.rightBlink = false + } + clusterDataControl.leftTurnLight = leftSignalButton.pressed + car.leftBlink = leftSignalButton.pressed + } + } + mouseEnabled: !hazardButton.pressed + } + ButtonHolder { + id: rightSignalButton + icon: "qrc:/Icon_TurnRight_OFF.png" + iconPressed: "qrc:/Icon_TurnRight_ON.png" + text: "Turn Right" + blinkingEnabled: false + onPressedChanged: { + if (!hazardButton.pressed) { + if (rightSignalButton.pressed && leftSignalButton.pressed) { + leftSignalButton.pressed = false + car.leftBlink = false + } + clusterDataControl.rightTurnLight = rightSignalButton.pressed + car.rightBlink = rightSignalButton.pressed + } + } + mouseEnabled: !hazardButton.pressed + } + ButtonHolder { + id: hazardButton + icon: "qrc:/Icon_HazardWarning_OFF.png" + iconPressed: "qrc:/Icon_HazardWarning_ON.png" + text: "Hazard Warning" + blinkingEnabled: false + property bool leftPreviousState: false + property bool rightPreviousState: false + onPressedChanged: { + clusterDataControl.hazardSignal = hazardButton.pressed + if (hazardButton.pressed) { + if (leftSignalButton.pressed) + hazardButton.leftPreviousState = true + else + leftSignalButton.pressed = true + if (rightSignalButton.pressed) + hazardButton.rightPreviousState = true + else + rightSignalButton.pressed = true + } else { + if (hazardButton.leftPreviousState) + hazardButton.leftPreviousState = false + else + leftSignalButton.pressed = false + if (hazardButton.rightPreviousState) + hazardButton.rightPreviousState = false + else + rightSignalButton.pressed = false + } + car.leftBlink = leftSignalButton.pressed + car.rightBlink = rightSignalButton.pressed + } + } + /* + ButtonHolder { + id: parkLights + text: "Position Lights" + onPressedChanged: clusterDataControl.parkLight = parkLights.pressed + } + */ + ButtonHolder { + id: headLights + icon: "qrc:/Icon_LowBeam_OFF.png" + iconPressed: "qrc:/Icon_LowBeam_ON.png" + text: "Low Beam" + onPressedChanged: clusterDataControl.headLight = headLights.pressed + } + ButtonHolder { + id: lampFailureButton + icon: "qrc:/Icon_BulbFailure_OFF.png" + iconPressed: "qrc:/Icon_BulbFailure_ON.png" + text: "Bulb Failure" + onPressedChanged: clusterDataControl.lightFailure = pressed + } + ButtonHolder { + id: tireFailureButton + text: "Tyre Malfunction" + icon: "qrc:/Icon_TyreMalfunction_OFF.png" + iconPressed: "qrc:/Icon_TyreMalfunction_ON.png" + onPressedChanged: clusterDataControl.flatTire = pressed + } + + // 2nd row + /* + ButtonHolder { + text: "Seat Belt" + } + ButtonHolder { + text: "Tyre Malfunction" + icon: "qrc:/Icon_TyreMalfunction_OFF.png" + iconPressed: "qrc:/Icon_TyreMalfunction_ON.png" + } + ButtonHolder { + text: "Fuel" + } + */ + ButtonHolder { + id: brakeLights + icon: "qrc:/Icon_ParkingBrake_OFF.png" + iconPressed: "qrc:/Icon_ParkingBrake_ON.png" + text: "Parking Brake" + onPressedChanged: { + gearController.gear = 0 + gearControllerAutomatic.gear = 0 + clusterDataControl.brake = brakeLights.pressed + } + } + /* + ButtonHolder { + text: "Coolant Temp." + } + ButtonHolder { + text: "Battery" + } + */ + + // 3rd row + Button { + id: leftFrontDoorButton + height: 60 + text: (carNumber === 0) ? "Left Door\nFRONT" : "Left Door" + onPressedChanged: clusterDataControl.frontLeftDoorOpen = pressed + visible: carNumber !== 2 + } + Button { + id: rightFrontDoorButton + height: 60 + text: (carNumber === 0) ? "Right Door\nFRONT" : "Right Door" + onPressedChanged: clusterDataControl.frontRightDoorOpen = pressed + visible: carNumber !== 2 + } + Button { + id: hoodDoorButton + height: 60 + text: "Hood" + onPressedChanged: clusterDataControl.hoodOpen = pressed + visible: carNumber !== 2 + } + Button { + id: leftBackDoorButton + height: 60 + visible: (carNumber === 0) + text: "Left Door\nBACK" + onPressedChanged: clusterDataControl.rearLeftDoorOpen = pressed + } + Button { + id: rightBackDoorButton + height: 60 + visible: (carNumber === 0) + text: "Right Door\nBACK" + onPressedChanged: clusterDataControl.rearRightDoorOpen = pressed + } + Button { + id: bootDoorButton + height: 60 + text: "Trunk" + onPressedChanged: clusterDataControl.trunkOpen = pressed + visible: carNumber !== 2 + } + } + Row { + id: viewButtons + spacing: 10 + visible: false // Center view changing is not used with automotivedemo + anchors { + top: buttonGrid.bottom + horizontalCenter: parent.horizontalCenter + topMargin: 42 + } + ViewChange { + width: 270 + text: (carNumber === 0) ? "CHANGE LEFT VIEW" : "CHANGE CENTER VIEW" + optionalIcons: carNumber === 2 + } + ViewChange { + visible: carNumber === 0 + text: "CHANGE RIGHT VIEW" + mainView: false + width: 270 + } + } + + Column { + anchors { + top: viewButtons.bottom + topMargin: 42 + left: parent.left + leftMargin: 42 + right: parent.right + rightMargin: 42 + bottom: parent.bottom + bottomMargin: 30 + } + SlideHolder { + id: batteryLevel + text: "BATTERY CHARGE" + max: 100 + steps: 10 + value: 80 + valueStep: 2.5 + onValueChanged: { + // Battery charge vs. battery % level + // 12.66 V = 100 % + // 12.45 V = 75 % + // 12.24 V = 50 % + // 12.06 V = 25 % + // 11.89 V = 0 % + //clusterDataControl.batteryPotential = (11.89 + (0.0077 * batteryLevel.value)) + clusterDataControl.batteryPotential = batteryLevel.value + } + Component.onCompleted: clusterDataControl.batteryPotential = batteryLevel.value + + } + SlideHolder { + id: waterTemperature + text: "COOLANT TEMPERATURE" + visible: carNumber !== 0 + min: 40 + max: 120 + steps: 8 + value: 60 + valueStep: 5 + enabled: !demoMode.pressed + onValueChanged: clusterDataControl.engineTemp = waterTemperature.value + Component.onCompleted: clusterDataControl.engineTemp = waterTemperature.value + } + SlideHolder { + id: gasLevel + text: "FUEL" + visible: carNumber !== 0 + max: 100 + steps: 10 + value: 67 + onValueChanged: clusterDataControl.gasLevel = gasLevel.value + Component.onCompleted: clusterDataControl.gasLevel = gasLevel.value + } + SlideHolder { + id: rpm + visible: carNumber !== 0 + text: "RPM (x1000)" + max: 8.0 + steps: 8 + value: 4.0 + valueStep: 0.01 + enabled: !demoMode.pressed + onValueChanged: clusterDataControl.rpm = rpm.value * 1000 + Component.onCompleted: clusterDataControl.rpm = rpm.value * 1000 + } + } + } + + function resetButtonStates() { + headLights.pressed = false + brakeLights.pressed = false + //oilPressureWarning.pressed = false + leftFrontDoorButton.pressed = false + rightFrontDoorButton.pressed = false + leftBackDoorButton.pressed = false + rightBackDoorButton.pressed = false + bootDoorButton.pressed = false + hoodDoorButton.pressed = false + tireFailureButton.pressed = false + lampFailureButton.pressed = false + leftSignalButton.pressed = false + rightSignalButton.pressed = false + hazardButton.pressed = false + gearController.gear = 1 + gearControllerAutomatic.gear = 1 + } +} diff --git a/CanController/CenterViewOff.png b/CanController/CenterViewOff.png Binary files differnew file mode 100644 index 0000000..f4b6b62 --- /dev/null +++ b/CanController/CenterViewOff.png diff --git a/CanController/CenterViewOffOpt.png b/CanController/CenterViewOffOpt.png Binary files differnew file mode 100644 index 0000000..19f2d55 --- /dev/null +++ b/CanController/CenterViewOffOpt.png diff --git a/CanController/CenterViewOn.png b/CanController/CenterViewOn.png Binary files differnew file mode 100644 index 0000000..eca718f --- /dev/null +++ b/CanController/CenterViewOn.png diff --git a/CanController/CenterViewOnOpt.png b/CanController/CenterViewOnOpt.png Binary files differnew file mode 100644 index 0000000..95ca235 --- /dev/null +++ b/CanController/CenterViewOnOpt.png diff --git a/CanController/E-Car_BackDoorLeftOFF.png b/CanController/E-Car_BackDoorLeftOFF.png Binary files differnew file mode 100644 index 0000000..7ad393a --- /dev/null +++ b/CanController/E-Car_BackDoorLeftOFF.png diff --git a/CanController/E-Car_BackDoorLeftON.png b/CanController/E-Car_BackDoorLeftON.png Binary files differnew file mode 100644 index 0000000..096f459 --- /dev/null +++ b/CanController/E-Car_BackDoorLeftON.png diff --git a/CanController/E-Car_BackDoorRightOFF.png b/CanController/E-Car_BackDoorRightOFF.png Binary files differnew file mode 100644 index 0000000..a0b711b --- /dev/null +++ b/CanController/E-Car_BackDoorRightOFF.png diff --git a/CanController/E-Car_BackDoorRightON.png b/CanController/E-Car_BackDoorRightON.png Binary files differnew file mode 100644 index 0000000..52927be --- /dev/null +++ b/CanController/E-Car_BackDoorRightON.png diff --git a/CanController/E-Car_BrakesOFF.png b/CanController/E-Car_BrakesOFF.png Binary files differnew file mode 100644 index 0000000..ff98a39 --- /dev/null +++ b/CanController/E-Car_BrakesOFF.png diff --git a/CanController/E-Car_BrakesON.png b/CanController/E-Car_BrakesON.png Binary files differnew file mode 100644 index 0000000..7518ea6 --- /dev/null +++ b/CanController/E-Car_BrakesON.png diff --git a/CanController/E-Car_FrontDoorLeftOFF.png b/CanController/E-Car_FrontDoorLeftOFF.png Binary files differnew file mode 100644 index 0000000..7e8f8b8 --- /dev/null +++ b/CanController/E-Car_FrontDoorLeftOFF.png diff --git a/CanController/E-Car_FrontDoorLeftON.png b/CanController/E-Car_FrontDoorLeftON.png Binary files differnew file mode 100644 index 0000000..18673ba --- /dev/null +++ b/CanController/E-Car_FrontDoorLeftON.png diff --git a/CanController/E-Car_FrontDoorRightOFF.png b/CanController/E-Car_FrontDoorRightOFF.png Binary files differnew file mode 100644 index 0000000..ce674c9 --- /dev/null +++ b/CanController/E-Car_FrontDoorRightOFF.png diff --git a/CanController/E-Car_FrontDoorRightON.png b/CanController/E-Car_FrontDoorRightON.png Binary files differnew file mode 100644 index 0000000..f72ce13 --- /dev/null +++ b/CanController/E-Car_FrontDoorRightON.png diff --git a/CanController/E-Car_HoodOFF.png b/CanController/E-Car_HoodOFF.png Binary files differnew file mode 100644 index 0000000..908c207 --- /dev/null +++ b/CanController/E-Car_HoodOFF.png diff --git a/CanController/E-Car_HoodON.png b/CanController/E-Car_HoodON.png Binary files differnew file mode 100644 index 0000000..ccbb2e6 --- /dev/null +++ b/CanController/E-Car_HoodON.png diff --git a/CanController/E-Car_LowBeamsOFF.png b/CanController/E-Car_LowBeamsOFF.png Binary files differnew file mode 100644 index 0000000..510ed40 --- /dev/null +++ b/CanController/E-Car_LowBeamsOFF.png diff --git a/CanController/E-Car_LowBeamsON.png b/CanController/E-Car_LowBeamsON.png Binary files differnew file mode 100644 index 0000000..5c23423 --- /dev/null +++ b/CanController/E-Car_LowBeamsON.png diff --git a/CanController/E-Car_Shape.png b/CanController/E-Car_Shape.png Binary files differnew file mode 100644 index 0000000..a2e49a7 --- /dev/null +++ b/CanController/E-Car_Shape.png diff --git a/CanController/E-Car_TrunkOFF.png b/CanController/E-Car_TrunkOFF.png Binary files differnew file mode 100644 index 0000000..3aa9082 --- /dev/null +++ b/CanController/E-Car_TrunkOFF.png diff --git a/CanController/E-Car_TrunkON.png b/CanController/E-Car_TrunkON.png Binary files differnew file mode 100644 index 0000000..1dd8e40 --- /dev/null +++ b/CanController/E-Car_TrunkON.png diff --git a/CanController/E-Car_TurnLeftOFF.png b/CanController/E-Car_TurnLeftOFF.png Binary files differnew file mode 100644 index 0000000..4496fee --- /dev/null +++ b/CanController/E-Car_TurnLeftOFF.png diff --git a/CanController/E-Car_TurnLeftON.png b/CanController/E-Car_TurnLeftON.png Binary files differnew file mode 100644 index 0000000..5535a71 --- /dev/null +++ b/CanController/E-Car_TurnLeftON.png diff --git a/CanController/E-Car_TurnRightOFF.png b/CanController/E-Car_TurnRightOFF.png Binary files differnew file mode 100644 index 0000000..a0feea1 --- /dev/null +++ b/CanController/E-Car_TurnRightOFF.png diff --git a/CanController/E-Car_TurnRightON.png b/CanController/E-Car_TurnRightON.png Binary files differnew file mode 100644 index 0000000..5bc7e21 --- /dev/null +++ b/CanController/E-Car_TurnRightON.png diff --git a/CanController/Gear.qml b/CanController/Gear.qml new file mode 100644 index 0000000..0a3a732 --- /dev/null +++ b/CanController/Gear.qml @@ -0,0 +1,455 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: gearMain + width: 270 + height: 270 + radius: 135 + color: "#1b1c1d" + + property int gear: 0 + property int previousGear: 0 + + property bool animating: false + property alias knobColor: knob.color + property color trackColor: "#b6181e" + property color unselectecColor: "#ffffff" + property color selectecColor: "#1b1c1d" + + onGearChanged: { + if (gearMain.animating || gearMain.gear < -1 || gearMain.gear > 5) { + gearMain.gear = gearMain.previousGear + } + else { + if (gearMain.previousGear === 0) { + if (gearMain.gear === 1) from0to1.start() + else if (gearMain.gear === 2) from0to2.start() + else if (gearMain.gear === 3) from0to3.start() + else if (gearMain.gear === 4) from0to4.start() + else if (gearMain.gear === 5) from0to5.start() + else if (gearMain.gear === -1) from0toR.start() + } + else if (gearMain.previousGear === 1) from1to0.start() + else if (gearMain.previousGear === 2) from2to0.start() + else if (gearMain.previousGear === 3) from3to0.start() + else if (gearMain.previousGear === 4) from4to0.start() + else if (gearMain.previousGear === 5) from5to0.start() + else if (gearMain.previousGear === -1) fromRto0.start() + gearMain.previousGear = gearMain.gear + } + } + + Rectangle { + id: verticalLine + anchors.centerIn: parent + width: 126 + height: 6 + color: gearMain.trackColor + } + + Rectangle { + id: leftHorizontalLine + anchors { + left: verticalLine.left + verticalCenter: parent.verticalCenter + } + width: 6 + height: 70 + color: gearMain.trackColor + } + + Rectangle { + id: middleHorizontalLine + anchors.centerIn: parent + width: 6 + height: 70 + color: gearMain.trackColor + } + + Rectangle { + id: rightHorizontalLine + anchors { + right: verticalLine.right + verticalCenter: parent.verticalCenter + } + width: 6 + height: 70 + color: gearMain.trackColor + } + + Rectangle { + id: knob + width: 50 + height: 50 + radius: 25 + color: "#b6181e" + property int middleX: 110 + property int middleY: 110 + property int leftX: 50 + property int rightX: 170 + property int topY: 50 + property int bottomY: 170 + x: knob.middleX + y: knob.middleY + + SequentialAnimation { + id: from0to1 + PropertyAnimation { target: knob; property: "x"; from: knob.middleX; to: knob.leftX; } + PropertyAnimation { target: knob; property: "y"; from: knob.middleY; to: knob.topY; } + onRunningChanged: gearMain.animating = from0to1.running; + } + SequentialAnimation { + id: from0to2 + PropertyAnimation { target: knob; property: "x"; from: knob.middleX; to: knob.leftX; } + PropertyAnimation { target: knob; property: "y"; from: knob.middleY; to: knob.bottomY; } + onRunningChanged: gearMain.animating = from0to2.running; + } + PropertyAnimation { + id: from0to3 + target: knob + property: "y" + from: knob.middleY + to: knob.topY + onRunningChanged: gearMain.animating = from0to3.running + } + PropertyAnimation { + id: from0to4 + target: knob + property: "y" + from: knob.middleY + to: knob.bottomY + onRunningChanged: gearMain.animating = from0to4.running + } + SequentialAnimation { + id: from0to5 + PropertyAnimation { target: knob; property: "x"; from: knob.middleX; to: knob.rightX; } + PropertyAnimation { target: knob; property: "y"; from: knob.middleY; to: knob.topY; } + onRunningChanged: gearMain.animating = from0to5.running + } + SequentialAnimation { + id: from0toR + PropertyAnimation { target: knob; property: "x"; from: knob.middleX; to: knob.rightX; } + PropertyAnimation { target: knob; property: "y"; from: knob.middleY; to: knob.bottomY; } + onRunningChanged: gearMain.animating = from0toR.running + } + SequentialAnimation { + id: from1to0 + PropertyAnimation { target: knob; property: "y"; from: knob.topY; to: knob.middleY; } + PropertyAnimation { target: knob; property: "x"; from: knob.leftX; to: knob.middleX; } + onRunningChanged: { + if (!from1to0.running) { + if (gearMain.gear === 2) from0to2.start() + else if (gearMain.gear === 3) from0to3.start() + else if (gearMain.gear === 4) from0to4.start() + else if (gearMain.gear === 5) from0to5.start() + else if (gearMain.gear === -1) from0toR.start() + else gearMain.animating = false + } + else { + gearMain.animating = true + } + } + } + SequentialAnimation { + id: from2to0 + PropertyAnimation { target: knob; property: "y"; from: knob.bottomY; to: knob.middleY; } + PropertyAnimation { target: knob; property: "x"; from: knob.leftX; to: knob.middleX; } + onRunningChanged: { + if (!from2to0.running) { + if (gearMain.gear === 1) from0to1.start() + else if (gearMain.gear === 3) from0to3.start() + else if (gearMain.gear === 4) from0to4.start() + else if (gearMain.gear === 5) from0to5.start() + else if (gearMain.gear === -1) from0toR.start() + else gearMain.animating = false + } + else { + gearMain.animating = true + } + } + } + PropertyAnimation { + id: from3to0 + target: knob + property: "y" + from: knob.topY + to: knob.middleY + onRunningChanged: { + if (!from3to0.running) { + if (gearMain.gear === -1) from0toR.start() + else if (gearMain.gear === 1) from0to1.start() + else if (gearMain.gear === 2) from0to2.start() + else if (gearMain.gear === 4) from0to4.start() + else if (gearMain.gear === 5) from0to5.start() + else gearMain.animating = false + } + else { + gearMain.animating = true + } + } + } + PropertyAnimation { + id: from4to0 + target: knob + property: "y" + from: knob.bottomY + to: knob.middleY + onRunningChanged: { + if (!from4to0.running) { + if (gearMain.gear === 1) from0to1.start() + else if (gearMain.gear === 2) from0to2.start() + else if (gearMain.gear === 3) from0to3.start() + else if (gearMain.gear === 5) from0to5.start() + else if (gearMain.gear === -1) from0toR.start() + else gearMain.animating = false + } + else { + gearMain.animating = true + } + } + } + SequentialAnimation { + id: from5to0 + PropertyAnimation { target: knob; property: "y"; from: knob.topY; to: knob.middleY; } + PropertyAnimation { target: knob; property: "x"; from: knob.rightX; to: knob.middleX; } + onRunningChanged: { + if (!from5to0.running) { + if (gearMain.gear === 1) from0to1.start() + else if (gearMain.gear === 2) from0to2.start() + else if (gearMain.gear === 3) from0to3.start() + else if (gearMain.gear === 4) from0to4.start() + else if (gearMain.gear === -1) from0toR.start() + else gearMain.animating = false + } + else { + gearMain.animating = true + } + } + } + SequentialAnimation { + id: fromRto0 + PropertyAnimation { target: knob; property: "y"; from: knob.bottomY; to: knob.middleY; } + PropertyAnimation { target: knob; property: "x"; from: knob.rightX; to: knob.middleX; } + onRunningChanged: { + if (!fromRto0.running) { + if (gearMain.gear === 1) from0to1.start() + else if (gearMain.gear === 2) from0to2.start() + else if (gearMain.gear === 3) from0to3.start() + else if (gearMain.gear === 4) from0to4.start() + else if (gearMain.gear === 5) from0to5.start() + else gearMain.animating = false + } + else { + gearMain.animating = true + } + } + } + } + + Item { + anchors { + bottom: leftHorizontalLine.top + horizontalCenter: leftHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: text1 + anchors.centerIn: parent + font.pixelSize: 30 + text: "1" + color: (!gearMain.animating && gearMain.gear === 1 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + + Item { + anchors { + top: leftHorizontalLine.bottom + horizontalCenter: leftHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: text2 + anchors.centerIn: parent + font.pixelSize: 30 + text: "2" + color: (!gearMain.animating && gearMain.gear === 2 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + Item { + anchors { + bottom: middleHorizontalLine.top + horizontalCenter: middleHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: text3 + anchors.centerIn: parent + font.pixelSize: 30 + text: "3" + color: (!gearMain.animating && gearMain.gear === 3 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + Item { + anchors { + top: middleHorizontalLine.bottom + horizontalCenter: middleHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: text4 + anchors.centerIn: parent + font.pixelSize: 30 + text: "4" + color: (!gearMain.animating && gearMain.gear === 4 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + Item { + anchors { + bottom: rightHorizontalLine.top + horizontalCenter: rightHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: text5 + anchors.centerIn: parent + font.pixelSize: 30 + text: "5" + color: (!gearMain.animating && gearMain.gear === 5 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + Item { + anchors { + top: rightHorizontalLine.bottom + horizontalCenter: rightHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: textR + anchors.centerIn: parent + font.pixelSize: 30 + text: "R" + color: (!gearMain.animating && gearMain.gear === -1 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + + Rectangle { + anchors.centerIn: parent + width: 32 + height: 32 + radius: 16 + color: gearMain.trackColor + Rectangle { + anchors.centerIn: parent + width: 28 + height: 28 + radius: 14 + color: (!gearMain.animating && gearMain.gear === 0 ? gearMain.unselectecColor + : gearMain.selectecColor) + Text { + anchors.centerIn: parent + font.pixelSize: 20 + text: "N" + color: (!gearMain.animating && gearMain.gear === 0 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + } + + MouseArea { + x: 0 + y: 0 + width: 105 + height: 135 + enabled: !gearMain.animating + onClicked: gearMain.gear = 1 + } + MouseArea { + x: 105 + y: 0 + width: 60 + height: 105 + enabled: !gearMain.animating + onClicked: gearMain.gear = 3 + } + MouseArea { + x: 165 + y: 0 + width: 105 + height: 135 + enabled: !gearMain.animating + onClicked: gearMain.gear = 5 + } + MouseArea { + x: 0 + y: 135 + width: 105 + height: 135 + enabled: !gearMain.animating + onClicked: gearMain.gear = 2 + } + MouseArea { + x: 105 + y: 165 + width: 60 + height: 105 + enabled: !gearMain.animating + onClicked: gearMain.gear = 4 + } + MouseArea { + x: 165 + y: 135 + width: 105 + height: 135 + enabled: !gearMain.animating + onClicked: gearMain.gear = -1 + } + MouseArea { + x: 105 + y: 105 + width: 60 + height: 60 + enabled: !gearMain.animating + onClicked: gearMain.gear = 0 + } + +} diff --git a/CanController/GearAutomatic.qml b/CanController/GearAutomatic.qml new file mode 100644 index 0000000..70b6ea1 --- /dev/null +++ b/CanController/GearAutomatic.qml @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle { + id: gearMain + width: 270 + height: 270 + radius: 135 + color: "#1b1c1d" + + property int gear: 0 + property int previousGear: 0 + + property bool animating: false + property alias knobColor: knob.color + property color trackColor: "#b6181e" + property color unselectecColor: "#ffffff" + property color selectecColor: "#1b1c1d" + + onGearChanged: { + if (gearMain.animating || gearMain.gear < -1 || gearMain.gear > 1) { + gearMain.gear = gearMain.previousGear + } else { + if (gearMain.previousGear === 0) { + if (gearMain.gear === 1) + from0to1.start() + else if (gearMain.gear === -1) + from0toR.start() + } else if (gearMain.previousGear === 1) { + from1to0.start() + } else if (gearMain.previousGear === -1) { + fromRto0.start() + } + gearMain.previousGear = gearMain.gear + } + } + + Rectangle { + id: verticalLine + anchors.centerIn: parent + width: 126 + height: 6 + color: gearMain.trackColor + } + + Rectangle { + id: leftHorizontalLine + anchors { + left: verticalLine.left + bottom: parent.verticalCenter + } + width: 6 + height: 35 + color: gearMain.trackColor + } + + Rectangle { + id: rightHorizontalLine + anchors { + right: verticalLine.right + top: parent.verticalCenter + } + width: 6 + height: 35 + color: gearMain.trackColor + } + + Rectangle { + id: knob + width: 50 + height: 50 + radius: 25 + color: "#b6181e" + property int middleX: 110 + property int middleY: 110 + property int leftX: 50 + property int rightX: 170 + property int topY: 50 + property int bottomY: 170 + x: knob.middleX + y: knob.middleY + + SequentialAnimation { + id: from0to1 + PropertyAnimation { target: knob; property: "x"; from: knob.middleX; to: knob.leftX; } + PropertyAnimation { target: knob; property: "y"; from: knob.middleY; to: knob.topY; } + onRunningChanged: gearMain.animating = from0to1.running + } + SequentialAnimation { + id: from0toR + PropertyAnimation { target: knob; property: "x"; from: knob.middleX; to: knob.rightX; } + PropertyAnimation { target: knob; property: "y"; from: knob.middleY; to: knob.bottomY; } + onRunningChanged: gearMain.animating = from0toR.running + } + SequentialAnimation { + id: from1to0 + PropertyAnimation { target: knob; property: "y"; from: knob.topY; to: knob.middleY; } + PropertyAnimation { target: knob; property: "x"; from: knob.leftX; to: knob.middleX; } + onRunningChanged: { + if (!from1to0.running) { + if (gearMain.gear === -1) + from0toR.start() + else + gearMain.animating = false + } else { + gearMain.animating = true + } + } + } + SequentialAnimation { + id: fromRto0 + PropertyAnimation { target: knob; property: "y"; from: knob.bottomY; to: knob.middleY; } + PropertyAnimation { target: knob; property: "x"; from: knob.rightX; to: knob.middleX; } + onRunningChanged: { + if (!fromRto0.running) { + if (gearMain.gear === 1) + from0to1.start() + else + gearMain.animating = false + } else { + gearMain.animating = true + } + } + } + } + + Item { + anchors { + bottom: leftHorizontalLine.top + horizontalCenter: leftHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: text1 + anchors.centerIn: parent + font.pixelSize: 30 + text: "D" + color: (!gearMain.animating && gearMain.gear === 1 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + + Item { + anchors { + top: rightHorizontalLine.bottom + horizontalCenter: rightHorizontalLine.horizontalCenter + } + width: 50 + height: 50 + Text { + id: textR + anchors.centerIn: parent + font.pixelSize: 30 + text: "R" + color: (!gearMain.animating && gearMain.gear === -1 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + + Rectangle { + anchors.centerIn: parent + width: 32 + height: 32 + radius: 16 + color: gearMain.trackColor + Rectangle { + anchors.centerIn: parent + width: 28 + height: 28 + radius: 14 + color: (!gearMain.animating && gearMain.gear === 0 ? gearMain.unselectecColor + : gearMain.selectecColor) + Text { + anchors.centerIn: parent + font.pixelSize: 20 + text: "N" + color: (!gearMain.animating && gearMain.gear === 0 ? gearMain.selectecColor + : gearMain.unselectecColor) + } + } + } + + MouseArea { + x: 0 + y: 0 + width: 105 + height: 135 + enabled: !gearMain.animating + onClicked: gearMain.gear = 1 + } + MouseArea { + x: 165 + y: 135 + width: 105 + height: 135 + enabled: !gearMain.animating + onClicked: gearMain.gear = -1 + } + MouseArea { + x: 105 + y: 105 + width: 60 + height: 60 + enabled: !gearMain.animating + onClicked: gearMain.gear = 0 + } + +} diff --git a/CanController/Icon_BulbFailure_OFF.png b/CanController/Icon_BulbFailure_OFF.png Binary files differnew file mode 100644 index 0000000..1ff0fef --- /dev/null +++ b/CanController/Icon_BulbFailure_OFF.png diff --git a/CanController/Icon_BulbFailure_ON.png b/CanController/Icon_BulbFailure_ON.png Binary files differnew file mode 100644 index 0000000..cd083cd --- /dev/null +++ b/CanController/Icon_BulbFailure_ON.png diff --git a/CanController/Icon_HazardWarning_OFF.png b/CanController/Icon_HazardWarning_OFF.png Binary files differnew file mode 100644 index 0000000..88477d2 --- /dev/null +++ b/CanController/Icon_HazardWarning_OFF.png diff --git a/CanController/Icon_HazardWarning_ON.png b/CanController/Icon_HazardWarning_ON.png Binary files differnew file mode 100644 index 0000000..95e5dab --- /dev/null +++ b/CanController/Icon_HazardWarning_ON.png diff --git a/CanController/Icon_LowBeam_OFF.png b/CanController/Icon_LowBeam_OFF.png Binary files differnew file mode 100644 index 0000000..411682a --- /dev/null +++ b/CanController/Icon_LowBeam_OFF.png diff --git a/CanController/Icon_LowBeam_ON.png b/CanController/Icon_LowBeam_ON.png Binary files differnew file mode 100644 index 0000000..d5e9188 --- /dev/null +++ b/CanController/Icon_LowBeam_ON.png diff --git a/CanController/Icon_ParkingBrake_OFF.png b/CanController/Icon_ParkingBrake_OFF.png Binary files differnew file mode 100644 index 0000000..6819d87 --- /dev/null +++ b/CanController/Icon_ParkingBrake_OFF.png diff --git a/CanController/Icon_ParkingBrake_ON.png b/CanController/Icon_ParkingBrake_ON.png Binary files differnew file mode 100644 index 0000000..dfe7ab5 --- /dev/null +++ b/CanController/Icon_ParkingBrake_ON.png diff --git a/CanController/Icon_TurnLeft_OFF.png b/CanController/Icon_TurnLeft_OFF.png Binary files differnew file mode 100644 index 0000000..eb19b74 --- /dev/null +++ b/CanController/Icon_TurnLeft_OFF.png diff --git a/CanController/Icon_TurnLeft_ON.png b/CanController/Icon_TurnLeft_ON.png Binary files differnew file mode 100644 index 0000000..8a47ee6 --- /dev/null +++ b/CanController/Icon_TurnLeft_ON.png diff --git a/CanController/Icon_TurnRight_OFF.png b/CanController/Icon_TurnRight_OFF.png Binary files differnew file mode 100644 index 0000000..5ba8141 --- /dev/null +++ b/CanController/Icon_TurnRight_OFF.png diff --git a/CanController/Icon_TurnRight_ON.png b/CanController/Icon_TurnRight_ON.png Binary files differnew file mode 100644 index 0000000..9803e1a --- /dev/null +++ b/CanController/Icon_TurnRight_ON.png diff --git a/CanController/Icon_TyreMalfunction_OFF.png b/CanController/Icon_TyreMalfunction_OFF.png Binary files differnew file mode 100644 index 0000000..90dbf9a --- /dev/null +++ b/CanController/Icon_TyreMalfunction_OFF.png diff --git a/CanController/Icon_TyreMalfunction_ON.png b/CanController/Icon_TyreMalfunction_ON.png Binary files differnew file mode 100644 index 0000000..59459cb --- /dev/null +++ b/CanController/Icon_TyreMalfunction_ON.png diff --git a/CanController/S-Car_BrakesOFF.png b/CanController/S-Car_BrakesOFF.png Binary files differnew file mode 100644 index 0000000..c485aae --- /dev/null +++ b/CanController/S-Car_BrakesOFF.png diff --git a/CanController/S-Car_BrakesON.png b/CanController/S-Car_BrakesON.png Binary files differnew file mode 100644 index 0000000..bdb3198 --- /dev/null +++ b/CanController/S-Car_BrakesON.png diff --git a/CanController/S-Car_DoorLeftOFF.png b/CanController/S-Car_DoorLeftOFF.png Binary files differnew file mode 100644 index 0000000..1c29d02 --- /dev/null +++ b/CanController/S-Car_DoorLeftOFF.png diff --git a/CanController/S-Car_DoorLeftON.png b/CanController/S-Car_DoorLeftON.png Binary files differnew file mode 100644 index 0000000..d2c66cb --- /dev/null +++ b/CanController/S-Car_DoorLeftON.png diff --git a/CanController/S-Car_DoorRightOFF.png b/CanController/S-Car_DoorRightOFF.png Binary files differnew file mode 100644 index 0000000..3da124e --- /dev/null +++ b/CanController/S-Car_DoorRightOFF.png diff --git a/CanController/S-Car_DoorRightON.png b/CanController/S-Car_DoorRightON.png Binary files differnew file mode 100644 index 0000000..43488a7 --- /dev/null +++ b/CanController/S-Car_DoorRightON.png diff --git a/CanController/S-Car_HoodOFF.png b/CanController/S-Car_HoodOFF.png Binary files differnew file mode 100644 index 0000000..3b768a0 --- /dev/null +++ b/CanController/S-Car_HoodOFF.png diff --git a/CanController/S-Car_HoodON.png b/CanController/S-Car_HoodON.png Binary files differnew file mode 100644 index 0000000..307bd56 --- /dev/null +++ b/CanController/S-Car_HoodON.png diff --git a/CanController/S-Car_LowBeamsOFF.png b/CanController/S-Car_LowBeamsOFF.png Binary files differnew file mode 100644 index 0000000..4391898 --- /dev/null +++ b/CanController/S-Car_LowBeamsOFF.png diff --git a/CanController/S-Car_LowBeamsON.png b/CanController/S-Car_LowBeamsON.png Binary files differnew file mode 100644 index 0000000..8873915 --- /dev/null +++ b/CanController/S-Car_LowBeamsON.png diff --git a/CanController/S-Car_Shape.png b/CanController/S-Car_Shape.png Binary files differnew file mode 100644 index 0000000..a17a926 --- /dev/null +++ b/CanController/S-Car_Shape.png diff --git a/CanController/S-Car_TrunkOFF.png b/CanController/S-Car_TrunkOFF.png Binary files differnew file mode 100644 index 0000000..dd05e39 --- /dev/null +++ b/CanController/S-Car_TrunkOFF.png diff --git a/CanController/S-Car_TrunkON.png b/CanController/S-Car_TrunkON.png Binary files differnew file mode 100644 index 0000000..e7c4ecc --- /dev/null +++ b/CanController/S-Car_TrunkON.png diff --git a/CanController/S-Car_TurnLeftOFF.png b/CanController/S-Car_TurnLeftOFF.png Binary files differnew file mode 100644 index 0000000..8f2ae29 --- /dev/null +++ b/CanController/S-Car_TurnLeftOFF.png diff --git a/CanController/S-Car_TurnLeftON.png b/CanController/S-Car_TurnLeftON.png Binary files differnew file mode 100644 index 0000000..b3fa4cc --- /dev/null +++ b/CanController/S-Car_TurnLeftON.png diff --git a/CanController/S-Car_TurnRightOFF.png b/CanController/S-Car_TurnRightOFF.png Binary files differnew file mode 100644 index 0000000..b6610d7 --- /dev/null +++ b/CanController/S-Car_TurnRightOFF.png diff --git a/CanController/S-Car_TurnRightON.png b/CanController/S-Car_TurnRightON.png Binary files differnew file mode 100644 index 0000000..e009bc2 --- /dev/null +++ b/CanController/S-Car_TurnRightON.png diff --git a/CanController/Slide.qml b/CanController/Slide.qml new file mode 100644 index 0000000..e23a018 --- /dev/null +++ b/CanController/Slide.qml @@ -0,0 +1,163 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +import QtQuick 2.0 + +Item { + id: mainSlide + width: 500 + height: 80 + + property real min: 0 + property real value: min + property real max: 100 + property int steps: 10 + property real valueStep: 5 + property color sliderColor: enabled ? "#b6181e" : "lightGray" + + Rectangle { + id: slideRail + anchors { + top: parent.top + topMargin: 40 + left: parent.left + leftMargin: 5 + right: parent.right + rightMargin: 5 + } + height: 4 + color: "#d6d6d6" + property int railStep: ((mainSlide.max - mainSlide.min) / mainSlide.steps) + Repeater { + model: (mainSlide.steps + 1) + anchors.bottom: parent.bottom + Item { + x: index * width - 0.5 * width + y: -6 + width: (slideRail.width / mainSlide.steps) + height: 30 + Rectangle { + id: slideIndex + anchors.horizontalCenter: parent.horizontalCenter + width: 3 + height: 10 + //radius: 3 + color: (mainSlide.value >= (mainSlide.min + (index * slideRail.railStep)) + ? sliderColor : "#d6d6d6") + } + Text { + anchors { + bottom: slideIndex.bottom + bottomMargin: 25 + horizontalCenter: parent.horizontalCenter + } + color: (mainSlide.value >= (mainSlide.min + (index * slideRail.railStep)) + ? sliderColor : "#d6d6d6") + font.pixelSize: 12 + text: mainSlide.min + (index * slideRail.railStep) + } + } + } + } + MouseArea { + anchors.fill: parent + onClicked: { + slideMouse.changeX = true + if (mouse.x <= slideRail.x) + hiddenSlider.x = (slideRail.x - (0.5 * hiddenSlider.width)) + else if (mouse.x >= slideRail.x + slideRail.width) + hiddenSlider.x = (slideRail.x + slideRail.width - (0.5 * hiddenSlider.width)) + else + hiddenSlider.x = (mouse.x - (0.5 * hiddenSlider.width)) + slideMouse.changeX = false + } + } + Rectangle { + id: slideValue + anchors { + top: slideRail.top + left: slideRail.left + right: slider.right + rightMargin: 1 + } + radius: 5 + height: 4 + color: sliderColor + } + + function calculateSliderPosition() { + slider.x = (slideRail.x - (0.5 * slider.width) + + (((Math.min(Math.max(mainSlide.value, mainSlide.min), mainSlide.max) + - mainSlide.min) / (mainSlide.max - mainSlide.min)) * slideRail.width)) + } + + onValueChanged: { + mainSlide.calculateSliderPosition() + } + + Item { + id: hiddenSlider + width: 60 + height: parent.height + onXChanged: { + var tempValue = (mainSlide.min + (((hiddenSlider.x - slideRail.x + + (0.5 * hiddenSlider.width)) / slideRail.width) + * (mainSlide.max - mainSlide.min))) + var tempStep = (tempValue % mainSlide.valueStep) + mainSlide.value = tempValue - tempStep + + (tempStep < (0.5 * mainSlide.valueStep) ? 0 : mainSlide.valueStep) + } + MouseArea { + id: slideMouse + anchors.fill: parent + property bool changeX: false + drag { + target: hiddenSlider + axis: Drag.XAxis + minimumX : (slideRail.x - (0.5 * hiddenSlider.width)) + maximumX: (slideRail.x + slideRail.width - (0.5 * hiddenSlider.width)) + onActiveChanged: slideMouse.changeX = slideMouse.drag.active + } + } + } + + Rectangle { + id: slider + Component.onCompleted: mainSlide.calculateSliderPosition() + anchors { + top: parent.top + topMargin: 22 + } + + width: 16 + height: 40 + radius: 8 + color: sliderColor + } +} diff --git a/CanController/SlideHolder.qml b/CanController/SlideHolder.qml new file mode 100644 index 0000000..394122e --- /dev/null +++ b/CanController/SlideHolder.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Item { + width: parent.width + height: (0.25 * parent.height) + property alias text: sliderText.text + property alias max: slide.max + property alias min: slide.min + property alias steps: slide.steps + property alias value: slide.value + property alias valueStep: slide.valueStep + + Text { + id: sliderText + anchors { + top: parent.top + topMargin: 10 + left: parent.left + leftMargin: 5 + } + font.pixelSize: 14 + } + + Slide { + id: slide + anchors{ + top: sliderText.bottom + left: parent.left + right: parent.right + } + } +} diff --git a/CanController/ViewChange.qml b/CanController/ViewChange.qml new file mode 100644 index 0000000..3dd38d0 --- /dev/null +++ b/CanController/ViewChange.qml @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +Rectangle{ + id: viewButton + height: 60 + radius: 5 + border.width: 2 + color: pressed ? blinkColor : "white" + + property alias text: buttonText.text + property bool mainView: true + property bool pressed: false + property bool optionalIcons: false + + property color blinkColor: "#26282a" + property color textBlinkColor: "#d6d6d6" + + property url iconOn: optionalIcons ? "qrc:/CenterViewOnOpt.png" : "qrc:/CenterViewOn.png" + property url iconOff: optionalIcons ? "qrc:/CenterViewOffOpt.png" : "qrc:/CenterViewOff.png" + + onPressedChanged: { + // TODO: Hack, use oilTemp/oilPressure CAN messages for view change + if (mainView) + clusterDataControl.oilTemp = pressed ? 10 : 0 + else + clusterDataControl.oilPressure = pressed ? 10 : 0 + } + + MouseArea { + id: buttonMouse + anchors.fill: parent + onPressed: { + buttonText.color = textBlinkColor + viewButton.pressed = !viewButton.pressed + } + onReleased: { + buttonText.color = blinkColor + viewButton.pressed = !viewButton.pressed + } + } + + Column { + spacing: 10 + + anchors.centerIn: parent + Image { + source: viewButton.pressed ? iconOff : iconOn + anchors.horizontalCenter: parent.horizontalCenter + } + Text { + id: buttonText + anchors.horizontalCenter: parent.horizontalCenter + font.pixelSize: 14 + color: "#26282a" + } + } +} diff --git a/CanController/canclusterdatacontrol.cpp b/CanController/canclusterdatacontrol.cpp new file mode 100644 index 0000000..4b2ff5f --- /dev/null +++ b/CanController/canclusterdatacontrol.cpp @@ -0,0 +1,934 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "canclusterdatacontrol.h" + +#include <QCanBus> +#include <QtGlobal> +#include <QDateTime> + +#include <QDebug> + +#define SOCKETCAN "socketcan" + +// J1939 PGNs +#define PGN_65268 0xFEF4 // Tire Condition - TIRE +#define PGN_64933 0xFDA5 // Door Control 2 - DC2 +#define PGN_64972 0xFDCC // Light Control +#define PGN_61445 0xF005 // Electronic Transmission Controller 2 - ETC2 +#define PGN_65265 0xFEF1 // Cruise Control/Vehicle Speed - CCVS +#define PGN_65267 0xFEF3 // vehicle position - VP +#define PGN_65256 0xFEE8 // vehicle direction/speed +#define PGN_65262 0xFEEE // Engine Temperature 1 - ET1 +#define PGN_65263 0xFEEF // Engine Fluid Level/Pressure 1 - EFL/P1 +#define PGN_65271 0xFEF7 // Vehicle Electrical Power - VEP +#define PGN_65276 0xFEFC // Dash Display - DD +#define PGN_61444 0xF004 // Electronic Engine Controller 1 - EEC1 +#define PGN_60928 0xEE00 // Address Calimed - ACL + +// door defines +#define DOOR_INIT 0xF33CCFF1FCFFFF0F +#define OPEN_DOOR_1 0x400000000000000 +#define OPEN_DOOR_2 0x1000000000000 +#define OPEN_DOOR_3 0x40000000000000 +#define OPEN_DOOR_4 0x100000000000 +#define OPEN_DOOR_5 0x400000000 +#define OPEN_DOOR_6 0x1000000 + +// light defines +#define LIGHT_INIT 0xF000FFFFFFFFFFFF +#define HEAD_LIGHT 0x200000000000000 +#define PARK_LIGHT 0x100000000000000 +#define LIGHT_ERROR 0x400000000000000 +#define LEFT_TURN_SIGNAL 0x10000000000000 +#define RIGHT_TURN_SIGNAL 0x20000000000000 +#define HAZARD_SIGNAL 0x4000000000000 + +// Current gear +#define GEAR_PARK 0xFB +#define GEAR_REVERSE 0x7C +#define GEAR_NEUTRAL 0x7D +// #define GEAR_1 0x7E +// #define GEAR_2 0x7F +// #define GEAR_3 0x80 +// #define GEAR_4 0x81 +// #define GEAR_5 0x82 +// #define GEAR_6 0x83 + +//#define _CAN_DEBUG + +CanClusterDataControl::CanClusterDataControl(QObject* parent) : + ClusterDataControlInterface(parent), + m_canBus(QCanBus::instance()), + m_device(Q_NULLPTR), + m_doorStatus(DOOR_INIT), + m_lightStatus(LIGHT_INIT), + m_brake(false) +{ + Q_ASSERT(m_canBus); + qsrand(QDateTime::currentMSecsSinceEpoch()); + QStringList plugins(m_canBus->plugins()); + if (plugins.contains(SOCKETCAN)) { + m_device = m_canBus->createDevice(SOCKETCAN, "can0"); + m_device->setParent(this); + connect(m_device, SIGNAL(errorOccurred(QCanBusDevice::CanBusError)), this, SLOT(canError(QCanBusDevice::CanBusError))); + connect(m_device, SIGNAL(framesReceived()), this, SLOT(canFramesReceived())); + connect(m_device, SIGNAL(stateChanged(QCanBusDevice::CanBusDeviceState)), this, SLOT(canStateChanged(QCanBusDevice::CanBusDeviceState))); +#ifdef _CAN_DEBUG + connect(m_device, SIGNAL(framesWritten(qint64)), this, SLOT(canFramesWritten(qint64))); + qDebug() << "CanClusterDataControl::CanClusterDataControl - connect device:" << +#endif + m_device->connectDevice(); + } +} + +int CanClusterDataControl::carId() const +{ + return m_carId; +} + +bool CanClusterDataControl::headLight() const +{ + return (m_lightStatus & HEAD_LIGHT); +} + +bool CanClusterDataControl::parkLight() const +{ + return (m_lightStatus & PARK_LIGHT); +} + +bool CanClusterDataControl::rightTurnLight() const +{ + return (m_lightStatus & RIGHT_TURN_SIGNAL); +} + +bool CanClusterDataControl::leftTurnLight() const +{ + return (m_lightStatus & LEFT_TURN_SIGNAL); +} + +int CanClusterDataControl::gear() const +{ + return m_gear; +} + +bool CanClusterDataControl::lightFailure() const +{ + return (m_lightStatus & LIGHT_ERROR); +} + +bool CanClusterDataControl::frontLeftDoorOpen() const +{ + return (m_doorStatus & OPEN_DOOR_1); +} + +bool CanClusterDataControl::frontRightDoorOpen() const +{ + return (m_doorStatus & OPEN_DOOR_2); +} + +bool CanClusterDataControl::rearLeftDoorOpen() const +{ + return (m_doorStatus & OPEN_DOOR_3); +} + +bool CanClusterDataControl::rearRightDoorOpen() const +{ + return (m_doorStatus & OPEN_DOOR_4); +} + +bool CanClusterDataControl::trunkOpen() const +{ + return (m_doorStatus & OPEN_DOOR_5); +} + +bool CanClusterDataControl::hoodOpen() const +{ + return (m_doorStatus & OPEN_DOOR_6); +} + +bool CanClusterDataControl::flatTire() const +{ + return m_flatTire; +} + +double CanClusterDataControl::direction() const +{ + return m_direction; +} + +double CanClusterDataControl::longitude() const +{ + return m_longitude; +} + +double CanClusterDataControl::latitude() const +{ + return m_latitude; +} + +double CanClusterDataControl::vehicleSpeed() const +{ + return m_vehicleSpeed; +} + +bool CanClusterDataControl::hazardSignal() const +{ + return (m_lightStatus & HAZARD_SIGNAL); +} + +bool CanClusterDataControl::brake() const +{ + return m_brake; +} + +double CanClusterDataControl::oilTemp() const +{ + return m_oilTemp; +} + +int CanClusterDataControl::oilPressure() const +{ + return m_oilPressure; +} + +double CanClusterDataControl::batteryPotential() const +{ + return m_batteryPotential; +} + +double CanClusterDataControl::gasLevel() const +{ + return m_gasLevel; +} + +int CanClusterDataControl::rpm() const +{ + return m_rpm; +} + +int CanClusterDataControl::engineTemp() const +{ + return m_engineTemp; +} + +void CanClusterDataControl::setVehicleSpeed(double vehicleSpeed) +{ + if (m_vehicleSpeed == vehicleSpeed) + return; + +#ifdef _CAN_DEBUG + qDebug("setVehicleSpeed: %f", vehicleSpeed); +#endif + + m_vehicleSpeed = vehicleSpeed; + + sendCCVS(); + + emit vehicleSpeedChanged(vehicleSpeed); +} + +void CanClusterDataControl::setLatitude(double latitude) +{ + if (m_latitude == latitude) + return; + +#ifdef _CAN_DEBUG + qDebug("setLatitude: %f", latitude); +#endif + + m_latitude = latitude; + emit latitudeChanged(latitude); +} + +void CanClusterDataControl::setLongitude(double longitude) +{ + if (m_longitude == longitude) + return; + +#ifdef _CAN_DEBUG + qDebug("setLongitude: %f", longitude); +#endif + + m_longitude = longitude; + emit longitudeChanged(longitude); +} + +void CanClusterDataControl::setDirection(double direction) +{ + if (m_direction == direction) + return; + +#ifdef _CAN_DEBUG + qDebug("setDirection: %f", direction); +#endif + + quint16 convertedDirection(128.0 * direction); // 1/128 deg/bit + QByteArray directionData; + directionData.append((convertedDirection >> 8) & 0xff); + directionData.append(convertedDirection & 0xff); + char emptyData[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; + directionData.append(emptyData, 6); + + QCanBusFrame directionFrame(PGN_65256, directionData); + + if (!m_device->writeFrame(directionFrame)) { + qWarning("CanClusterDataControl::setDirection - Error in pgn 65256 - vehicle direction/speed - VDS: %s", qPrintable(m_device->errorString())); + return; + } + + m_direction = direction; + emit directionChanged(direction); +} + +void CanClusterDataControl::setFlatTire(bool flatTire) +{ + if (m_flatTire == flatTire) + return; + + m_flatTire = flatTire; + + char tireId(0x00); // front left + // tireId = 0x01; // front right + // tireId = 0x10; // back left + // tireId = 0x11; // back right + + // status 2 bits: + // 00 Ok (no fault) + // 01 Tire leak detected + // 10 Error + // 11 Not Supported + + // temperature, Resolution: 0.03125 deg C/bit, -273 deg C offset + // spn242 - Tire Temperature - Temperature at the surface of the tire sidewall. + // Data Length: 2 bytes + // Resolution: 0.03125 deg C/bit , -273 deg C offset + // Data Range: -273 to 1735 deg C + quint16 temperature(0x1dc0 + (qrand() % 0x960)); // -35 to +40 C + + if (flatTire) { + // pressure: 0 kPa + // status: 01 Tire leak detected + sendTireConditionData(tireId, 0x0, temperature, 0x01); + } + else { + char pressure(0x31 + (qrand() % 0xf)); // 196 - 256 kPa + // status: 00 Ok (no fault) + sendTireConditionData(tireId, pressure, temperature, 0x00); + } + + emit flatTireChanged(flatTire); +} + +void CanClusterDataControl::setFrontLeftDoorOpen(bool doorOpen) +{ + if ((m_doorStatus & OPEN_DOOR_1) == doorOpen) + return; + + sendDoorOpenStatus(OPEN_DOOR_1, doorOpen); + + emit frontLeftDoorOpenChanged(doorOpen); +} + +void CanClusterDataControl::setFrontRightDoorOpen(bool doorOpen) +{ + if ((m_doorStatus & OPEN_DOOR_2) == doorOpen) + return; + + sendDoorOpenStatus(OPEN_DOOR_2, doorOpen); + + emit frontRightDoorOpenChanged(doorOpen); +} + +void CanClusterDataControl::setRearLeftDoorOpen(bool doorOpen) +{ + if ((m_doorStatus & OPEN_DOOR_3) == doorOpen) + return; + + sendDoorOpenStatus(OPEN_DOOR_3, doorOpen); + + emit rearLeftDoorOpenChanged(doorOpen); +} + +void CanClusterDataControl::setRearRightDoorOpen(bool doorOpen) +{ + if ((m_doorStatus & OPEN_DOOR_4) == doorOpen) + return; + + sendDoorOpenStatus(OPEN_DOOR_4, doorOpen); + + emit rearRightDoorOpenChanged(doorOpen); +} + +void CanClusterDataControl::setTrunkOpen(bool doorOpen) +{ + if ((m_doorStatus & OPEN_DOOR_5) == doorOpen) + return; + + sendDoorOpenStatus(OPEN_DOOR_5, doorOpen); + + emit trunkOpenChanged(doorOpen); +} + +void CanClusterDataControl::setHoodOpen(bool doorOpen) +{ + if ((m_doorStatus & OPEN_DOOR_6) == doorOpen) + return; + + sendDoorOpenStatus(OPEN_DOOR_6, doorOpen); + + emit hoodOpenChanged(doorOpen); +} + +void CanClusterDataControl::setLightFailure(bool lightFailure) +{ + if ((m_lightStatus & LIGHT_ERROR) == lightFailure) + return; + +#ifdef _CAN_DEBUG + qDebug("setLightFailure - status: %s", (lightFailure ? "on" : "off")); +#endif + + sendLightStatus(LIGHT_ERROR, lightFailure); + emit lightFailureChanged(lightFailure); +} + +void CanClusterDataControl::setGear(int gear) +{ + if (m_gear == gear) + return; + +#ifdef _CAN_DEBUG + qDebug("setGear: %d", gear); +#endif + + m_gear = gear; + + char driveGear; + if (gear == 0xff ) { + driveGear = GEAR_PARK; + } + else if (gear < 0) { + driveGear = GEAR_REVERSE; + } + else { + driveGear = (GEAR_NEUTRAL + gear); + } + + QByteArray gearData; + char emptyData[3] = { 0x0, 0x0, 0x0 }; + gearData.append(emptyData, 3); + gearData.append(driveGear); + char emptyData2[4] = { 0x0, 0x0, 0x0, 0x0 }; + gearData.append(emptyData2, 4); + QCanBusFrame gearFrame(PGN_61445, gearData); + if (!m_device->writeFrame(gearFrame)) { + qWarning("CanClusterDataControl::setGear - Error in pgn 61445 - Electronic Transmission Controller 2 - ETC2 send: %s", qPrintable(m_device->errorString())); + } + + emit gearChanged(gear); +} + +void CanClusterDataControl::setLeftTurnLight(bool leftTurnLight) +{ + if ((m_lightStatus & HAZARD_SIGNAL) || (m_lightStatus & LEFT_TURN_SIGNAL) == leftTurnLight) + return; + +#ifdef _CAN_DEBUG + qDebug("setLeftTurnLight - status: %s", (leftTurnLight ? "on" : "off")); +#endif + + sendLightStatus(LEFT_TURN_SIGNAL, leftTurnLight); + emit leftTurnLightChanged(leftTurnLight); +} + +void CanClusterDataControl::setRightTurnLight(bool rightTurnLight) +{ + if ((m_lightStatus & HAZARD_SIGNAL) || (m_lightStatus & RIGHT_TURN_SIGNAL) == rightTurnLight) + return; + +#ifdef _CAN_DEBUG + qDebug("setRightTurnLight - status: %s", (rightTurnLight ? "on" : "off")); +#endif + + sendLightStatus(RIGHT_TURN_SIGNAL, rightTurnLight); + emit rightTurnLightChanged(rightTurnLight); +} + +void CanClusterDataControl::setHeadLight(bool headLight) +{ + if ((m_lightStatus & HEAD_LIGHT) == headLight) + return; + +#ifdef _CAN_DEBUG + qDebug("setHeadLight - status: %s", (headLight ? "on" : "off")); +#endif + + sendLightStatus(HEAD_LIGHT, headLight); + emit headLightChanged(headLight); +} + +void CanClusterDataControl::setParkLight(bool parkLight) +{ + if ((m_lightStatus & PARK_LIGHT) == parkLight) + return; + +#ifdef _CAN_DEBUG + qDebug("setParkLight - status: %s", (parkLight ? "on" : "off")); +#endif + + sendLightStatus(PARK_LIGHT, parkLight); + emit parkLightChanged(parkLight); +} + +void CanClusterDataControl::setCarId(int carId) +{ + if (m_carId == carId) + return; + + m_carId = carId; + +#ifdef _CAN_DEBUG + qDebug("setCarId - carId: %d", carId); +#endif + + quint16 carIdData(carId); // only 21 bits allowed (0x0 - 0x1FFFFF), pos 1.1 - 3.5 in message + + QByteArray aclData; + aclData.append((char)(carIdData >> 13 & 0xff)); + aclData.append((char)(carIdData >> 5 & 0xff)); + aclData.append((char)(carIdData << 3 & 0xf8)); + char emptyData[5] = { 0x0, 0x0, 0x0, 0x0, 0x0 }; + aclData.append(emptyData, 5); + QCanBusFrame aclFrame(PGN_60928, aclData); + if (!m_device->writeFrame(aclFrame)) { + qWarning("CanClusterDataControl::setCarId - Error in pgn 60928 - Address Claimed - ACL send: %s", qPrintable(m_device->errorString())); + } + + emit carIdChanged(carId); +} + +void CanClusterDataControl::setHazardSignal(bool hazard) +{ + if ((m_lightStatus & HAZARD_SIGNAL) == hazard) + return; + +#ifdef _CAN_DEBUG + qDebug("setHazardSignal - status: %s", (hazard ? "on" : "off")); +#endif + + sendLightStatus(HAZARD_SIGNAL, hazard); + emit hazardSignalChanged(hazard); +} + +void CanClusterDataControl::setBrake(bool brakeOn) +{ + if (m_brake == brakeOn) return; + m_brake = brakeOn; + +#ifdef _CAN_DEBUG + qDebug("setBrake - status: %s", (brakeOn ? "on" : "off")); +#endif + + sendCCVS(); + emit brakeChanged(brakeOn); +} + +void CanClusterDataControl::setOilTemp(double oilTemp) +{ + if (m_oilTemp == oilTemp) + return; + +#ifdef _CAN_DEBUG + qDebug("setOilTemp - level: %f", oilTemp); +#endif + + m_oilTemp = oilTemp; + sendET1(); + emit oilTempChanged(oilTemp); +} + +void CanClusterDataControl::setOilPressure(int oilPressure) +{ + if (m_oilPressure == oilPressure) + return; + +#ifdef _CAN_DEBUG + qDebug("setOilPressure - level: %u", oilPressure); +#endif + + m_oilPressure = oilPressure; + + QByteArray eflp1Data; + char emptyData[3] = { 0x0, 0x0, 0x0 }; + eflp1Data.append(emptyData, 3); + + // spn100 - Engine Oil Pressure - Gage pressure of oil in engine lubrication system as provided by oil pump. + // Data Length: 1 byte + // Resolution: 4 kPa/bit , 0 offset + // Data Range: 0 to 1000 kPa + eflp1Data.append((char)(0.25 * (double)oilPressure)); + + char emptyData2[4] = { 0x0, 0x0, 0x0, 0x0 }; + eflp1Data.append(emptyData2, 4); + QCanBusFrame eflp1Frame(PGN_65263, eflp1Data); + if (!m_device->writeFrame(eflp1Frame)) { + qWarning("CanClusterDataControl::setOilPressure - Error in pgn 65263 - Engine Fluid Level/Pressure 1 - EFL/P1: %s", qPrintable(m_device->errorString())); + } + + emit oilPressureChanged(oilPressure); +} + + +void CanClusterDataControl::setBatteryPotential(double batteryPotential) +{ + if (m_batteryPotential == batteryPotential) + return; + +#ifdef _CAN_DEBUG + qDebug("setbatteryPotential - level: %f", batteryPotential); +#endif + + m_batteryPotential = batteryPotential; + + // spn158 - Battery Potential (Voltage), Switched + // Data Length: 2 bytes + // Resolution: 0.05 V/bit , 0 offset + // Data Range: 0 to 3212.75 V + quint16 convertedBatteryPotential(20.0 * batteryPotential); + + QByteArray vepData; + // 1 1 byte Net Battery Current 114 + // 2 1 byte Alternator Current 115 + // 3-4 2 bytes Alternator Potential (Voltage) 167 + // 5-6 2 bytes Electrical Potential (Voltage) 168 + char emptyData[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; + vepData.append(emptyData, 6); + + vepData.append((convertedBatteryPotential >> 8 ) & 0xff); + vepData.append(convertedBatteryPotential & 0xff); + + QCanBusFrame vepFrame(PGN_65271, vepData); + if (!m_device->writeFrame(vepFrame)) { + qWarning("CanClusterDataControl::setBatteryPotential - Error in pgn 65271 - Vehicle Electrical Power - VEP: %s", qPrintable(m_device->errorString())); + } + + emit batteryPotentialChanged(batteryPotential); +} + +void CanClusterDataControl::setGasLevel(double gasLevel) +{ + if (m_gasLevel == gasLevel) + return; + +#ifdef _CAN_DEBUG + qDebug("setGasLevel - level: %f", gasLevel); +#endif + + m_gasLevel = gasLevel; + + QByteArray ddData; + + // 1 1 byte Washer Fluid Level 80 + ddData.append((char)0x00); + + // spn96 - Fuel Level - Ratio of volume of fuel to the total volume of fuel storage container. + // Data Length: 1 byte + // Resolution: 0.4 %/bit , 0 offset + // Data Range: 0 to 100 % + ddData.append((char)(2.5 * gasLevel)); + + // 3 1 byte Fuel Filter Differential Pressure 95 + // 4 1 byte Engine Oil Filter Differential Pressure 99 + // 5-6 2 bytes Cargo Ambient Temperature 169 + // 7-8 2 bytes undefined + char emptyData[6] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; + ddData.append(emptyData, 6); + + QCanBusFrame ddFrame(PGN_65276, ddData); + if (!m_device->writeFrame(ddFrame)) { + qWarning("CanClusterDataControl::setbatteryPotential - Error in pgn 65276 - Dash Display - DD: %s", qPrintable(m_device->errorString())); + } + + emit gasLevelChanged(gasLevel); +} + +void CanClusterDataControl::setRpm(int rpm) +{ + if (m_rpm == rpm) + return; + +#ifdef _CAN_DEBUG + qDebug("setRpm - rpm: %d", rpm); +#endif + + m_rpm = rpm; + + QByteArray eec1Data; +// 1.1 4 bits Engine Torque Mode 899 +// 2 1 byte Driver's Demand Engine - Percent Torque 512 +// 3 1 byte Actual Engine - Percent Torque 513 + char emptyData[3] = { 0x0, 0x0, 0x0 }; + eec1Data.append(emptyData, 3); + + // spn190 - Engine Speed - Actual engine speed which is calculated over a minimum crankshaft angle of 720 degrees divided by + // the number of cylinders. + // Data Length: 2 bytes + // Resolution: 0.125 rpm/bit , 0 offset + // Data Range: 0 to 8,031.875 rpm + + quint16 convertedRpm(8.0 * m_rpm); + + eec1Data.append((convertedRpm >> 8 ) & 0xff); + eec1Data.append(convertedRpm & 0xff); + + // 6 1 byte Source Address of Controlling Device for Engine Control 1483 + // 7.1 4 bits Engine Starter Mode 1675 + // 8 1 byte Engine Demand - Percent Torque 2432 + eec1Data.append(emptyData, 3); + + QCanBusFrame eec1Frame(PGN_61444, eec1Data); + if (!m_device->writeFrame(eec1Frame)) { + qWarning("CanClusterDataControl::setbatteryPotential - Error in pgn 61444 - Electronic Engine Controller 1 - EEC1: %s", qPrintable(m_device->errorString())); + } + + emit rpmChanged(rpm); +} + +void CanClusterDataControl::setEngineTemp(int engineTemp) +{ + if (m_engineTemp == engineTemp) + return; + +#ifdef _CAN_DEBUG + qDebug("setengineTemp - engineTemp: %d", engineTemp); +#endif + + m_engineTemp = engineTemp; + sendET1(); + emit engineTempChanged(engineTemp); +} + +void CanClusterDataControl::sendPosition(QTime timeStamp) +{ +#ifdef _CAN_DEBUG + qDebug("CanClusterDataControl::sendPosition - time stamp: %d:%d:%d.%d", timeStamp.hour(), timeStamp.minute(), timeStamp.second(), timeStamp.msec()); +#endif + + QByteArray rapidPositionData; + + // 10^-7 deg/bit , -210 deg offset + quint32 lat((m_latitude + 210.0) * 10000000.0); + rapidPositionData.append((lat >> 24) & 0xff); + rapidPositionData.append((lat >> 16) & 0xff); + rapidPositionData.append((lat >> 8) & 0xff); + rapidPositionData.append(lat & 0xff); + + quint32 lon((m_longitude + 210.0) * 10000000.0); + rapidPositionData.append((lon >> 24) & 0xff); + rapidPositionData.append((lon >> 16) & 0xff); + rapidPositionData.append((lon >> 8) & 0xff); + rapidPositionData.append(lon & 0xff); + + // PGN_65267 – Vehicle position - VP + QCanBusFrame positionFrame(PGN_65267, rapidPositionData); + // timestamp not needed + // QCanBusFrame::TimeStamp ts(timeStamp.second(), timeStamp.msec() * 1000); + // positionFrame.setTimeStamp(ts); + if (!m_device->writeFrame(positionFrame)) { + qWarning("CanClusterDataControl::sendPosition - Error in pgn 65267 - Vehicle position - VP: %s", qPrintable(m_device->errorString())); + } +} + +void CanClusterDataControl::canError(QCanBusDevice::CanBusError error) +{ +#ifdef _CAN_DEBUG + qDebug() << "CanClusterDataControl::canError - error:" << error << "- string:" << m_device->errorString(); +#endif + m_device->disconnectDevice(); +} + +void CanClusterDataControl::canFramesReceived() +{ + while (m_device->framesAvailable() > 0) { +#ifdef _CAN_DEBUG + QCanBusFrame frame(m_device->readFrame()); + QByteArray data(frame.payload()); + qDebug() << "CanClusterDataControl::canFramesReceived - data:" << data; +#else + m_device->readFrame(); +#endif + } +} + +void CanClusterDataControl::canFramesWritten(qint64 framesCount) +{ +#ifdef _CAN_DEBUG + qDebug() << "CanClusterDataControl::canFramesWritten - framesCount:" << framesCount; +#else + Q_UNUSED(framesCount) +#endif +} + +void CanClusterDataControl::canStateChanged(QCanBusDevice::CanBusDeviceState state) +{ +#ifdef _CAN_DEBUG + qDebug() << "CanClusterDataControl::canStateChanged - state:" << state; +#else + Q_UNUSED(state) +#endif +} + +void CanClusterDataControl::sendTireConditionData(char tireId, char pressure, quint16 temperature, char status) +{ + QByteArray tireConditionData; + tireConditionData.append(tireId); // 8 bits, SPN 929 Tire Location + tireConditionData.append(pressure); // 8 bits, SPN 241 Tire Pressure + + tireConditionData.append((char)(temperature >> 8 & 0xff)); + tireConditionData.append((char)(temperature & 0xff)); + + // 5.1 2 bits CTI Wheel Sensor Status 1699, 11 = not supported + // 5.3 2 bits CTI Tire Status 1698, ok = 00, leak = 01 + // 5.5 2 bits CTI Wheel End Electrical Fault 1697, 11 = not supported + + tireConditionData.append(((status << 4) & 0x30) | 0xcc); // SPN 1698 CTI Tire Status + char emptyData[3] = { 0x0, 0x0, 0xe }; + + // 6-7 2 bytes Tire Air Leakage Rate 2586, 0 + // 8.6 3 bits Tire Pressure Threshold Detection 2587, 111 = Not available + tireConditionData.append(emptyData, 3); + QCanBusFrame tireConditionFrame(PGN_65268, tireConditionData); + if (!m_device->writeFrame(tireConditionFrame)) { + qWarning("CanClusterDataControl::sendTireConditionData - Error in pgn 65268 - Tire Condition - TIRE send: %s", qPrintable(m_device->errorString())); + } +} + +void CanClusterDataControl::sendDoorOpenStatus(quint64 door, bool open) +{ + if (open) { + m_doorStatus |= door; + } + else { + m_doorStatus &= ~door; + } + + QByteArray doorOpenData; + doorOpenData.append((char)(m_doorStatus >> 56 & 0xff)); + doorOpenData.append((char)(m_doorStatus >> 48 & 0xff)); + doorOpenData.append((char)(m_doorStatus >> 40 & 0xff)); + doorOpenData.append((char)(m_doorStatus >> 32 & 0xff)); + doorOpenData.append((char)(m_doorStatus >> 24 & 0xff)); + doorOpenData.append((char)(m_doorStatus >> 16 & 0xff)); + doorOpenData.append((char)(m_doorStatus >> 8 & 0xff)); + doorOpenData.append((char)(m_doorStatus & 0xff)); + + QCanBusFrame doorFrame(PGN_64933, doorOpenData); // Door Control 2 - DC2 + if (!m_device->writeFrame(doorFrame)) { + qWarning("CanClusterDataControl::sendDoorOpenStatus - Error in pgn 64933 - Door Control 2 send: %s", qPrintable(m_device->errorString())); + } +} + +void CanClusterDataControl::sendLightStatus(quint64 lightID, bool lightOn) +{ + if (lightOn) { + m_lightStatus |= lightID; + } + else { + m_lightStatus &= ~lightID; + } + + QByteArray lightData; + lightData.append((char)(m_lightStatus >> 56 & 0xff)); + lightData.append((char)(m_lightStatus >> 48 & 0xff)); + lightData.append((char)(m_lightStatus >> 40 & 0xff)); + lightData.append((char)(m_lightStatus >> 32 & 0xff)); + lightData.append((char)(m_lightStatus >> 24 & 0xff)); + lightData.append((char)(m_lightStatus >> 16 & 0xff)); + lightData.append((char)(m_lightStatus >> 8 & 0xff)); + lightData.append((char)(m_lightStatus & 0xff)); + + QCanBusFrame lightFrame(PGN_64972, lightData); + if (!m_device->writeFrame(lightFrame)) { + qWarning("RouteSender::sendNextData - Error in pgn 64972 - Light control send: %s", qPrintable(m_device->errorString())); + } +} + +void CanClusterDataControl::sendCCVS() +{ + QByteArray ccvsData; + ccvsData.append((char)0x0); + + // 16 bits, Wheel-Based Vehicle Speed (SPN 84), Resolution: 1/256 km/h per bit, Data Range: 0 to 250.996 km/h + quint16 speed(256.0 * m_vehicleSpeed); + ccvsData.append((speed >> 8) & 0xff); + ccvsData.append(speed & 0xff); + + // 2 bits Brake Switch (SPN 597) + // 00 = pedal released + // 01 = pedal depressed + if (m_brake) { + ccvsData.append((char)0x10); + } + else { + ccvsData.append((char)0x00); + } + char emptyData[4] = { 0x0, 0x0, 0x0, 0x0 }; + ccvsData.append(emptyData, 4); + QCanBusFrame ccvsFrame(PGN_65265, ccvsData); + if (!m_device->writeFrame(ccvsFrame)) { + qWarning("CanClusterDataControl::sendCCVS - Error in pgn 65265 - Cruise Control/Vehicle Speed - CCVS: %s", qPrintable(m_device->errorString())); + } +} + +void CanClusterDataControl::sendET1() +{ + QByteArray et1Data; + // SPN 110 - Engine Coolant Temperature + // Data Length: 1 byte + // Resolution: 1 deg C/bit , -40 deg C offset + // Data Range: -40 to 210 deg C + et1Data.append((quint8)(m_engineTemp + 40)); + et1Data.append((char)0x00); // SPN 174 Fuel Temperature + // spn175 - Engine Oil Temperature 1 - Temperature of the engine lubricant. + // Data Length: 2 bytes + // Resolution: 0.03125 deg C/bit , -273 deg C offset + // Data Range: -273 to 1735 deg C + quint16 convertedEngOilTemp(32.0 * (m_oilTemp + 273.0)); + et1Data.append((convertedEngOilTemp >> 8) & 0xff); + et1Data.append(convertedEngOilTemp & 0xff); + // 5-6 2 bytes Turbo Oil Temperature 176 + // 7 1 byte Engine Intercooler Temperature 52 + // 8 1 byte Engine Intercooler Thermostat Opening 1134 + char emptyData[4] = { 0x0, 0x0, 0x0, 0x0 }; + et1Data.append(emptyData, 4); + QCanBusFrame et1Frame(PGN_65262, et1Data); + if (!m_device->writeFrame(et1Frame)) { + qWarning("CanClusterDataControl::sendET1 - Error in pgn 65262 - Engine Temperature 1 - ET1: %s", qPrintable(m_device->errorString())); + } +} diff --git a/CanController/canclusterdatacontrol.h b/CanController/canclusterdatacontrol.h new file mode 100644 index 0000000..1708c8a --- /dev/null +++ b/CanController/canclusterdatacontrol.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CANCLUSTERDATACONTROL_H +#define CANCLUSTERDATACONTROL_H + +#include "clusterdatacontrolinterface.h" +#include <QTime> +#include <QCanBusDevice> + +class CanClusterDataControl : public ClusterDataControlInterface +{ + Q_OBJECT + +public: + CanClusterDataControl(QObject* parent = Q_NULLPTR); + +public: // from class ClusterDataControlInterface + virtual int carId() const; + virtual bool headLight() const; + virtual bool parkLight() const; + virtual bool rightTurnLight() const; + virtual bool leftTurnLight() const; + virtual int gear() const; + virtual bool lightFailure() const; + virtual bool frontLeftDoorOpen() const; + virtual bool frontRightDoorOpen() const; + virtual bool rearLeftDoorOpen() const; + virtual bool rearRightDoorOpen() const; + virtual bool hoodOpen() const; + virtual bool trunkOpen() const; + virtual bool flatTire() const; + virtual double direction() const; + virtual double longitude() const; + virtual double latitude() const; + virtual double vehicleSpeed() const; + virtual bool hazardSignal() const; + virtual bool brake() const; + virtual double oilTemp() const; + virtual int oilPressure() const; + virtual double batteryPotential() const; + virtual double gasLevel() const; + virtual int rpm() const; + virtual int engineTemp() const; + +public slots: // from class ClusterDataControlInterface + virtual void setVehicleSpeed(double vehicleSpeed); + virtual void setLatitude(double latitude); + virtual void setLongitude(double longitude); + virtual void setDirection(double direction); + virtual void setFlatTire(bool flatTire); + virtual void setFrontLeftDoorOpen(bool doorOpen); + virtual void setFrontRightDoorOpen(bool doorOpen); + virtual void setRearLeftDoorOpen(bool doorOpen); + virtual void setRearRightDoorOpen(bool doorOpen); + virtual void setHoodOpen(bool doorOpen); + virtual void setTrunkOpen(bool doorOpen); + virtual void setLightFailure(bool lightFailure); + virtual void setGear(int gear); + virtual void setLeftTurnLight(bool leftTurnLight); + virtual void setRightTurnLight(bool rightTurnLight); + virtual void setHeadLight(bool headLight); + virtual void setParkLight(bool parkLight); + virtual void setCarId(int carId); + virtual void setHazardSignal(bool hazard); + virtual void setBrake(bool brakeOn); + virtual void setOilTemp(double oilTemp); + virtual void setOilPressure(int oilPressure); + virtual void setBatteryPotential (double batteryPotential); + virtual void setGasLevel(double gasLevel); + virtual void setRpm(int rpm); + virtual void setEngineTemp(int engineTemp); + +public slots: // new local slots + void sendPosition(QTime timeStamp); + +private slots: + void canError(QCanBusDevice::CanBusError error); + void canFramesReceived(); + void canFramesWritten(qint64 framesCount); + void canStateChanged(QCanBusDevice::CanBusDeviceState state); + +private: + void sendTireConditionData(char tireId, char pressure, quint16 temperature, char status); + void sendDoorOpenStatus(quint64 door, bool open); + void sendLightStatus(quint64 lightID, bool lightOn); + void sendCCVS(); + void sendET1(); + +private: // data + class QCanBus* m_canBus; + class QCanBusDevice* m_device; + quint64 m_doorStatus; + quint64 m_lightStatus; + bool m_brake; +}; + +#endif // CANCLUSTERDATACONTROL_H diff --git a/CanController/carui.qrc b/CanController/carui.qrc new file mode 100644 index 0000000..8eb3ccb --- /dev/null +++ b/CanController/carui.qrc @@ -0,0 +1,70 @@ +<RCC> + <qresource prefix="/"> + <file>Button.qml</file> + <file>ButtonHolder.qml</file> + <file>Car.qml</file> + <file>CarUI.qml</file> + <file>Gear.qml</file> + <file>GearAutomatic.qml</file> + <file>Icon_BulbFailure_OFF.png</file> + <file>Icon_BulbFailure_ON.png</file> + <file>Icon_HazardWarning_OFF.png</file> + <file>Icon_HazardWarning_ON.png</file> + <file>Icon_LowBeam_OFF.png</file> + <file>Icon_LowBeam_ON.png</file> + <file>Icon_TurnLeft_OFF.png</file> + <file>Icon_TurnLeft_ON.png</file> + <file>Icon_TurnRight_OFF.png</file> + <file>Icon_TurnRight_ON.png</file> + <file>Icon_TyreMalfunction_OFF.png</file> + <file>Icon_TyreMalfunction_ON.png</file> + <file>Slide.qml</file> + <file>SlideHolder.qml</file> + <file>S-Car_BrakesOFF.png</file> + <file>S-Car_BrakesON.png</file> + <file>S-Car_DoorLeftOFF.png</file> + <file>S-Car_DoorLeftON.png</file> + <file>S-Car_DoorRightOFF.png</file> + <file>S-Car_DoorRightON.png</file> + <file>S-Car_HoodOFF.png</file> + <file>S-Car_HoodON.png</file> + <file>S-Car_LowBeamsOFF.png</file> + <file>S-Car_LowBeamsON.png</file> + <file>S-Car_Shape.png</file> + <file>S-Car_TrunkOFF.png</file> + <file>S-Car_TrunkON.png</file> + <file>S-Car_TurnLeftOFF.png</file> + <file>S-Car_TurnLeftON.png</file> + <file>S-Car_TurnRightOFF.png</file> + <file>S-Car_TurnRightON.png</file> + <file>E-Car_BackDoorLeftOFF.png</file> + <file>E-Car_BackDoorLeftON.png</file> + <file>E-Car_BackDoorRightOFF.png</file> + <file>E-Car_BackDoorRightON.png</file> + <file>E-Car_BrakesOFF.png</file> + <file>E-Car_BrakesON.png</file> + <file>E-Car_FrontDoorLeftOFF.png</file> + <file>E-Car_FrontDoorLeftON.png</file> + <file>E-Car_FrontDoorRightOFF.png</file> + <file>E-Car_FrontDoorRightON.png</file> + <file>E-Car_HoodOFF.png</file> + <file>E-Car_HoodON.png</file> + <file>E-Car_LowBeamsOFF.png</file> + <file>E-Car_LowBeamsON.png</file> + <file>E-Car_Shape.png</file> + <file>E-Car_TrunkOFF.png</file> + <file>E-Car_TrunkON.png</file> + <file>E-Car_TurnLeftOFF.png</file> + <file>E-Car_TurnLeftON.png</file> + <file>E-Car_TurnRightOFF.png</file> + <file>E-Car_TurnRightON.png</file> + <file>ViewChange.qml</file> + <file>CenterViewOff.png</file> + <file>CenterViewOn.png</file> + <file>route.txt</file> + <file>Icon_ParkingBrake_OFF.png</file> + <file>Icon_ParkingBrake_ON.png</file> + <file>CenterViewOffOpt.png</file> + <file>CenterViewOnOpt.png</file> + </qresource> +</RCC> diff --git a/CanController/clusterdatacontrolinterface.h b/CanController/clusterdatacontrolinterface.h new file mode 100644 index 0000000..1e11dc1 --- /dev/null +++ b/CanController/clusterdatacontrolinterface.h @@ -0,0 +1,184 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CLUSTERDATACONTROLINTERFACE_H +#define CLUSTERDATACONTROLINTERFACE_H + +#include <QObject> + +class ClusterDataControlInterface : public QObject +{ + Q_OBJECT + Q_PROPERTY(double vehicleSpeed READ vehicleSpeed WRITE setVehicleSpeed NOTIFY vehicleSpeedChanged) + Q_PROPERTY(double latitude READ latitude WRITE setLatitude NOTIFY latitudeChanged) + Q_PROPERTY(double longitude READ longitude WRITE setLongitude NOTIFY longitudeChanged) + Q_PROPERTY(double direction READ direction WRITE setDirection NOTIFY directionChanged) + Q_PROPERTY(bool flatTire READ flatTire WRITE setFlatTire NOTIFY flatTireChanged) + Q_PROPERTY(bool frontLeftDoorOpen READ frontLeftDoorOpen WRITE setFrontLeftDoorOpen NOTIFY frontLeftDoorOpenChanged) + Q_PROPERTY(bool frontRightDoorOpen READ frontRightDoorOpen WRITE setFrontRightDoorOpen NOTIFY frontRightDoorOpenChanged) + Q_PROPERTY(bool rearLeftDoorOpen READ rearLeftDoorOpen WRITE setRearLeftDoorOpen NOTIFY rearLeftDoorOpenChanged) + Q_PROPERTY(bool rearRightDoorOpen READ rearRightDoorOpen WRITE setRearRightDoorOpen NOTIFY rearRightDoorOpenChanged) + Q_PROPERTY(bool lightFailure READ lightFailure WRITE setLightFailure NOTIFY lightFailureChanged) + Q_PROPERTY(bool trunkOpen READ trunkOpen WRITE setTrunkOpen NOTIFY trunkOpenChanged) + Q_PROPERTY(bool hoodOpen READ hoodOpen WRITE setHoodOpen NOTIFY hoodOpenChanged) + Q_PROPERTY(int gear READ gear WRITE setGear NOTIFY gearChanged) + Q_PROPERTY(bool leftTurnLight READ leftTurnLight WRITE setLeftTurnLight NOTIFY leftTurnLightChanged) + Q_PROPERTY(bool rightTurnLight READ rightTurnLight WRITE setRightTurnLight NOTIFY rightTurnLightChanged) + Q_PROPERTY(bool headLight READ headLight WRITE setHeadLight NOTIFY headLightChanged) + Q_PROPERTY(bool parkLight READ parkLight WRITE setParkLight NOTIFY parkLightChanged) + Q_PROPERTY(int carId READ carId WRITE setCarId NOTIFY carIdChanged) + Q_PROPERTY(bool hazardSignal READ hazardSignal WRITE setHazardSignal NOTIFY hazardSignalChanged) + Q_PROPERTY(bool brake READ brake WRITE setBrake NOTIFY brakeChanged) + Q_PROPERTY(double oilTemp READ oilTemp WRITE setOilTemp NOTIFY oilTempChanged) + Q_PROPERTY(int oilPressure READ oilPressure WRITE setOilPressure NOTIFY oilPressureChanged) + Q_PROPERTY(double batteryPotential READ batteryPotential WRITE setBatteryPotential NOTIFY batteryPotentialChanged) + Q_PROPERTY(double gasLevel READ gasLevel WRITE setGasLevel NOTIFY gasLevelChanged) + Q_PROPERTY(int rpm READ rpm WRITE setRpm NOTIFY rpmChanged) + Q_PROPERTY(int engineTemp READ engineTemp WRITE setEngineTemp NOTIFY engineTempChanged) +public: + ClusterDataControlInterface(QObject *parent) : + QObject(parent), + m_carId(2), + m_gear(1), + m_lightFailure(false), + m_flatTire(false), + m_direction(0.0), + m_longitude(0.0), + m_latitude(0.0), + m_vehicleSpeed(0.0), + m_oilTemp(40.0), + m_oilPressure(0), + m_batteryPotential(80.0), + m_gasLevel(67.0), + m_rpm(4000), + m_engineTemp(60) + {} + + virtual int carId() const = 0; + virtual bool headLight() const = 0; + virtual bool parkLight() const = 0; + virtual bool rightTurnLight() const = 0; + virtual bool leftTurnLight() const = 0; + virtual int gear() const = 0; + virtual bool lightFailure() const = 0; + virtual bool frontLeftDoorOpen() const = 0; + virtual bool frontRightDoorOpen() const = 0; + virtual bool rearLeftDoorOpen() const = 0; + virtual bool rearRightDoorOpen() const = 0; + virtual bool hoodOpen() const = 0; + virtual bool trunkOpen() const = 0; + virtual bool flatTire() const = 0; + virtual double direction() const = 0; + virtual double longitude() const = 0; + virtual double latitude() const = 0; + virtual double vehicleSpeed() const = 0; + virtual bool hazardSignal() const = 0; + virtual bool brake() const = 0; + virtual double oilTemp() const = 0; + virtual int oilPressure() const = 0; + virtual double batteryPotential() const = 0; + virtual double gasLevel() const = 0; + virtual int rpm() const = 0; + virtual int engineTemp() const = 0; + +public slots: + virtual void setVehicleSpeed(double vehicleSpeed) = 0; + virtual void setLatitude(double latitude) = 0; + virtual void setLongitude(double longitude) = 0; + virtual void setDirection(double direction) = 0; + virtual void setFlatTire(bool flatTire) = 0; + virtual void setFrontLeftDoorOpen(bool doorOpen) = 0; + virtual void setFrontRightDoorOpen(bool doorOpen) = 0; + virtual void setRearLeftDoorOpen(bool doorOpen) = 0; + virtual void setRearRightDoorOpen(bool doorOpen) = 0; + virtual void setHoodOpen(bool doorOpen) = 0; + virtual void setTrunkOpen(bool doorOpen) = 0; + virtual void setLightFailure(bool lightFailure) = 0; + virtual void setGear(int gear) = 0; + virtual void setLeftTurnLight(bool leftTurnLight) = 0; + virtual void setRightTurnLight(bool rightTurnLight) = 0; + virtual void setHeadLight(bool headLight) = 0; + virtual void setParkLight(bool parkLight) = 0; + virtual void setCarId(int carId) = 0; + virtual void setHazardSignal(bool) = 0; + virtual void setBrake(bool) = 0; + virtual void setOilTemp(double oilTemp) = 0; + virtual void setOilPressure(int oilPressure) = 0; + virtual void setBatteryPotential(double batteryPotential) = 0; + virtual void setGasLevel(double gasLevel) = 0; + virtual void setRpm(int rpm) = 0; + virtual void setEngineTemp(int engineTemp) = 0; + +signals: + void dataReset(); + void carIdChanged(int carId); + void headLightChanged(bool headLight); + void parkLightChanged(bool parkLight); + void rightTurnLightChanged(bool rightTurnLight); + void leftTurnLightChanged(bool leftTurnLight); + void gearChanged(bool gear); + void lightFailureChanged(bool lightFailure); + void frontLeftDoorOpenChanged(bool doorOpen); + void frontRightDoorOpenChanged(bool doorOpen); + void rearLeftDoorOpenChanged(bool doorOpen); + void rearRightDoorOpenChanged(bool doorOpen); + void hoodOpenChanged(bool doorOpen); + void trunkOpenChanged(bool doorOpen); + void flatTireChanged(bool flatTire); + void directionChanged(double direction); + void longitudeChanged(double longitude); + void latitudeChanged(double latitude); + void vehicleSpeedChanged(double vehicleSpeed); + void hazardSignalChanged(bool hazard); + void brakeChanged(bool brakeOn); + void oilTempChanged(double oilTemp); + void oilPressureChanged(int oilPressure); + void batteryPotentialChanged(double batteryPotential); + void gasLevelChanged(double gasLevel); + void rpmChanged(int rpm); + void engineTempChanged(int engineTemp); + +protected: + int m_carId; + int m_gear; + bool m_lightFailure; + bool m_flatTire; + double m_direction; + double m_longitude; + double m_latitude; + double m_vehicleSpeed; + double m_oilTemp; + int m_oilPressure; + double m_batteryPotential; + double m_gasLevel; + int m_rpm; + int m_engineTemp; + +}; + +#endif // CLUSTERDATACONTROLINTERFACE_H diff --git a/CanController/gpssender.cpp b/CanController/gpssender.cpp new file mode 100644 index 0000000..a5ffb32 --- /dev/null +++ b/CanController/gpssender.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gpssender.h" +#include "nmea.h" + +#include <QFile> +#include <QDebug> + +GpsSender::GpsSender(QString routeFileName, QObject* parent) : + QObject(parent), + m_dataPosition(0), + m_nmea(Q_NULLPTR), + m_latitude(0.0), + m_longitude(0.0), + m_direction(0.0), + m_vehicleSpeed(0.0) +{ + parseRouteFile(routeFileName); + m_timer.setSingleShot(true); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(nextData()), Qt::QueuedConnection); + m_nmea = NMEA::parse(m_data.at(m_dataPosition)); + QMetaObject::invokeMethod(this, "nextData", Qt::QueuedConnection); +} + +GpsSender::~GpsSender() +{ + delete m_nmea; +} + +void GpsSender::parseRouteFile(QString routeFileName) +{ + QFile routeFile(routeFileName); + if (!routeFile.open(QIODevice::ReadOnly | QIODevice::Text)) { + qWarning("GpsSender::parseRouteFile - Error opening route file: %s", qPrintable(routeFileName)); + return; + } + while (!routeFile.atEnd()) { + m_data.append(routeFile.readLine().simplified()); + } + routeFile.close(); +} + +void GpsSender::nextData() +{ + if (m_nmea) { + NMEAType::Type type(m_nmea->type()); + bool convertOk(false); + + if (type != NMEAType::UndefinedType) { + qreal position(m_nmea->value(NMEAType::Latitude).toDouble(&convertOk)); +#ifndef TCPCLUSTERDATACONNECTION + bool posChanged(false); +#endif + if (convertOk && m_latitude != position) { + m_latitude = position; + emit latitudeChanged(m_latitude); +#ifndef TCPCLUSTERDATACONNECTION + posChanged = true; +#endif + } + position = m_nmea->value(NMEAType::Longitude).toDouble(&convertOk); + if (convertOk && m_longitude != position) { + m_longitude = position; + emit longitudeChanged(m_longitude); +#ifndef TCPCLUSTERDATACONNECTION + posChanged = true; +#endif + } +#ifndef TCPCLUSTERDATACONNECTION +// qDebug("GpsSender::nextData - posChanged: %s, m_timeStamp is valid: %s", (posChanged ? "true" : "false"), (m_timeStamp.isValid() ? "true" : "false")); + if (posChanged && m_timeStamp.isValid()) { + emit positionChanged(m_timeStamp); + } +#endif + } + + if (type == NMEAType::RMCType) { + qreal convertedValue(m_nmea->value(NMEAType::RMCAngle).toDouble(&convertOk)); + if (convertOk && m_direction != convertedValue) { + m_direction = convertedValue; + emit directionChanged(m_direction); + } + convertedValue = m_nmea->value(NMEAType::RMCSpeed).toDouble(&convertOk); + if (convertOk && m_vehicleSpeed != convertedValue) { + m_vehicleSpeed = convertedValue; + emit vehicleSpeedChanged(m_vehicleSpeed); + } + } + } + + delete m_nmea; + if (++m_dataPosition >= m_data.count()) { + m_dataPosition = 0; + } + + m_nmea = NMEA::parse(m_data.at(m_dataPosition)); + + if (m_nmea) { + QTime timeStamp(m_nmea->value(NMEAType::UTCTime).toTime()); + int mseconds(m_timeStamp.msecsTo(timeStamp)); + m_timeStamp = timeStamp; + if (mseconds > 0) { + m_timer.start(mseconds); + } + else { + QMetaObject::invokeMethod(this, "nextData", Qt::QueuedConnection); + } + } + else { + m_timeStamp = QTime(); + qWarning("GpsSender::nextData - Error in NMEA parsing"); + } +} diff --git a/CanController/gpssender.h b/CanController/gpssender.h new file mode 100644 index 0000000..0fc595e --- /dev/null +++ b/CanController/gpssender.h @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GPSSENDER_H +#define GPSSENDER_H + +#include <QObject> +#include <QTimer> +#include <QTime> + +class GpsSender : public QObject +{ + Q_OBJECT + +public: + explicit GpsSender(QString routeFileName, QObject* parent = Q_NULLPTR); + virtual ~GpsSender(); + +private: + void parseRouteFile(QString routeFileName); + +signals: + void latitudeChanged(qreal latitude); + void longitudeChanged(qreal longitude); + void directionChanged(qreal direction); + void vehicleSpeedChanged(qreal vehicleSpeed); +#ifndef TCPCLUSTERDATACONNECTION + void positionChanged(QTime timeStamp); +#endif + +private slots: + void nextData(); + +private: // data + QStringList m_data; + QTimer m_timer; + int m_dataPosition; + class NMEA* m_nmea; + qreal m_latitude; + qreal m_longitude; + qreal m_direction; + qreal m_vehicleSpeed; + QTime m_timeStamp; + +}; + +#endif // GPSSENDER_H diff --git a/CanController/main.cpp b/CanController/main.cpp new file mode 100644 index 0000000..b50e5cc --- /dev/null +++ b/CanController/main.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QGuiApplication> +#include <QQuickView> +#include <QObject> +#include <QQmlEngine> +#include <QQmlContext> + +#include "gpssender.h" + +#ifdef TCPCLUSTERDATACONNECTION +#include "tcpclusterdatacontrol.h" +#else +#include <QTime> +#include "canclusterdatacontrol.h" +#endif + +int main(int argc, char** argv) +{ + QGuiApplication app(argc, argv); + + ClusterDataControlInterface* dataInterface(Q_NULLPTR); + +#ifdef TCPCLUSTERDATACONNECTION + dataInterface = new TCPClusterDataControl; +#else + dataInterface = new CanClusterDataControl; +#endif + + Q_ASSERT(dataInterface); + + QString routeFileName(DEFAULT_ROUTE_FILE); + QStringList args(app.arguments()); + if (args.count() > 1) { + routeFileName = args.at(1); + } + + GpsSender gpsSender(routeFileName); + + QObject::connect(&gpsSender, SIGNAL(latitudeChanged(qreal)), dataInterface, SLOT(setLatitude(double))); + QObject::connect(&gpsSender, SIGNAL(longitudeChanged(qreal)), dataInterface, SLOT(setLongitude(double))); + QObject::connect(&gpsSender, SIGNAL(directionChanged(qreal)), dataInterface, SLOT(setDirection(double))); + QObject::connect(&gpsSender, SIGNAL(vehicleSpeedChanged(qreal)), dataInterface, SLOT(setVehicleSpeed(double))); + +#ifndef TCPCLUSTERDATACONNECTION + QObject::connect(&gpsSender, SIGNAL(positionChanged(QTime)), qobject_cast<CanClusterDataControl*>(dataInterface), SLOT(sendPosition(QTime))); +#endif + + QQuickView view; + + view.rootContext()->setContextProperty("clusterDataControl", dataInterface); + + QObject::connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit())); + + view.setSource(QUrl(MAIN_QML_FILE_NAME)); + + view.show(); + + return app.exec(); +} diff --git a/CanController/nmea.cpp b/CanController/nmea.cpp new file mode 100644 index 0000000..a73361d --- /dev/null +++ b/CanController/nmea.cpp @@ -0,0 +1,446 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "nmea.h" + +#include <QObject> +#include <QtMath> + +#include <QDebug> + + +// NMEAPrivate +struct NMEAPrivate +{ + NMEAPrivate() : m_checksum(0), m_type(NMEAType::UndefinedType) { + } + int m_checksum; + NMEAType::Type m_type; + QTime m_taken; +}; + + +// NMEA +NMEA::NMEA() : m_private(new NMEAPrivate) +{ +} + +NMEA::~NMEA() +{ + delete m_private; + m_private = NULL; +} + +NMEA* NMEA::parse(QString data) +{ + NMEA* nmea(Q_NULLPTR); + + int lastIndex(data.lastIndexOf("*")); + int checksum(0); + for (int index(data.indexOf("$") + 1); index < lastIndex; index++) { + checksum ^= (int)data.at(index).toLatin1(); + } + + QString checksumString(QString::number(checksum, 16)); + if (checksum <= 0xf) { + checksumString.prepend("0"); + } + QString compareChecksum(data.mid(lastIndex + 1)); + if (compareChecksum.compare(checksumString)) { + qWarning("NMEA::parse - Error invalid checksum %s != %s", qPrintable(compareChecksum), qPrintable(QString::number(checksum, 16))); + return nmea; + } + + QStringList dataList(data.left(lastIndex).split(",")); + if (dataList.count() <= 1) { + return nmea; + } + + QString type(dataList.at(0)); + + if (type.compare("$GPGGA", Qt::CaseInsensitive) == 0) { + nmea = new GGA(dataList); + } + + else if (type.compare("$GPRMC", Qt::CaseInsensitive) == 0) { + nmea = new RMC(dataList); + } + + if (!nmea) { + qWarning("NMEA::parse - Error NMEA creation error"); + } + else if (nmea->isValid()) { + nmea->m_private->m_checksum = checksum; + } + else { + qWarning("NMEA::parse - Error NMEA is not valid, deleting it"); + delete nmea; + nmea = Q_NULLPTR; + } + + return nmea; +} + +bool NMEA::isValid() const +{ + Q_ASSERT(m_private != Q_NULLPTR); + return (m_private && m_private->m_type != NMEAType::UndefinedType); +} + +NMEAType::Type NMEA::type() const +{ + Q_ASSERT(m_private != Q_NULLPTR); + return (m_private ? m_private->m_type : NMEAType::UndefinedType); +} + +QVariant NMEA::value(NMEAType::Value type) const +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type == NMEAType::UTCTime) { + return QVariant::fromValue<QTime>(m_private->m_taken); + } + else if (type == NMEAType::CheckSum) { + return QVariant::fromValue<int>(m_private->m_checksum); + } + else return QVariant(); +} + +void NMEA::setValue(NMEAType::Value type, QVariant value) +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type == NMEAType::UTCTime && value.type() == QVariant::Time) { + m_private->m_taken = value.toTime(); + } + else if (type == NMEAType::CheckSum && value.type() == QVariant::Int) { + m_private->m_checksum = value.toInt(); + } +} + +// GeoBasePrivate +struct GeoBasePrivate : public NMEAPrivate +{ + GeoBasePrivate() : m_latitude(0.0), m_longitude(0.0) { + } + qreal m_latitude; + qreal m_longitude; +}; + + +// GeoBasePrivate +GeoBase::GeoBase() +{ +} + +GeoBase::~GeoBase() +{ +} + +QVariant GeoBase::value(NMEAType::Value type) const +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type >= (NMEAType::Value)NMEAType::NMEAStart && type <= (NMEAType::Value)NMEAType::NMEAEnd) { + return NMEA::value(type); + } + else { + GeoBasePrivate* geoBasePrivate((GeoBasePrivate*)m_private); + switch (type) { + case NMEAType::Latitude : return QVariant::fromValue<qreal>(geoBasePrivate->m_latitude); + case NMEAType::Longitude : return QVariant::fromValue<qreal>(geoBasePrivate->m_longitude); + default: /* do nothing */ break; + } + } + return QVariant(); +} + +void GeoBase::setValue(NMEAType::Value type, QVariant value) +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type >= (NMEAType::Value)NMEAType::NMEAStart && type <= (NMEAType::Value)NMEAType::NMEAEnd) { + NMEA::setValue(type, value); + } + else { + GeoBasePrivate* geoBasePrivate((GeoBasePrivate*)m_private); + switch (type) { + case NMEAType::Latitude : geoBasePrivate->m_latitude = value.toDouble(); break; + case NMEAType::Longitude : geoBasePrivate->m_longitude = value.toDouble(); break; + default: /* do nothing */ break; + } + } +} + + +// GGA +struct GGAPrivate : public GeoBasePrivate +{ + GGAPrivate() : m_quality(0), m_satellites(0), m_dilution(0.0), m_altitude(0.0), m_geoid(0.0) { + } + int m_quality; + int m_satellites; + qreal m_dilution; + qreal m_altitude; + qreal m_geoid; +}; + +GGA::~GGA() { +} + +QVariant GGA::value(NMEAType::Value type) const +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type >= (NMEAType::Value)NMEAType::NMEAStart && type <= (NMEAType::Value)NMEAType::GeoBaseEnd) { + return GeoBase::value(type); + } + else { + GGAPrivate* ggaPrivate((GGAPrivate*)m_private); + switch (type) { + case NMEAType::GGAQuality : return QVariant::fromValue<int>(ggaPrivate->m_quality); + case NMEAType::GGASatellites : return QVariant::fromValue<int>(ggaPrivate->m_satellites); + case NMEAType::GGADilution : return QVariant::fromValue<qreal>(ggaPrivate->m_dilution); + case NMEAType::GGAAltitude : return QVariant::fromValue<qreal>(ggaPrivate->m_altitude); + case NMEAType::GGAGeoid : return QVariant::fromValue<qreal>(ggaPrivate->m_geoid); + default: /* do nothing */ break; + } + } + return QVariant(); + +} + +void GGA::setValue(NMEAType::Value type, QVariant value) +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type >= (NMEAType::Value)NMEAType::NMEAStart && type <= (NMEAType::Value)NMEAType::GeoBaseEnd) { + return GeoBase::setValue(type, value); + } + else { + GGAPrivate* ggaPrivate((GGAPrivate*)m_private); + switch (type) { + case NMEAType::GGAQuality : ggaPrivate->m_quality = value.toInt(); break; + case NMEAType::GGASatellites : ggaPrivate->m_satellites = value.toInt(); break; + case NMEAType::GGADilution : ggaPrivate->m_dilution = value.toDouble(); break; + case NMEAType::GGAAltitude : ggaPrivate->m_altitude = value.toDouble(); break; + case NMEAType::GGAGeoid : ggaPrivate->m_geoid = value.toDouble(); break; + default: /* do nothing */ break; + } + } +} + +GGA::GGA(QStringList data) +{ + GGAPrivate* newPrivate = new GGAPrivate; + if (data.count() == 15) { + QString utcTime(data.at(1)); + if (utcTime.length() > 6) { + newPrivate->m_taken = QTime::fromString(utcTime, "hhmmss.z"); + } + else { + newPrivate->m_taken = QTime::fromString(utcTime, "hhmmss"); + } + + bool ok(false); + qreal position(data.at(2).toDouble(&ok)); + if (ok) { + qreal degrees(qFloor(0.01 * position)); + newPrivate->m_latitude = (degrees + ((position - (100.0 * degrees)) / 60)); + if (data.at(3).compare("S", Qt::CaseInsensitive) == 0) { + newPrivate->m_latitude *= -1.0; + } + } + else { + qWarning("GGA::GGA - Error in latitude parse"); + } + + position = data.at(4).toDouble(&ok); + if (ok) { + qreal degrees(qFloor(0.01 * position)); + newPrivate->m_longitude = (degrees + ((position - (100.0 * degrees)) / 60)); + if (data.at(5).compare("W", Qt::CaseInsensitive) == 0) { + newPrivate->m_longitude *= -1.0; + } + } + else { + qWarning("GGA::GGA - Error in longitude parse"); + } + newPrivate->m_quality = data.at(6).toInt(&ok); + if (!ok) { + qWarning("GGA::GGA - Error in quality parse"); + } + newPrivate->m_satellites = data.at(7).toInt(&ok); + if (!ok) { + qWarning("GGA::GGA - Error in satellites parse"); + } + newPrivate->m_dilution = data.at(8).toDouble(&ok); + if (!ok) { + qWarning("GGA::GGA - Error in dilution parse"); + } + newPrivate->m_altitude = data.at(9).toDouble(&ok); + if (!ok) { + qWarning("GGA::GGA - Error in altitude parse"); + } + if (data.at(10).compare("M")) { + qWarning("GGA::GGA - Error in altitude type parse"); + } + newPrivate->m_geoid = data.at(11).toDouble(&ok); + if (!ok) { + qWarning("GGA::GGA - Error in height of geoid parse"); + } + if (data.at(12).compare("M")) { + qWarning("GGA::GGA - Error in height of geoid type parse"); + } + if (!data.at(13).isEmpty()) { + qWarning("GGA::GGA - Error in not empty field 14 - data: %s", qPrintable(data.at(13))); + } + if (!data.at(14).isEmpty()) { + qWarning("GGA::GGA - Error in not empty field 15 - data: %s", qPrintable(data.at(14))); + } + } + else { + qWarning("GGA::GGA - Error incorrect amount of data %d available!", data.count()); + } + delete m_private; + newPrivate->m_type = NMEAType::GGAType; + m_private = newPrivate; +} + + +// RMC +struct RMCPrivate : public GeoBasePrivate +{ + RMCPrivate() : m_active(false), m_speed(0.0), m_angle(0.0), m_variation(0.0) { + } + bool m_active; + qreal m_speed; + qreal m_angle; + QDate m_date; + qreal m_variation; +}; + +RMC::~RMC() +{ +} + +QVariant RMC::value(NMEAType::Value type) const +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type >= (NMEAType::Value)NMEAType::NMEAStart && type <= (NMEAType::Value)NMEAType::GeoBaseEnd) { + return GeoBase::value(type); + } + else { + RMCPrivate* rmcPrivate((RMCPrivate*)m_private); + switch (type) { + case NMEAType::RMCActive : return QVariant::fromValue<bool>(rmcPrivate->m_active); + case NMEAType::RMCSpeed : return QVariant::fromValue<qreal>(rmcPrivate->m_speed); + case NMEAType::RMCAngle : return QVariant::fromValue<qreal>(rmcPrivate->m_angle); + case NMEAType::RMCDate : return QVariant::fromValue<QDate>(rmcPrivate->m_date); + case NMEAType::RMCVariation : return QVariant::fromValue<qreal>(rmcPrivate->m_variation); + default: /* do nothing */ break; + } + } + return QVariant(); +} + +void RMC::setValue(NMEAType::Value type, QVariant value) +{ + Q_ASSERT(m_private != Q_NULLPTR); + if (type >= (NMEAType::Value)NMEAType::NMEAStart && type <= (NMEAType::Value)NMEAType::GeoBaseEnd) { + return GeoBase::setValue(type, value); + } + else { + RMCPrivate* rmcPrivate((RMCPrivate*)m_private); + switch (type) { + case NMEAType::RMCActive : rmcPrivate->m_active = value.toBool(); break; + case NMEAType::RMCSpeed : rmcPrivate->m_speed = value.toDouble(); break; + case NMEAType::RMCAngle : rmcPrivate->m_angle = value.toDouble(); break; + case NMEAType::RMCDate : rmcPrivate->m_date = value.toDate(); break; + case NMEAType::RMCVariation : rmcPrivate->m_variation = value.toDouble(); break; + default: /* do nothing */ break; + } + } +} + +RMC::RMC(QStringList data) +{ + RMCPrivate* newPrivate = new RMCPrivate; + if (data.count() == 13) { + QString utcTime(data.at(1)); + if (utcTime.length() > 6) { + newPrivate->m_taken = QTime::fromString(utcTime, "hhmmss.z"); + } + else { + newPrivate->m_taken = QTime::fromString(utcTime, "hhmmss"); + } + + newPrivate->m_active = (data.at(2).compare("A") == 0); + + bool ok(false); + qreal position(data.at(3).toDouble(&ok)); + if (ok) { + qreal degrees(qFloor(0.01 * position)); + newPrivate->m_latitude = (degrees + ((position - (100.0 * degrees)) / 60)); + if (data.at(4).compare("S", Qt::CaseInsensitive) == 0) { + newPrivate->m_latitude *= -1.0; + } + } + else { + qWarning("RMC::RMC - Error in latitude parse"); + } + position = data.at(5).toDouble(&ok); + if (ok) { + qreal degrees(qFloor(0.01 * position)); + newPrivate->m_longitude = (degrees + ((position - (100.0 * degrees)) / 60)); + if (data.at(6).compare("W", Qt::CaseInsensitive) == 0) { + newPrivate->m_longitude *= -1.0; + } + } + else { + qWarning("RMC::RMC - Error in longitude parse"); + } + newPrivate->m_speed = data.at(7).toDouble(&ok); + if (!ok) { + qWarning("RMC::RMC - Error in speed parse"); + } + newPrivate->m_angle = data.at(8).toDouble(&ok); + if (!ok) { + qWarning("RMC::RMC - Error in angle parse, data: %s", qPrintable(data.at(8))); + } + newPrivate->m_date = QDate::fromString(data.at(9), "ddMMyy"); + + newPrivate->m_variation = data.at(10).toDouble(&ok); + if (!ok) { + qWarning("RMC::RMC - Error in variation parse"); + } + if (data.at(11).compare("W", Qt::CaseInsensitive) == 0) { + newPrivate->m_variation *= -1.0; + } + } + else { + qWarning("RMC::RMC - Error incorrect amount of data %d available!", data.count()); + } + delete m_private; + newPrivate->m_type = NMEAType::RMCType; + m_private = newPrivate; +} diff --git a/CanController/nmea.h b/CanController/nmea.h new file mode 100644 index 0000000..8df1b63 --- /dev/null +++ b/CanController/nmea.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NMEA_H +#define NMEA_H + +#include <QStringList> +#include <QDateTime> +#include <QByteArray> +#include <QList> +#include <QVariant> + +#include "valuetypes.h" + +class NMEA +{ +protected: + NMEA(); + +public: + virtual ~NMEA(); + + // NOTE: ownership is changed, caller must delete + static NMEA* parse(QString data); + bool isValid() const; + NMEAType::Type type() const; + virtual QVariant value(NMEAType::Value type) const; + virtual void setValue(NMEAType::Value type, QVariant value); + +protected: + struct NMEAPrivate* m_private; + +}; + + +// GeoBase + +class GeoBase : public NMEA +{ +protected: + GeoBase(); + +public: + virtual ~GeoBase(); + virtual QVariant value(NMEAType::Value type) const; + virtual void setValue(NMEAType::Value type, QVariant value); +}; + + +// GGA + +class GGA : public GeoBase +{ +public: + virtual ~GGA(); + virtual QVariant value(NMEAType::Value type) const; + virtual void setValue(NMEAType::Value type, QVariant value); + +private: + GGA(QStringList data); + friend class NMEA; +}; + + +// RMC + +class RMC : public GeoBase +{ +public: + virtual ~RMC(); + virtual QVariant value(NMEAType::Value type) const; + virtual void setValue(NMEAType::Value type, QVariant value); + +private: + RMC(QStringList data); + friend class NMEA; +}; + +#endif // NMEA_H diff --git a/CanController/route.txt b/CanController/route.txt new file mode 100644 index 0000000..2262763 --- /dev/null +++ b/CanController/route.txt @@ -0,0 +1,1188 @@ +$GPGGA,120156,5232.08,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,120156,A,5232.08,N,1317.6,E,0,200.0,030308,11.2,W,A*22 +$GPGGA,120157,5232.08,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120157,A,5232.08,N,1317.6,E,0,200.0,030308,11.2,W,A*23 +$GPGGA,120158,5232.08,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120158,A,5232.08,N,1317.6,E,0,200.0,030308,11.2,W,A*2c +$GPGGA,120159,5232.08,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*7e +$GPRMC,120159,A,5232.08,N,1317.6,E,0,200.0,030308,11.2,W,A*2d +$GPGGA,120200,5232.08,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,120200,A,5232.08,N,1317.6,E,3.9,200.0,030308,11.2,W,A*36 +$GPGGA,120201,5232.08,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120201,A,5232.08,N,1317.6,E,8.7,197.0,030308,11.2,W,A*3f +$GPGGA,120202,5232.07,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*7c +$GPRMC,120202,A,5232.07,N,1317.6,E,11.7,215.0,030308,11.2,W,A*02 +$GPGGA,120203,5232.07,N,1317.59,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120203,A,5232.07,N,1317.59,E,19.4,205.0,030308,11.2,W,A*33 +$GPGGA,120204,5232.06,N,1317.59,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120204,A,5232.06,N,1317.59,E,19.9,191.0,030308,11.2,W,A*36 +$GPGGA,120205,5232.05,N,1317.59,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120205,A,5232.05,N,1317.59,E,21.4,166.0,030308,11.2,W,A*3a +$GPGGA,120206,5232.05,N,1317.6,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120206,A,5232.05,N,1317.6,E,19.9,131.0,030308,11.2,W,A*07 +$GPGGA,120207,5232.04,N,1317.61,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120207,A,5232.04,N,1317.61,E,18.5,140.0,030308,11.2,W,A*3d +$GPGGA,120208,5232.04,N,1317.62,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120208,A,5232.04,N,1317.62,E,17.5,133.0,030308,11.2,W,A*3a +$GPGGA,120209,5232.03,N,1317.62,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120209,A,5232.03,N,1317.62,E,17.5,151.0,030308,11.2,W,A*38 +$GPGGA,120210,5232.03,N,1317.63,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120210,A,5232.03,N,1317.63,E,9.7,161.0,030308,11.2,W,A*0f +$GPGGA,120211,5232.02,N,1317.63,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120211,A,5232.02,N,1317.63,E,5.8,168.0,030308,11.2,W,A*05 +$GPGGA,120212,5232.02,N,1317.63,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120212,A,5232.02,N,1317.63,E,0,166.0,030308,11.2,W,A*1b +$GPGGA,120213,5232.02,N,1317.63,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120213,A,5232.02,N,1317.63,E,0,166.0,030308,11.2,W,A*1a +$GPGGA,120214,5232.02,N,1317.63,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120214,A,5232.02,N,1317.63,E,0,166.0,030308,11.2,W,A*1d +$GPGGA,120215,5232.01,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120215,A,5232.01,N,1317.64,E,9.7,153.0,030308,11.2,W,A*0e +$GPGGA,120216,5232,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*64 +$GPRMC,120216,A,5232,N,1317.64,E,19.4,153.0,030308,11.2,W,A*10 +$GPGGA,120217,5232,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*64 +$GPRMC,120217,A,5232,N,1317.65,E,19.4,157.0,030308,11.2,W,A*14 +$GPGGA,120218,5231.99,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120218,A,5231.99,N,1317.65,E,19.9,154.0,030308,11.2,W,A*38 +$GPGGA,120219,5231.99,N,1317.66,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120219,A,5231.99,N,1317.66,E,22.4,156.0,030308,11.2,W,A*3d +$GPGGA,120220,5231.98,N,1317.66,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120220,A,5231.98,N,1317.66,E,21.9,150.0,030308,11.2,W,A*3e +$GPGGA,120221,5231.97,N,1317.67,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120221,A,5231.97,N,1317.67,E,22.4,160.0,030308,11.2,W,A*3c +$GPGGA,120222,5231.96,N,1317.67,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120222,A,5231.96,N,1317.67,E,23.3,154.0,030308,11.2,W,A*3f +$GPGGA,120223,5231.96,N,1317.68,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120223,A,5231.96,N,1317.68,E,23.3,165.0,030308,11.2,W,A*33 +$GPGGA,120224,5231.95,N,1317.68,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120224,A,5231.95,N,1317.68,E,23.3,161.0,030308,11.2,W,A*33 +$GPGGA,120225,5231.94,N,1317.68,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120225,A,5231.94,N,1317.68,E,23.3,160.0,030308,11.2,W,A*32 +$GPGGA,120226,5231.94,N,1317.69,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120226,A,5231.94,N,1317.69,E,23.3,155.0,030308,11.2,W,A*36 +$GPGGA,120227,5231.93,N,1317.69,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120227,A,5231.93,N,1317.69,E,23.3,157.0,030308,11.2,W,A*32 +$GPGGA,120228,5231.92,N,1317.7,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120228,A,5231.92,N,1317.7,E,23.3,159.0,030308,11.2,W,A*0a +$GPGGA,120229,5231.91,N,1317.71,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120229,A,5231.91,N,1317.71,E,23.8,157.0,030308,11.2,W,A*3c +$GPGGA,120230,5231.9,N,1317.71,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120230,A,5231.9,N,1317.71,E,25.3,158.0,030308,11.2,W,A*07 +$GPGGA,120231,5231.9,N,1317.72,E,1,07,1.3,50.6,M,39.2,M,,*72 +$GPRMC,120231,A,5231.9,N,1317.72,E,28.2,157.0,030308,11.2,W,A*06 +$GPGGA,120232,5231.89,N,1317.72,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120232,A,5231.89,N,1317.72,E,29.2,159.0,030308,11.2,W,A*32 +$GPGGA,120233,5231.88,N,1317.72,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120233,A,5231.88,N,1317.72,E,29.6,165.0,030308,11.2,W,A*39 +$GPGGA,120234,5231.87,N,1317.73,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120234,A,5231.87,N,1317.73,E,28.7,167.0,030308,11.2,W,A*32 +$GPGGA,120235,5231.86,N,1317.73,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120235,A,5231.86,N,1317.73,E,28.2,168.0,030308,11.2,W,A*38 +$GPGGA,120236,5231.85,N,1317.73,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120236,A,5231.85,N,1317.73,E,26.7,168.0,030308,11.2,W,A*33 +$GPGGA,120237,5231.84,N,1317.74,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120237,A,5231.84,N,1317.74,E,28.2,170.0,030308,11.2,W,A*36 +$GPGGA,120238,5231.83,N,1317.74,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120238,A,5231.83,N,1317.74,E,28.7,172.0,030308,11.2,W,A*39 +$GPGGA,120239,5231.82,N,1317.74,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120239,A,5231.82,N,1317.74,E,29.2,168.0,030308,11.2,W,A*36 +$GPGGA,120240,5231.81,N,1317.75,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120240,A,5231.81,N,1317.75,E,28.7,168.0,030308,11.2,W,A*3e +$GPGGA,120241,5231.8,N,1317.75,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120241,A,5231.8,N,1317.75,E,28.2,167.0,030308,11.2,W,A*04 +$GPGGA,120242,5231.79,N,1317.75,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120242,A,5231.79,N,1317.75,E,27.7,170.0,030308,11.2,W,A*3d +$GPGGA,120243,5231.78,N,1317.75,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120243,A,5231.78,N,1317.75,E,27.2,169.0,030308,11.2,W,A*30 +$GPGGA,120244,5231.77,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120244,A,5231.77,N,1317.76,E,26.7,165.0,030308,11.2,W,A*33 +$GPGGA,120245,5231.76,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120245,A,5231.76,N,1317.77,E,26.2,153.0,030308,11.2,W,A*32 +$GPGGA,120246,5231.75,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120246,A,5231.75,N,1317.77,E,26.2,156.0,030308,11.2,W,A*37 +$GPGGA,120247,5231.75,N,1317.78,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120247,A,5231.75,N,1317.78,E,26.2,155.0,030308,11.2,W,A*3a +$GPGGA,120248,5231.74,N,1317.78,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120248,A,5231.74,N,1317.78,E,25.8,151.0,030308,11.2,W,A*39 +$GPGGA,120249,5231.74,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120249,A,5231.74,N,1317.79,E,23.8,150.0,030308,11.2,W,A*3e +$GPGGA,120250,5231.73,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120250,A,5231.73,N,1317.79,E,21.9,166.0,030308,11.2,W,A*37 +$GPGGA,120251,5231.72,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120251,A,5231.72,N,1317.79,E,23.3,167.0,030308,11.2,W,A*3e +$GPGGA,120252,5231.71,N,1317.8,E,1,07,1.3,50.6,M,39.2,M,,*75 +$GPRMC,120252,A,5231.71,N,1317.8,E,24.8,173.0,030308,11.2,W,A*01 +$GPGGA,120253,5231.7,N,1317.8,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120253,A,5231.7,N,1317.8,E,24.8,170.0,030308,11.2,W,A*32 +$GPGGA,120254,5231.69,N,1317.8,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120254,A,5231.69,N,1317.8,E,24.8,171.0,030308,11.2,W,A*0c +$GPGGA,120255,5231.68,N,1317.8,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120255,A,5231.68,N,1317.8,E,24.8,166.0,030308,11.2,W,A*0a +$GPGGA,120256,5231.68,N,1317.81,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120256,A,5231.68,N,1317.81,E,24.9,167.0,030308,11.2,W,A*38 +$GPGGA,120257,5231.67,N,1317.81,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120257,A,5231.67,N,1317.81,E,28.2,165.0,030308,11.2,W,A*33 +$GPGGA,120258,5231.66,N,1317.81,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120258,A,5231.66,N,1317.81,E,30.1,165.0,030308,11.2,W,A*37 +$GPGGA,120259,5231.65,N,1317.82,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120259,A,5231.65,N,1317.82,E,31.6,168.0,030308,11.2,W,A*3d +$GPGGA,120300,5231.64,N,1317.82,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120300,A,5231.64,N,1317.82,E,33.0,167.0,030308,11.2,W,A*3a +$GPGGA,120301,5231.63,N,1317.82,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120301,A,5231.63,N,1317.82,E,33.0,169.0,030308,11.2,W,A*32 +$GPGGA,120302,5231.62,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120302,A,5231.62,N,1317.83,E,33.0,171.0,030308,11.2,W,A*38 +$GPGGA,120303,5231.61,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120303,A,5231.61,N,1317.83,E,33.0,168.0,030308,11.2,W,A*32 +$GPGGA,120304,5231.6,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*74 +$GPRMC,120304,A,5231.6,N,1317.83,E,33.0,166.0,030308,11.2,W,A*0a +$GPGGA,120305,5231.59,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120305,A,5231.59,N,1317.84,E,34.5,169.0,030308,11.2,W,A*3b +$GPGGA,120306,5231.58,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120306,A,5231.58,N,1317.84,E,34.5,165.0,030308,11.2,W,A*35 +$GPGGA,120307,5231.57,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120307,A,5231.57,N,1317.84,E,35.5,168.0,030308,11.2,W,A*37 +$GPGGA,120308,5231.56,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120308,A,5231.56,N,1317.85,E,36.0,170.0,030308,11.2,W,A*37 +$GPGGA,120309,5231.55,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120309,A,5231.55,N,1317.85,E,35.5,174.0,030308,11.2,W,A*37 +$GPGGA,120310,5231.54,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120310,A,5231.54,N,1317.85,E,34.0,168.0,030308,11.2,W,A*37 +$GPGGA,120311,5231.53,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120311,A,5231.53,N,1317.85,E,34.0,174.0,030308,11.2,W,A*3c +$GPGGA,120312,5231.52,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120312,A,5231.52,N,1317.85,E,33.0,176.0,030308,11.2,W,A*3b +$GPGGA,120313,5231.51,N,1317.86,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120313,A,5231.51,N,1317.86,E,32.6,173.0,030308,11.2,W,A*38 +$GPGGA,120314,5231.5,N,1317.86,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120314,A,5231.5,N,1317.86,E,31.6,168.0,030308,11.2,W,A*07 +$GPGGA,120315,5231.49,N,1317.86,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120315,A,5231.49,N,1317.86,E,29.6,166.0,030308,11.2,W,A*39 +$GPGGA,120316,5231.49,N,1317.87,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120316,A,5231.49,N,1317.87,E,29.6,165.0,030308,11.2,W,A*38 +$GPGGA,120317,5231.48,N,1317.87,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120317,A,5231.48,N,1317.87,E,29.6,152.0,030308,11.2,W,A*3c +$GPGGA,120318,5231.47,N,1317.88,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120318,A,5231.47,N,1317.88,E,30.6,155.0,030308,11.2,W,A*3c +$GPGGA,120319,5231.46,N,1317.89,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120319,A,5231.46,N,1317.89,E,31.6,146.0,030308,11.2,W,A*3e +$GPGGA,120320,5231.45,N,1317.9,E,1,07,1.3,50.6,M,39.2,M,,*77 +$GPRMC,120320,A,5231.45,N,1317.9,E,31.6,140.0,030308,11.2,W,A*09 +$GPGGA,120321,5231.44,N,1317.91,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120321,A,5231.44,N,1317.91,E,31.6,145.0,030308,11.2,W,A*3d +$GPGGA,120322,5231.44,N,1317.92,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120322,A,5231.44,N,1317.92,E,31.6,140.0,030308,11.2,W,A*38 +$GPGGA,120323,5231.43,N,1317.93,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120323,A,5231.43,N,1317.93,E,31.6,143.0,030308,11.2,W,A*3c +$GPGGA,120324,5231.42,N,1317.94,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120324,A,5231.42,N,1317.94,E,31.8,144.0,030308,11.2,W,A*34 +$GPGGA,120325,5231.41,N,1317.95,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120325,A,5231.41,N,1317.95,E,32.1,143.0,030308,11.2,W,A*3a +$GPGGA,120326,5231.4,N,1317.96,E,1,07,1.3,50.6,M,39.2,M,,*72 +$GPRMC,120326,A,5231.4,N,1317.96,E,31.1,141.0,030308,11.2,W,A*0a +$GPGGA,120327,5231.39,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120327,A,5231.39,N,1317.97,E,35.0,143.0,030308,11.2,W,A*33 +$GPGGA,120328,5231.39,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120328,A,5231.39,N,1317.98,E,35.0,148.0,030308,11.2,W,A*38 +$GPGGA,120329,5231.38,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120329,A,5231.38,N,1317.98,E,35.0,143.0,030308,11.2,W,A*33 +$GPGGA,120330,5231.38,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120330,A,5231.38,N,1317.99,E,25.3,142.0,030308,11.2,W,A*39 +$GPGGA,120331,5231.37,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*6a +$GPRMC,120331,A,5231.37,N,1318,E,15.6,141.0,030308,11.2,W,A*13 +$GPGGA,120332,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120332,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*10 +$GPGGA,120333,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120333,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*11 +$GPGGA,120334,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120334,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*16 +$GPGGA,120335,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120335,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*17 +$GPGGA,120336,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120336,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*14 +$GPGGA,120337,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120337,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*15 +$GPGGA,120338,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120338,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*1a +$GPGGA,120339,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120339,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*1b +$GPGGA,120340,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120340,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*15 +$GPGGA,120341,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120341,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*14 +$GPGGA,120342,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120342,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*17 +$GPGGA,120343,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120343,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*16 +$GPGGA,120344,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120344,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*11 +$GPGGA,120345,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120345,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*10 +$GPGGA,120346,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120346,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*13 +$GPGGA,120347,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120347,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*12 +$GPGGA,120348,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120348,A,5231.36,N,1318.01,E,0,143.0,030308,11.2,W,A*1d +$GPGGA,120349,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120349,A,5231.36,N,1318.01,E,10.2,156.0,030308,11.2,W,A*35 +$GPGGA,120350,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120350,A,5231.36,N,1318.01,E,17.5,149.0,030308,11.2,W,A*33 +$GPGGA,120351,5231.35,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120351,A,5231.35,N,1318.02,E,23.3,148.0,030308,11.2,W,A*32 +$GPGGA,120352,5231.35,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120352,A,5231.35,N,1318.02,E,29.2,177.0,030308,11.2,W,A*36 +$GPGGA,120353,5231.34,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120353,A,5231.34,N,1318.02,E,29.2,189.0,030308,11.2,W,A*37 +$GPGGA,120354,5231.34,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120354,A,5231.34,N,1318.01,E,29.2,198.0,030308,11.2,W,A*33 +$GPGGA,120355,5231.33,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120355,A,5231.33,N,1318.01,E,29.2,192.0,030308,11.2,W,A*3f +$GPGGA,120356,5231.32,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120356,A,5231.32,N,1318.01,E,35.0,196.0,030308,11.2,W,A*36 +$GPGGA,120357,5231.31,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*6c +$GPRMC,120357,A,5231.31,N,1318,E,35.0,202.0,030308,11.2,W,A*15 +$GPGGA,120358,5231.3,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*52 +$GPRMC,120358,A,5231.3,N,1318,E,27.2,201.0,030308,11.2,W,A*29 +$GPGGA,120359,5231.3,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*72 +$GPRMC,120359,A,5231.3,N,1317.99,E,28.7,196.0,030308,11.2,W,A*0e +$GPGGA,120400,5231.29,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120400,A,5231.29,N,1317.99,E,29.6,200.0,030308,11.2,W,A*31 +$GPGGA,120401,5231.28,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120401,A,5231.28,N,1317.98,E,30.6,201.0,030308,11.2,W,A*39 +$GPGGA,120402,5231.27,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120402,A,5231.27,N,1317.98,E,30.1,201.0,030308,11.2,W,A*32 +$GPGGA,120403,5231.26,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120403,A,5231.26,N,1317.97,E,29.2,198.0,030308,11.2,W,A*35 +$GPGGA,120404,5231.25,N,1317.96,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120404,A,5231.25,N,1317.96,E,25.8,199.0,030308,11.2,W,A*37 +$GPGGA,120405,5231.24,N,1317.96,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120405,A,5231.24,N,1317.96,E,23.8,188.0,030308,11.2,W,A*31 +$GPGGA,120406,5231.23,N,1317.96,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120406,A,5231.23,N,1317.96,E,22.4,177.0,030308,11.2,W,A*38 +$GPGGA,120407,5231.22,N,1317.96,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120407,A,5231.22,N,1317.96,E,19.9,174.0,030308,11.2,W,A*3e +$GPGGA,120408,5231.22,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120408,A,5231.22,N,1317.97,E,11.7,170.0,030308,11.2,W,A*32 +$GPGGA,120409,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120409,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*29 +$GPGGA,120410,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*77 +$GPRMC,120410,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*21 +$GPGGA,120411,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*76 +$GPRMC,120411,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*20 +$GPGGA,120412,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*75 +$GPRMC,120412,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*23 +$GPGGA,120413,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*74 +$GPRMC,120413,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*22 +$GPGGA,120414,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120414,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*25 +$GPGGA,120415,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*72 +$GPRMC,120415,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*24 +$GPGGA,120416,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,120416,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*27 +$GPGGA,120417,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120417,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*26 +$GPGGA,120418,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120418,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*29 +$GPGGA,120419,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*7e +$GPRMC,120419,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*28 +$GPGGA,120420,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*74 +$GPRMC,120420,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*22 +$GPGGA,120421,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*75 +$GPRMC,120421,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*23 +$GPGGA,120422,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*76 +$GPRMC,120422,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*20 +$GPGGA,120423,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*77 +$GPRMC,120423,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*21 +$GPGGA,120424,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120424,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*26 +$GPGGA,120425,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,120425,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*27 +$GPGGA,120426,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*72 +$GPRMC,120426,A,5231.2,N,1317.97,E,0,171.0,030308,11.2,W,A*24 +$GPGGA,120427,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120427,A,5231.2,N,1317.97,E,9.7,149.0,030308,11.2,W,A*3e +$GPGGA,120428,5231.2,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*7c +$GPRMC,120428,A,5231.2,N,1317.97,E,13.6,171.0,030308,11.2,W,A*00 +$GPGGA,120429,5231.19,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120429,A,5231.19,N,1317.97,E,13.6,172.0,030308,11.2,W,A*38 +$GPGGA,120430,5231.19,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120430,A,5231.19,N,1317.97,E,14.6,177.0,030308,11.2,W,A*32 +$GPGGA,120431,5231.18,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120431,A,5231.18,N,1317.98,E,17.5,162.0,030308,11.2,W,A*39 +$GPGGA,120432,5231.18,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120432,A,5231.18,N,1317.98,E,23.3,158.0,030308,11.2,W,A*32 +$GPGGA,120433,5231.17,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120433,A,5231.17,N,1317.98,E,23.3,146.0,030308,11.2,W,A*33 +$GPGGA,120434,5231.17,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120434,A,5231.17,N,1317.99,E,23.3,127.0,030308,11.2,W,A*32 +$GPGGA,120435,5231.17,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*6b +$GPRMC,120435,A,5231.17,N,1318,E,23.3,121.0,030308,11.2,W,A*14 +$GPGGA,120436,5231.16,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120436,A,5231.16,N,1318.01,E,24.8,120.0,030308,11.2,W,A*34 +$GPGGA,120437,5231.16,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120437,A,5231.16,N,1318.02,E,26.7,118.0,030308,11.2,W,A*30 +$GPGGA,120438,5231.16,N,1318.03,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120438,A,5231.16,N,1318.03,E,28.2,120.0,030308,11.2,W,A*3e +$GPGGA,120439,5231.15,N,1318.04,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120439,A,5231.15,N,1318.04,E,30.1,120.0,030308,11.2,W,A*31 +$GPGGA,120440,5231.15,N,1318.05,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120440,A,5231.15,N,1318.05,E,31.6,122.0,030308,11.2,W,A*3a +$GPGGA,120441,5231.14,N,1318.07,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120441,A,5231.14,N,1318.07,E,32.6,119.0,030308,11.2,W,A*33 +$GPGGA,120442,5231.14,N,1318.08,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120442,A,5231.14,N,1318.08,E,33.5,117.0,030308,11.2,W,A*33 +$GPGGA,120443,5231.13,N,1318.1,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,120443,A,5231.13,N,1318.1,E,34.5,118.0,030308,11.2,W,A*04 +$GPGGA,120444,5231.13,N,1318.11,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120444,A,5231.13,N,1318.11,E,35.5,118.0,030308,11.2,W,A*33 +$GPGGA,120445,5231.12,N,1318.12,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120445,A,5231.12,N,1318.12,E,36.4,118.0,030308,11.2,W,A*32 +$GPGGA,120446,5231.12,N,1318.14,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120446,A,5231.12,N,1318.14,E,36.4,115.0,030308,11.2,W,A*3a +$GPGGA,120447,5231.12,N,1318.15,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120447,A,5231.12,N,1318.15,E,36.4,121.0,030308,11.2,W,A*3d +$GPGGA,120448,5231.11,N,1318.17,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120448,A,5231.11,N,1318.17,E,36.4,116.0,030308,11.2,W,A*37 +$GPGGA,120449,5231.11,N,1318.18,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120449,A,5231.11,N,1318.18,E,35.5,116.0,030308,11.2,W,A*3b +$GPGGA,120450,5231.1,N,1318.2,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120450,A,5231.1,N,1318.2,E,35.0,117.0,030308,11.2,W,A*3d +$GPGGA,120451,5231.1,N,1318.21,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120451,A,5231.1,N,1318.21,E,34.5,115.0,030308,11.2,W,A*0b +$GPGGA,120452,5231.09,N,1318.22,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120452,A,5231.09,N,1318.22,E,33.5,119.0,030308,11.2,W,A*38 +$GPGGA,120453,5231.09,N,1318.24,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120453,A,5231.09,N,1318.24,E,32.6,115.0,030308,11.2,W,A*31 +$GPGGA,120454,5231.08,N,1318.25,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120454,A,5231.08,N,1318.25,E,32.1,115.0,030308,11.2,W,A*31 +$GPGGA,120455,5231.08,N,1318.26,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120455,A,5231.08,N,1318.26,E,32.1,115.0,030308,11.2,W,A*33 +$GPGGA,120456,5231.08,N,1318.28,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120456,A,5231.08,N,1318.28,E,31.1,115.0,030308,11.2,W,A*3d +$GPGGA,120457,5231.07,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120457,A,5231.07,N,1318.29,E,31.1,114.0,030308,11.2,W,A*33 +$GPGGA,120458,5231.07,N,1318.3,E,1,07,1.3,50.6,M,39.2,M,,*7c +$GPRMC,120458,A,5231.07,N,1318.3,E,31.1,117.0,030308,11.2,W,A*07 +$GPGGA,120459,5231.07,N,1318.31,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120459,A,5231.07,N,1318.31,E,31.6,116.0,030308,11.2,W,A*31 +$GPGGA,120500,5231.06,N,1318.33,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120500,A,5231.06,N,1318.33,E,32.1,120.0,030308,11.2,W,A*3e +$GPGGA,120501,5231.06,N,1318.34,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120501,A,5231.06,N,1318.34,E,32.6,124.0,030308,11.2,W,A*3b +$GPGGA,120502,5231.05,N,1318.35,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120502,A,5231.05,N,1318.35,E,33.0,124.0,030308,11.2,W,A*3d +$GPGGA,120503,5231.05,N,1318.37,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120503,A,5231.05,N,1318.37,E,34.0,107.0,030308,11.2,W,A*38 +$GPGGA,120504,5231.04,N,1318.38,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120504,A,5231.04,N,1318.38,E,33.5,114.0,030308,11.2,W,A*31 +$GPGGA,120505,5231.04,N,1318.39,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120505,A,5231.04,N,1318.39,E,34.0,116.0,030308,11.2,W,A*31 +$GPGGA,120506,5231.04,N,1318.41,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120506,A,5231.04,N,1318.41,E,34.5,112.0,030308,11.2,W,A*3c +$GPGGA,120507,5231.03,N,1318.42,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120507,A,5231.03,N,1318.42,E,35.0,116.0,030308,11.2,W,A*39 +$GPGGA,120508,5231.03,N,1318.44,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120508,A,5231.03,N,1318.44,E,35.5,120.0,030308,11.2,W,A*30 +$GPGGA,120509,5231.02,N,1318.45,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120509,A,5231.02,N,1318.45,E,35.5,120.0,030308,11.2,W,A*31 +$GPGGA,120510,5231.02,N,1318.47,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120510,A,5231.02,N,1318.47,E,36.4,120.0,030308,11.2,W,A*39 +$GPGGA,120511,5231.01,N,1318.48,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120511,A,5231.01,N,1318.48,E,36.0,118.0,030308,11.2,W,A*3b +$GPGGA,120512,5231.01,N,1318.5,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120512,A,5231.01,N,1318.5,E,36.4,103.0,030308,11.2,W,A*0f +$GPGGA,120513,5231.01,N,1318.51,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120513,A,5231.01,N,1318.51,E,36.4,115.0,030308,11.2,W,A*38 +$GPGGA,120514,5231,N,1318.53,E,1,07,1.3,50.6,M,39.2,M,,*69 +$GPRMC,120514,A,5231,N,1318.53,E,36.4,125.0,030308,11.2,W,A*11 +$GPGGA,120515,5231,N,1318.54,E,1,07,1.3,50.6,M,39.2,M,,*6f +$GPRMC,120515,A,5231,N,1318.54,E,36.0,102.0,030308,11.2,W,A*16 +$GPGGA,120516,5230.99,N,1318.56,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120516,A,5230.99,N,1318.56,E,35.5,110.0,030308,11.2,W,A*3d +$GPGGA,120517,5230.99,N,1318.57,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120517,A,5230.99,N,1318.57,E,34.0,125.0,030308,11.2,W,A*3f +$GPGGA,120518,5230.98,N,1318.58,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120518,A,5230.98,N,1318.58,E,33.5,127.0,030308,11.2,W,A*3e +$GPGGA,120519,5230.98,N,1318.6,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120519,A,5230.98,N,1318.6,E,33.5,125.0,030308,11.2,W,A*06 +$GPGGA,120520,5230.97,N,1318.61,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120520,A,5230.97,N,1318.61,E,33.0,134.0,030308,11.2,W,A*37 +$GPGGA,120521,5230.96,N,1318.63,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120521,A,5230.96,N,1318.63,E,32.6,116.0,030308,11.2,W,A*32 +$GPGGA,120522,5230.96,N,1318.64,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120522,A,5230.96,N,1318.64,E,31.6,116.0,030308,11.2,W,A*35 +$GPGGA,120523,5230.95,N,1318.67,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120523,A,5230.95,N,1318.67,E,31.6,120.0,030308,11.2,W,A*31 +$GPGGA,120524,5230.95,N,1318.68,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120524,A,5230.95,N,1318.68,E,33.0,114.0,030308,11.2,W,A*3a +$GPGGA,120525,5230.94,N,1318.7,E,1,07,1.3,50.6,M,39.2,M,,*78 +$GPRMC,120525,A,5230.94,N,1318.7,E,33.0,107.0,030308,11.2,W,A*01 +$GPGGA,120526,5230.94,N,1318.71,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120526,A,5230.94,N,1318.71,E,33.0,111.0,030308,11.2,W,A*34 +$GPGGA,120527,5230.93,N,1318.74,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120527,A,5230.93,N,1318.74,E,33.0,122.0,030308,11.2,W,A*37 +$GPGGA,120528,5230.93,N,1318.75,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120528,A,5230.93,N,1318.75,E,33.0,102.0,030308,11.2,W,A*3b +$GPGGA,120529,5230.92,N,1318.77,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120529,A,5230.92,N,1318.77,E,33.5,116.0,030308,11.2,W,A*39 +$GPGGA,120530,5230.92,N,1318.78,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120530,A,5230.92,N,1318.78,E,33.5,117.0,030308,11.2,W,A*3f +$GPGGA,120531,5230.91,N,1318.79,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120531,A,5230.91,N,1318.79,E,33.0,126.0,030308,11.2,W,A*3b +$GPGGA,120532,5230.91,N,1318.8,E,1,07,1.3,50.6,M,39.2,M,,*74 +$GPRMC,120532,A,5230.91,N,1318.8,E,33.0,115.0,030308,11.2,W,A*0e +$GPGGA,120533,5230.91,N,1318.82,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120533,A,5230.91,N,1318.82,E,33.0,117.0,030308,11.2,W,A*3f +$GPGGA,120534,5230.9,N,1318.83,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120534,A,5230.9,N,1318.83,E,33.0,118.0,030308,11.2,W,A*07 +$GPGGA,120535,5230.9,N,1318.84,E,1,07,1.3,50.6,M,39.2,M,,*76 +$GPRMC,120535,A,5230.9,N,1318.84,E,31.1,119.0,030308,11.2,W,A*03 +$GPGGA,120536,5230.89,N,1318.86,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120536,A,5230.89,N,1318.86,E,28.7,116.0,030308,11.2,W,A*3b +$GPGGA,120537,5230.89,N,1318.87,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120537,A,5230.89,N,1318.87,E,25.3,110.0,030308,11.2,W,A*34 +$GPGGA,120538,5230.89,N,1318.88,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120538,A,5230.89,N,1318.88,E,22.4,101.0,030308,11.2,W,A*34 +$GPGGA,120539,5230.88,N,1318.88,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120539,A,5230.88,N,1318.88,E,18.0,153.0,030308,11.2,W,A*3e +$GPGGA,120540,5230.88,N,1318.88,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120540,A,5230.88,N,1318.88,E,2.9,142.0,030308,11.2,W,A*02 +$GPGGA,120541,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120541,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2a +$GPGGA,120542,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120542,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*29 +$GPGGA,120543,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120543,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*28 +$GPGGA,120544,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120544,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2f +$GPGGA,120545,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120545,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2e +$GPGGA,120546,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120546,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2d +$GPGGA,120547,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120547,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2c +$GPGGA,120548,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120548,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*23 +$GPGGA,120549,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120549,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*22 +$GPGGA,120550,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120550,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2a +$GPGGA,120551,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120551,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2b +$GPGGA,120552,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120552,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*28 +$GPGGA,120553,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120553,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*29 +$GPGGA,120554,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120554,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2e +$GPGGA,120555,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120555,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2f +$GPGGA,120556,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120556,A,5230.88,N,1318.89,E,0,93.0,030308,11.2,W,A*2c +$GPGGA,120557,5230.88,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120557,A,5230.88,N,1318.89,E,5.3,124.0,030308,11.2,W,A*08 +$GPGGA,120558,5230.88,N,1318.9,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,120558,A,5230.88,N,1318.9,E,17.5,133.0,030308,11.2,W,A*0c +$GPGGA,120559,5230.88,N,1318.9,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120559,A,5230.88,N,1318.9,E,23.3,117.0,030308,11.2,W,A*0a +$GPGGA,120600,5230.87,N,1318.92,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120600,A,5230.87,N,1318.92,E,25.3,114.0,030308,11.2,W,A*3d +$GPGGA,120601,5230.87,N,1318.93,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120601,A,5230.87,N,1318.93,E,31.1,113.0,030308,11.2,W,A*3d +$GPGGA,120602,5230.87,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120602,A,5230.87,N,1318.94,E,35.0,104.0,030308,11.2,W,A*3a +$GPGGA,120603,5230.86,N,1318.95,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120603,A,5230.86,N,1318.95,E,38.9,118.0,030308,11.2,W,A*32 +$GPGGA,120604,5230.86,N,1318.96,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120604,A,5230.86,N,1318.96,E,31.1,109.0,030308,11.2,W,A*37 +$GPGGA,120605,5230.86,N,1318.98,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120605,A,5230.86,N,1318.98,E,30.6,116.0,030308,11.2,W,A*30 +$GPGGA,120606,5230.85,N,1318.99,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120606,A,5230.85,N,1318.99,E,30.6,107.0,030308,11.2,W,A*31 +$GPGGA,120607,5230.85,N,1319,E,1,07,1.3,50.6,M,39.2,M,,*63 +$GPRMC,120607,A,5230.85,N,1319,E,30.1,133.0,030308,11.2,W,A*1f +$GPGGA,120608,5230.84,N,1319.01,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120608,A,5230.84,N,1319.01,E,30.1,126.0,030308,11.2,W,A*3a +$GPGGA,120609,5230.84,N,1319.03,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120609,A,5230.84,N,1319.03,E,31.6,119.0,030308,11.2,W,A*33 +$GPGGA,120610,5230.83,N,1319.05,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120610,A,5230.83,N,1319.05,E,31.6,121.0,030308,11.2,W,A*31 +$GPGGA,120611,5230.83,N,1319.06,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120611,A,5230.83,N,1319.06,E,31.6,109.0,030308,11.2,W,A*39 +$GPGGA,120612,5230.83,N,1319.08,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120612,A,5230.83,N,1319.08,E,32.1,94.0,030308,11.2,W,A*05 +$GPGGA,120613,5230.83,N,1319.09,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120613,A,5230.83,N,1319.09,E,32.6,101.0,030308,11.2,W,A*3f +$GPGGA,120614,5230.82,N,1319.11,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120614,A,5230.82,N,1319.11,E,33.0,94.0,030308,11.2,W,A*0a +$GPGGA,120615,5230.82,N,1319.12,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120615,A,5230.82,N,1319.12,E,33.0,103.0,030308,11.2,W,A*37 +$GPGGA,120616,5230.82,N,1319.14,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120616,A,5230.82,N,1319.14,E,33.0,100.0,030308,11.2,W,A*31 +$GPGGA,120617,5230.82,N,1319.15,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120617,A,5230.82,N,1319.15,E,32.1,94.0,030308,11.2,W,A*0d +$GPGGA,120618,5230.81,N,1319.18,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120618,A,5230.81,N,1319.18,E,32.1,115.0,030308,11.2,W,A*34 +$GPGGA,120619,5230.81,N,1319.19,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120619,A,5230.81,N,1319.19,E,30.1,113.0,030308,11.2,W,A*30 +$GPGGA,120620,5230.81,N,1319.2,E,1,07,1.3,50.6,M,39.2,M,,*7e +$GPRMC,120620,A,5230.81,N,1319.2,E,28.2,107.0,030308,11.2,W,A*0f +$GPGGA,120621,5230.8,N,1319.21,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120621,A,5230.8,N,1319.21,E,25.3,107.0,030308,11.2,W,A*02 +$GPGGA,120622,5230.8,N,1319.22,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120622,A,5230.8,N,1319.22,E,21.4,117.0,030308,11.2,W,A*00 +$GPGGA,120623,5230.8,N,1319.23,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120623,A,5230.8,N,1319.23,E,0,116.0,030308,11.2,W,A*28 +$GPGGA,120624,5230.8,N,1319.23,E,1,07,1.3,50.6,M,39.2,M,,*78 +$GPRMC,120624,A,5230.8,N,1319.23,E,0,121.0,030308,11.2,W,A*2b +$GPGGA,120625,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*7e +$GPRMC,120625,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*28 +$GPGGA,120626,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*7d +$GPRMC,120626,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*2b +$GPGGA,120627,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*7c +$GPRMC,120627,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*2a +$GPGGA,120628,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120628,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*25 +$GPGGA,120629,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*72 +$GPRMC,120629,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*24 +$GPGGA,120630,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120630,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*2c +$GPGGA,120631,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*7b +$GPRMC,120631,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*2d +$GPGGA,120632,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*78 +$GPRMC,120632,A,5230.8,N,1319.24,E,0,117.0,030308,11.2,W,A*2e +$GPGGA,120633,5230.79,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120633,A,5230.79,N,1319.25,E,1.9,125.0,030308,11.2,W,A*0f +$GPGGA,120634,5230.79,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120634,A,5230.79,N,1319.25,E,11.7,139.0,030308,11.2,W,A*3a +$GPGGA,120635,5230.79,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120635,A,5230.79,N,1319.25,E,11.7,157.0,030308,11.2,W,A*33 +$GPGGA,120636,5230.78,N,1319.26,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120636,A,5230.78,N,1319.26,E,19.4,163.0,030308,11.2,W,A*3e +$GPGGA,120637,5230.77,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120637,A,5230.77,N,1319.25,E,20.4,196.0,030308,11.2,W,A*33 +$GPGGA,120638,5230.77,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120638,A,5230.77,N,1319.25,E,19.4,200.0,030308,11.2,W,A*3a +$GPGGA,120639,5230.76,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120639,A,5230.76,N,1319.25,E,20.4,183.0,030308,11.2,W,A*38 +$GPGGA,120640,5230.75,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120640,A,5230.75,N,1319.25,E,20.4,175.0,030308,11.2,W,A*3c +$GPGGA,120641,5230.74,N,1319.25,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120641,A,5230.74,N,1319.25,E,21.9,163.0,030308,11.2,W,A*37 +$GPGGA,120642,5230.74,N,1319.26,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120642,A,5230.74,N,1319.26,E,22.8,155.0,030308,11.2,W,A*30 +$GPGGA,120643,5230.73,N,1319.26,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120643,A,5230.73,N,1319.26,E,22.8,144.0,030308,11.2,W,A*36 +$GPGGA,120644,5230.72,N,1319.27,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120644,A,5230.72,N,1319.27,E,23.8,139.0,030308,11.2,W,A*3a +$GPGGA,120645,5230.73,N,1319.36,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120645,A,5230.73,N,1319.36,E,24.7,85.0,030308,11.2,W,A*04 +$GPGGA,120646,5230.74,N,1319.37,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120646,A,5230.74,N,1319.37,E,25.8,26.0,030308,11.2,W,A*06 +$GPGGA,120647,5230.75,N,1319.38,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120647,A,5230.75,N,1319.38,E,24.8,18.0,030308,11.2,W,A*05 +$GPGGA,120648,5230.76,N,1319.38,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120648,A,5230.76,N,1319.38,E,24.3,351.0,030308,11.2,W,A*3c +$GPGGA,120649,5230.76,N,1319.37,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120649,A,5230.76,N,1319.37,E,24.8,344.0,030308,11.2,W,A*3d +$GPGGA,120650,5230.77,N,1319.37,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120650,A,5230.77,N,1319.37,E,25.8,342.0,030308,11.2,W,A*33 +$GPGGA,120651,5230.78,N,1319.36,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120651,A,5230.78,N,1319.36,E,26.7,323.0,030308,11.2,W,A*37 +$GPGGA,120652,5230.78,N,1319.35,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120652,A,5230.78,N,1319.35,E,26.7,313.0,030308,11.2,W,A*34 +$GPGGA,120653,5230.79,N,1319.34,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120653,A,5230.79,N,1319.34,E,27.7,302.0,030308,11.2,W,A*34 +$GPGGA,120654,5230.79,N,1319.33,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120654,A,5230.79,N,1319.33,E,27.6,271.0,030308,11.2,W,A*30 +$GPGGA,120655,5230.79,N,1319.32,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120655,A,5230.79,N,1319.32,E,27.4,278.0,030308,11.2,W,A*3b +$GPGGA,120656,5230.79,N,1319.3,E,1,07,1.3,50.6,M,39.2,M,,*79 +$GPRMC,120656,A,5230.79,N,1319.3,E,27.2,274.0,030308,11.2,W,A*00 +$GPGGA,120657,5230.79,N,1319.29,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120657,A,5230.79,N,1319.29,E,26.2,274.0,030308,11.2,W,A*38 +$GPGGA,120658,5230.79,N,1319.28,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120658,A,5230.79,N,1319.28,E,25.8,284.0,030308,11.2,W,A*30 +$GPGGA,120659,5230.79,N,1319.27,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120659,A,5230.79,N,1319.27,E,26.7,292.0,030308,11.2,W,A*35 +$GPGGA,120700,5230.8,N,1319.26,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120700,A,5230.8,N,1319.26,E,28.2,299.0,030308,11.2,W,A*0f +$GPGGA,120701,5230.8,N,1319.24,E,1,07,1.3,50.6,M,39.2,M,,*79 +$GPRMC,120701,A,5230.8,N,1319.24,E,29.6,294.0,030308,11.2,W,A*04 +$GPGGA,120702,5230.8,N,1319.23,E,1,07,1.3,50.6,M,39.2,M,,*7d +$GPRMC,120702,A,5230.8,N,1319.23,E,30.6,294.0,030308,11.2,W,A*08 +$GPGGA,120703,5230.81,N,1319.22,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120703,A,5230.81,N,1319.22,E,33.0,295.0,030308,11.2,W,A*3d +$GPGGA,120704,5230.81,N,1319.2,E,1,07,1.3,50.6,M,39.2,M,,*79 +$GPRMC,120704,A,5230.81,N,1319.2,E,34.0,291.0,030308,11.2,W,A*0b +$GPGGA,120705,5230.82,N,1319.19,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120705,A,5230.82,N,1319.19,E,35.0,290.0,030308,11.2,W,A*33 +$GPGGA,120706,5230.82,N,1319.17,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120706,A,5230.82,N,1319.17,E,35.0,281.0,030308,11.2,W,A*3e +$GPGGA,120707,5230.82,N,1319.16,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120707,A,5230.82,N,1319.16,E,34.5,290.0,030308,11.2,W,A*3a +$GPGGA,120708,5230.82,N,1319.14,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120708,A,5230.82,N,1319.14,E,34.0,283.0,030308,11.2,W,A*30 +$GPGGA,120709,5230.83,N,1319.13,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120709,A,5230.83,N,1319.13,E,33.5,282.0,030308,11.2,W,A*34 +$GPGGA,120710,5230.83,N,1319.11,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120710,A,5230.83,N,1319.11,E,31.6,291.0,030308,11.2,W,A*3d +$GPGGA,120711,5230.83,N,1319.1,E,1,07,1.3,50.6,M,39.2,M,,*7c +$GPRMC,120711,A,5230.83,N,1319.1,E,31.6,276.0,030308,11.2,W,A*04 +$GPGGA,120712,5230.83,N,1319.09,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120712,A,5230.83,N,1319.09,E,31.1,283.0,030308,11.2,W,A*32 +$GPGGA,120713,5230.83,N,1319.07,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120713,A,5230.83,N,1319.07,E,31.6,285.0,030308,11.2,W,A*3c +$GPGGA,120714,5230.84,N,1319.06,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120714,A,5230.84,N,1319.06,E,32.1,288.0,030308,11.2,W,A*34 +$GPGGA,120715,5230.84,N,1319.04,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120715,A,5230.84,N,1319.04,E,33.0,294.0,030308,11.2,W,A*3a +$GPGGA,120716,5230.85,N,1319.03,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120716,A,5230.85,N,1319.03,E,33.0,297.0,030308,11.2,W,A*3c +$GPGGA,120717,5230.85,N,1319.02,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120717,A,5230.85,N,1319.02,E,32.6,293.0,030308,11.2,W,A*3f +$GPGGA,120718,5230.85,N,1319,E,1,07,1.3,50.6,M,39.2,M,,*6c +$GPRMC,120718,A,5230.85,N,1319,E,31.1,295.0,030308,11.2,W,A*1e +$GPGGA,120719,5230.86,N,1318.99,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120719,A,5230.86,N,1318.99,E,29.2,296.0,030308,11.2,W,A*3a +$GPGGA,120720,5230.86,N,1318.98,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120720,A,5230.86,N,1318.98,E,27.7,301.0,030308,11.2,W,A*35 +$GPGGA,120721,5230.86,N,1318.97,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120721,A,5230.86,N,1318.97,E,24.8,292.0,030308,11.2,W,A*3c +$GPGGA,120722,5230.87,N,1318.96,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120722,A,5230.87,N,1318.96,E,21.9,302.0,030308,11.2,W,A*33 +$GPGGA,120723,5230.87,N,1318.95,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120723,A,5230.87,N,1318.95,E,11.7,293.0,030308,11.2,W,A*35 +$GPGGA,120724,5230.87,N,1318.95,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120724,A,5230.87,N,1318.95,E,7.8,300.0,030308,11.2,W,A*01 +$GPGGA,120725,5230.87,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120725,A,5230.87,N,1318.94,E,3.9,298.0,030308,11.2,W,A*04 +$GPGGA,120726,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120726,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*19 +$GPGGA,120727,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120727,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*18 +$GPGGA,120728,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120728,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*17 +$GPGGA,120729,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120729,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*16 +$GPGGA,120730,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120730,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*1e +$GPGGA,120731,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120731,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*1f +$GPGGA,120732,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120732,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*1c +$GPGGA,120733,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120733,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*1d +$GPGGA,120734,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120734,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*1a +$GPGGA,120735,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120735,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*1b +$GPGGA,120736,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120736,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*18 +$GPGGA,120737,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120737,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*19 +$GPGGA,120738,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120738,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*16 +$GPGGA,120739,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120739,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*17 +$GPGGA,120740,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120740,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*19 +$GPGGA,120741,5230.88,N,1318.94,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120741,A,5230.88,N,1318.94,E,0,305.0,030308,11.2,W,A*18 +$GPGGA,120742,5230.88,N,1318.93,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120742,A,5230.88,N,1318.93,E,1.0,295.0,030308,11.2,W,A*0b +$GPGGA,120743,5230.88,N,1318.93,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120743,A,5230.88,N,1318.93,E,3.9,314.0,030308,11.2,W,A*09 +$GPGGA,120744,5230.88,N,1318.93,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120744,A,5230.88,N,1318.93,E,11.7,296.0,030308,11.2,W,A*38 +$GPGGA,120745,5230.88,N,1318.92,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120745,A,5230.88,N,1318.92,E,15.6,286.0,030308,11.2,W,A*3c +$GPGGA,120746,5230.88,N,1318.92,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120746,A,5230.88,N,1318.92,E,23.3,303.0,030308,11.2,W,A*33 +$GPGGA,120747,5230.88,N,1318.91,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120747,A,5230.88,N,1318.91,E,25.3,298.0,030308,11.2,W,A*34 +$GPGGA,120748,5230.89,N,1318.9,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,120748,A,5230.89,N,1318.9,E,29.2,298.0,030308,11.2,W,A*06 +$GPGGA,120749,5230.89,N,1318.89,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120749,A,5230.89,N,1318.89,E,29.2,298.0,030308,11.2,W,A*3f +$GPGGA,120750,5230.89,N,1318.88,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120750,A,5230.89,N,1318.88,E,29.2,303.0,030308,11.2,W,A*35 +$GPGGA,120751,5230.9,N,1318.87,E,1,07,1.3,50.6,M,39.2,M,,*75 +$GPRMC,120751,A,5230.9,N,1318.87,E,29.2,300.0,030308,11.2,W,A*00 +$GPGGA,120752,5230.9,N,1318.86,E,1,07,1.3,50.6,M,39.2,M,,*77 +$GPRMC,120752,A,5230.9,N,1318.86,E,29.2,294.0,030308,11.2,W,A*0e +$GPGGA,120753,5230.9,N,1318.85,E,1,07,1.3,50.6,M,39.2,M,,*75 +$GPRMC,120753,A,5230.9,N,1318.85,E,29.2,296.0,030308,11.2,W,A*0e +$GPGGA,120754,5230.91,N,1318.84,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120754,A,5230.91,N,1318.84,E,25.3,294.0,030308,11.2,W,A*36 +$GPGGA,120755,5230.91,N,1318.83,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120755,A,5230.91,N,1318.83,E,25.8,298.0,030308,11.2,W,A*37 +$GPGGA,120756,5230.91,N,1318.82,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120756,A,5230.91,N,1318.82,E,26.2,293.0,030308,11.2,W,A*37 +$GPGGA,120757,5230.92,N,1318.8,E,1,07,1.3,50.6,M,39.2,M,,*76 +$GPRMC,120757,A,5230.92,N,1318.8,E,27.2,297.0,030308,11.2,W,A*02 +$GPGGA,120758,5230.92,N,1318.79,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120758,A,5230.92,N,1318.79,E,29.2,296.0,030308,11.2,W,A*34 +$GPGGA,120759,5230.93,N,1318.77,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120759,A,5230.93,N,1318.77,E,35.0,293.0,030308,11.2,W,A*30 +$GPGGA,120800,5230.93,N,1318.76,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120800,A,5230.93,N,1318.76,E,36.9,300.0,030308,11.2,W,A*33 +$GPGGA,120801,5230.94,N,1318.74,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120801,A,5230.94,N,1318.74,E,38.9,296.0,030308,11.2,W,A*37 +$GPGGA,120802,5230.94,N,1318.73,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120802,A,5230.94,N,1318.73,E,38.9,303.0,030308,11.2,W,A*3e +$GPGGA,120803,5230.95,N,1318.71,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120803,A,5230.95,N,1318.71,E,38.9,299.0,030308,11.2,W,A*3e +$GPGGA,120804,5230.95,N,1318.69,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120804,A,5230.95,N,1318.69,E,38.9,295.0,030308,11.2,W,A*3c +$GPGGA,120805,5230.96,N,1318.67,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120805,A,5230.96,N,1318.67,E,38.9,298.0,030308,11.2,W,A*3d +$GPGGA,120806,5230.96,N,1318.66,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120806,A,5230.96,N,1318.66,E,38.9,297.0,030308,11.2,W,A*30 +$GPGGA,120807,5230.97,N,1318.65,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120807,A,5230.97,N,1318.65,E,38.9,303.0,030308,11.2,W,A*3f +$GPGGA,120808,5230.97,N,1318.64,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120808,A,5230.97,N,1318.64,E,38.9,298.0,030308,11.2,W,A*32 +$GPGGA,120809,5230.98,N,1318.62,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120809,A,5230.98,N,1318.62,E,26.2,300.0,030308,11.2,W,A*3e +$GPGGA,120810,5230.98,N,1318.61,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120810,A,5230.98,N,1318.61,E,25.8,292.0,030308,11.2,W,A*36 +$GPGGA,120811,5230.98,N,1318.6,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120811,A,5230.98,N,1318.6,E,25.8,295.0,030308,11.2,W,A*01 +$GPGGA,120812,5230.99,N,1318.59,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120812,A,5230.99,N,1318.59,E,23.3,297.0,030308,11.2,W,A*36 +$GPGGA,120813,5230.99,N,1318.57,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120813,A,5230.99,N,1318.57,E,19.4,297.0,030308,11.2,W,A*37 +$GPGGA,120814,5230.99,N,1318.56,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120814,A,5230.99,N,1318.56,E,13.6,295.0,030308,11.2,W,A*3b +$GPGGA,120815,5231,N,1318.55,E,1,07,1.3,50.6,M,39.2,M,,*63 +$GPRMC,120815,A,5231,N,1318.55,E,13.6,300.0,030308,11.2,W,A*1b +$GPGGA,120816,5231,N,1318.54,E,1,07,1.3,50.6,M,39.2,M,,*61 +$GPRMC,120816,A,5231,N,1318.54,E,13.6,299.0,030308,11.2,W,A*18 +$GPGGA,120817,5231.01,N,1318.53,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120817,A,5231.01,N,1318.53,E,19.4,298.0,030308,11.2,W,A*38 +$GPGGA,120818,5231.01,N,1318.52,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120818,A,5231.01,N,1318.52,E,30.6,298.0,030308,11.2,W,A*3f +$GPGGA,120819,5231.01,N,1318.5,E,1,07,1.3,50.6,M,39.2,M,,*75 +$GPRMC,120819,A,5231.01,N,1318.5,E,31.1,297.0,030308,11.2,W,A*05 +$GPGGA,120820,5231.02,N,1318.49,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120820,A,5231.02,N,1318.49,E,31.1,299.0,030308,11.2,W,A*3a +$GPGGA,120821,5231.02,N,1318.48,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,120821,A,5231.02,N,1318.48,E,31.1,298.0,030308,11.2,W,A*3b +$GPGGA,120822,5231.03,N,1318.47,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120822,A,5231.03,N,1318.47,E,30.6,299.0,030308,11.2,W,A*31 +$GPGGA,120823,5231.03,N,1318.45,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120823,A,5231.03,N,1318.45,E,30.1,302.0,030308,11.2,W,A*36 +$GPGGA,120824,5231.04,N,1318.44,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120824,A,5231.04,N,1318.44,E,30.1,299.0,030308,11.2,W,A*34 +$GPGGA,120825,5231.04,N,1318.43,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120825,A,5231.04,N,1318.43,E,35.0,298.0,030308,11.2,W,A*37 +$GPGGA,120826,5231.05,N,1318.41,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120826,A,5231.05,N,1318.41,E,35.0,298.0,030308,11.2,W,A*37 +$GPGGA,120827,5231.05,N,1318.4,E,1,07,1.3,50.6,M,39.2,M,,*7d +$GPRMC,120827,A,5231.05,N,1318.4,E,27.7,297.0,030308,11.2,W,A*0c +$GPGGA,120828,5231.05,N,1318.38,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120828,A,5231.05,N,1318.38,E,27.2,295.0,030308,11.2,W,A*3b +$GPGGA,120829,5231.06,N,1318.37,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120829,A,5231.06,N,1318.37,E,27.2,291.0,030308,11.2,W,A*32 +$GPGGA,120830,5231.06,N,1318.36,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120830,A,5231.06,N,1318.36,E,25.3,302.0,030308,11.2,W,A*33 +$GPGGA,120831,5231.06,N,1318.35,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120831,A,5231.06,N,1318.35,E,23.3,301.0,030308,11.2,W,A*34 +$GPGGA,120832,5231.07,N,1318.34,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120832,A,5231.07,N,1318.34,E,19.4,295.0,030308,11.2,W,A*35 +$GPGGA,120833,5231.07,N,1318.33,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120833,A,5231.07,N,1318.33,E,15.6,297.0,030308,11.2,W,A*3f +$GPGGA,120834,5231.07,N,1318.32,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120834,A,5231.07,N,1318.32,E,9.7,300.0,030308,11.2,W,A*0a +$GPGGA,120835,5231.08,N,1318.32,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120835,A,5231.08,N,1318.32,E,5.8,300.0,030308,11.2,W,A*07 +$GPGGA,120836,5231.08,N,1318.31,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120836,A,5231.08,N,1318.31,E,3.9,298.0,030308,11.2,W,A*00 +$GPGGA,120837,5231.08,N,1318.31,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120837,A,5231.08,N,1318.31,E,1.9,289.0,030308,11.2,W,A*03 +$GPGGA,120838,5231.08,N,1318.3,E,1,07,1.3,50.6,M,39.2,M,,*79 +$GPRMC,120838,A,5231.08,N,1318.3,E,1.9,300.0,030308,11.2,W,A*3d +$GPGGA,120839,5231.08,N,1318.3,E,1,07,1.3,50.6,M,39.2,M,,*78 +$GPRMC,120839,A,5231.08,N,1318.3,E,3.9,285.0,030308,11.2,W,A*32 +$GPGGA,120840,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120840,A,5231.08,N,1318.29,E,3.9,285.0,030308,11.2,W,A*04 +$GPGGA,120841,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120841,A,5231.08,N,1318.29,E,3.9,312.0,030308,11.2,W,A*0a +$GPGGA,120842,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120842,A,5231.08,N,1318.29,E,1.9,285.0,030308,11.2,W,A*04 +$GPGGA,120843,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120843,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*13 +$GPGGA,120844,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120844,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*14 +$GPGGA,120845,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120845,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*15 +$GPGGA,120846,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120846,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*16 +$GPGGA,120847,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120847,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*17 +$GPGGA,120848,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120848,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*18 +$GPGGA,120849,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120849,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*19 +$GPGGA,120850,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120850,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*11 +$GPGGA,120851,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120851,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*10 +$GPGGA,120852,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120852,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*13 +$GPGGA,120853,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120853,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*12 +$GPGGA,120854,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120854,A,5231.08,N,1318.29,E,0,285.0,030308,11.2,W,A*15 +$GPGGA,120855,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120855,A,5231.08,N,1318.29,E,7.8,285.0,030308,11.2,W,A*05 +$GPGGA,120856,5231.08,N,1318.29,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120856,A,5231.08,N,1318.29,E,9.7,240.0,030308,11.2,W,A*0e +$GPGGA,120857,5231.08,N,1318.28,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120857,A,5231.08,N,1318.28,E,11.7,281.0,030308,11.2,W,A*3a +$GPGGA,120858,5231.09,N,1318.27,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120858,A,5231.09,N,1318.27,E,18.0,299.0,030308,11.2,W,A*3c +$GPGGA,120859,5231.09,N,1318.26,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120859,A,5231.09,N,1318.26,E,19.9,297.0,030308,11.2,W,A*3a +$GPGGA,120900,5231.09,N,1318.25,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120900,A,5231.09,N,1318.25,E,22.4,297.0,030308,11.2,W,A*31 +$GPGGA,120901,5231.1,N,1318.24,E,1,07,1.3,50.6,M,39.2,M,,*7e +$GPRMC,120901,A,5231.1,N,1318.24,E,22.8,303.0,030308,11.2,W,A*09 +$GPGGA,120902,5231.1,N,1318.23,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120902,A,5231.1,N,1318.23,E,21.9,293.0,030308,11.2,W,A*07 +$GPGGA,120903,5231.1,N,1318.22,E,1,07,1.3,50.6,M,39.2,M,,*7a +$GPRMC,120903,A,5231.1,N,1318.22,E,19.0,296.0,030308,11.2,W,A*00 +$GPGGA,120904,5231.1,N,1318.21,E,1,07,1.3,50.6,M,39.2,M,,*7e +$GPRMC,120904,A,5231.1,N,1318.21,E,15.1,300.0,030308,11.2,W,A*07 +$GPGGA,120905,5231.11,N,1318.2,E,1,07,1.3,50.6,M,39.2,M,,*7f +$GPRMC,120905,A,5231.11,N,1318.2,E,14.6,292.0,030308,11.2,W,A*0a +$GPGGA,120906,5231.11,N,1318.19,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120906,A,5231.11,N,1318.19,E,16.0,297.0,030308,11.2,W,A*32 +$GPGGA,120907,5231.11,N,1318.18,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120907,A,5231.11,N,1318.18,E,19.0,293.0,030308,11.2,W,A*39 +$GPGGA,120908,5231.12,N,1318.17,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120908,A,5231.12,N,1318.17,E,21.4,297.0,030308,11.2,W,A*31 +$GPGGA,120909,5231.12,N,1318.16,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120909,A,5231.12,N,1318.16,E,24.3,296.0,030308,11.2,W,A*32 +$GPGGA,120910,5231.12,N,1318.15,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120910,A,5231.12,N,1318.15,E,25.8,301.0,030308,11.2,W,A*3c +$GPGGA,120911,5231.13,N,1318.14,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120911,A,5231.13,N,1318.14,E,26.2,303.0,030308,11.2,W,A*36 +$GPGGA,120912,5231.13,N,1318.13,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120912,A,5231.13,N,1318.13,E,26.7,299.0,030308,11.2,W,A*35 +$GPGGA,120913,5231.14,N,1318.12,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120913,A,5231.14,N,1318.12,E,27.2,299.0,030308,11.2,W,A*36 +$GPGGA,120914,5231.14,N,1318.1,E,1,07,1.3,50.6,M,39.2,M,,*79 +$GPRMC,120914,A,5231.14,N,1318.1,E,28.2,297.0,030308,11.2,W,A*02 +$GPGGA,120915,5231.14,N,1318.09,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120915,A,5231.14,N,1318.09,E,29.2,304.0,030308,11.2,W,A*31 +$GPGGA,120916,5231.15,N,1318.08,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120916,A,5231.15,N,1318.08,E,29.6,302.0,030308,11.2,W,A*30 +$GPGGA,120917,5231.15,N,1318.07,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120917,A,5231.15,N,1318.07,E,30.6,305.0,030308,11.2,W,A*31 +$GPGGA,120918,5231.16,N,1318.06,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120918,A,5231.16,N,1318.06,E,31.6,305.0,030308,11.2,W,A*3d +$GPGGA,120919,5231.16,N,1318.05,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,120919,A,5231.16,N,1318.05,E,31.6,300.0,030308,11.2,W,A*3a +$GPGGA,120920,5231.17,N,1318.03,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120920,A,5231.17,N,1318.03,E,30.6,298.0,030308,11.2,W,A*36 +$GPGGA,120921,5231.17,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120921,A,5231.17,N,1318.02,E,28.2,296.0,030308,11.2,W,A*35 +$GPGGA,120922,5231.17,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120922,A,5231.17,N,1318.01,E,26.2,293.0,030308,11.2,W,A*3e +$GPGGA,120923,5231.18,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*6e +$GPRMC,120923,A,5231.18,N,1318,E,23.8,299.0,030308,11.2,W,A*1a +$GPGGA,120924,5231.18,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120924,A,5231.18,N,1317.99,E,21.4,298.0,030308,11.2,W,A*33 +$GPGGA,120925,5231.19,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120925,A,5231.19,N,1317.98,E,20.4,306.0,030308,11.2,W,A*35 +$GPGGA,120926,5231.19,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120926,A,5231.19,N,1317.98,E,21.9,354.0,030308,11.2,W,A*3d +$GPGGA,120927,5231.21,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120927,A,5231.21,N,1317.97,E,23.3,349.0,030308,11.2,W,A*3c +$GPGGA,120928,5231.22,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120928,A,5231.22,N,1317.97,E,28.7,352.0,030308,11.2,W,A*35 +$GPGGA,120929,5231.23,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120929,A,5231.23,N,1317.97,E,29.6,355.0,030308,11.2,W,A*32 +$GPGGA,120930,5231.24,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120930,A,5231.24,N,1317.97,E,30.1,4.0,030308,11.2,W,A*35 +$GPGGA,120931,5231.25,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120931,A,5231.25,N,1317.97,E,29.6,7.0,030308,11.2,W,A*39 +$GPGGA,120932,5231.26,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120932,A,5231.26,N,1317.98,E,31.6,18.0,030308,11.2,W,A*01 +$GPGGA,120933,5231.27,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,120933,A,5231.27,N,1317.98,E,33.5,20.0,030308,11.2,W,A*0b +$GPGGA,120934,5231.27,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,120934,A,5231.27,N,1317.99,E,33.5,22.0,030308,11.2,W,A*0f +$GPGGA,120935,5231.28,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120935,A,5231.28,N,1317.99,E,32.6,19.0,030308,11.2,W,A*0b +$GPGGA,120936,5231.29,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*68 +$GPRMC,120936,A,5231.29,N,1318,E,31.1,23.0,030308,11.2,W,A*25 +$GPGGA,120937,5231.3,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*51 +$GPRMC,120937,A,5231.3,N,1318,E,31.1,12.0,030308,11.2,W,A*1e +$GPGGA,120938,5231.31,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120938,A,5231.31,N,1318.01,E,29.6,16.0,030308,11.2,W,A*05 +$GPGGA,120939,5231.32,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,120939,A,5231.32,N,1318.02,E,25.3,21.0,030308,11.2,W,A*09 +$GPGGA,120940,5231.33,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120940,A,5231.33,N,1318.02,E,23.3,16.0,030308,11.2,W,A*04 +$GPGGA,120941,5231.34,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120941,A,5231.34,N,1318.02,E,23.3,13.0,030308,11.2,W,A*07 +$GPGGA,120942,5231.35,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120942,A,5231.35,N,1318.02,E,23.3,6.0,030308,11.2,W,A*31 +$GPGGA,120943,5231.36,N,1318.02,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,120943,A,5231.36,N,1318.02,E,20.4,347.0,030308,11.2,W,A*31 +$GPGGA,120944,5231.36,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120944,A,5231.36,N,1318.01,E,24.3,322.0,030308,11.2,W,A*35 +$GPGGA,120945,5231.37,N,1318.01,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120945,A,5231.37,N,1318.01,E,26.7,321.0,030308,11.2,W,A*30 +$GPGGA,120946,5231.38,N,1318,E,1,07,1.3,50.6,M,39.2,M,,*6f +$GPRMC,120946,A,5231.38,N,1318,E,28.7,320.0,030308,11.2,W,A*1c +$GPGGA,120947,5231.38,N,1317.99,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,120947,A,5231.38,N,1317.99,E,30.6,319.0,030308,11.2,W,A*3e +$GPGGA,120948,5231.39,N,1317.98,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,120948,A,5231.39,N,1317.98,E,32.1,323.0,030308,11.2,W,A*3d +$GPGGA,120949,5231.4,N,1317.97,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,120949,A,5231.4,N,1317.97,E,32.6,324.0,030308,11.2,W,A*0d +$GPGGA,120950,5231.4,N,1317.96,E,1,07,1.3,50.6,M,39.2,M,,*79 +$GPRMC,120950,A,5231.4,N,1317.96,E,32.6,325.0,030308,11.2,W,A*05 +$GPGGA,120951,5231.41,N,1317.95,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,120951,A,5231.41,N,1317.95,E,32.6,321.0,030308,11.2,W,A*32 +$GPGGA,120952,5231.42,N,1317.94,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,120952,A,5231.42,N,1317.94,E,33.0,326.0,030308,11.2,W,A*33 +$GPGGA,120953,5231.43,N,1317.93,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,120953,A,5231.43,N,1317.93,E,33.5,323.0,030308,11.2,W,A*34 +$GPGGA,120954,5231.44,N,1317.92,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,120954,A,5231.44,N,1317.92,E,32.6,323.0,030308,11.2,W,A*37 +$GPGGA,120955,5231.45,N,1317.91,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,120955,A,5231.45,N,1317.91,E,32.1,308.0,030308,11.2,W,A*3a +$GPGGA,120956,5231.45,N,1317.9,E,1,07,1.3,50.6,M,39.2,M,,*7c +$GPRMC,120956,A,5231.45,N,1317.9,E,32.1,331.0,030308,11.2,W,A*02 +$GPGGA,120957,5231.46,N,1317.89,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,120957,A,5231.46,N,1317.89,E,31.1,327.0,030308,11.2,W,A*3c +$GPGGA,120958,5231.47,N,1317.88,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,120958,A,5231.47,N,1317.88,E,31.1,317.0,030308,11.2,W,A*30 +$GPGGA,120959,5231.48,N,1317.88,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,120959,A,5231.48,N,1317.88,E,33.0,352.0,030308,11.2,W,A*3c +$GPGGA,121000,5231.49,N,1317.88,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121000,A,5231.49,N,1317.88,E,33.0,352.0,030308,11.2,W,A*39 +$GPGGA,121001,5231.5,N,1317.87,E,1,07,1.3,50.6,M,39.2,M,,*74 +$GPRMC,121001,A,5231.5,N,1317.87,E,33.0,341.0,030308,11.2,W,A*0d +$GPGGA,121002,5231.51,N,1317.87,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,121002,A,5231.51,N,1317.87,E,32.6,347.0,030308,11.2,W,A*3e +$GPGGA,121003,5231.52,N,1317.86,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121003,A,5231.52,N,1317.86,E,32.1,348.0,030308,11.2,W,A*35 +$GPGGA,121004,5231.53,N,1317.86,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,121004,A,5231.53,N,1317.86,E,31.6,349.0,030308,11.2,W,A*36 +$GPGGA,121005,5231.54,N,1317.86,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121005,A,5231.54,N,1317.86,E,30.6,350.0,030308,11.2,W,A*39 +$GPGGA,121006,5231.55,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121006,A,5231.55,N,1317.85,E,29.2,347.0,030308,11.2,W,A*32 +$GPGGA,121007,5231.56,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,121007,A,5231.56,N,1317.85,E,25.8,349.0,030308,11.2,W,A*38 +$GPGGA,121008,5231.57,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,121008,A,5231.57,N,1317.85,E,15.6,354.0,030308,11.2,W,A*37 +$GPGGA,121009,5231.58,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,121009,A,5231.58,N,1317.85,E,3.9,347.0,030308,11.2,W,A*03 +$GPGGA,121010,5231.58,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,121010,A,5231.58,N,1317.85,E,11.7,344.0,030308,11.2,W,A*35 +$GPGGA,121011,5231.58,N,1317.85,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,121011,A,5231.58,N,1317.85,E,13.6,356.0,030308,11.2,W,A*34 +$GPGGA,121012,5231.58,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,121012,A,5231.58,N,1317.84,E,15.6,299.0,030308,11.2,W,A*32 +$GPGGA,121013,5231.58,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,121013,A,5231.58,N,1317.84,E,15.6,335.0,030308,11.2,W,A*34 +$GPGGA,121014,5231.59,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,121014,A,5231.59,N,1317.84,E,19.4,350.0,030308,11.2,W,A*3f +$GPGGA,121015,5231.59,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121015,A,5231.59,N,1317.84,E,19.4,353.0,030308,11.2,W,A*3d +$GPGGA,121016,5231.61,N,1317.84,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,121016,A,5231.61,N,1317.84,E,25.3,347.0,030308,11.2,W,A*38 +$GPGGA,121017,5231.61,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121017,A,5231.61,N,1317.83,E,25.3,349.0,030308,11.2,W,A*30 +$GPGGA,121018,5231.62,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,121018,A,5231.62,N,1317.83,E,26.7,351.0,030308,11.2,W,A*32 +$GPGGA,121019,5231.63,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,121019,A,5231.63,N,1317.83,E,29.2,354.0,030308,11.2,W,A*3d +$GPGGA,121020,5231.64,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121020,A,5231.64,N,1317.83,E,30.1,349.0,030308,11.2,W,A*37 +$GPGGA,121021,5231.65,N,1317.83,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121021,A,5231.65,N,1317.83,E,31.1,350.0,030308,11.2,W,A*3e +$GPGGA,121022,5231.65,N,1317.82,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,121022,A,5231.65,N,1317.82,E,32.6,349.0,030308,11.2,W,A*30 +$GPGGA,121023,5231.66,N,1317.82,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121023,A,5231.66,N,1317.82,E,33.0,350.0,030308,11.2,W,A*3d +$GPGGA,121024,5231.67,N,1317.82,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121024,A,5231.67,N,1317.82,E,33.0,350.0,030308,11.2,W,A*3b +$GPGGA,121025,5231.68,N,1317.82,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,121025,A,5231.68,N,1317.82,E,33.5,346.0,030308,11.2,W,A*37 +$GPGGA,121026,5231.69,N,1317.81,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,121026,A,5231.69,N,1317.81,E,33.5,353.0,030308,11.2,W,A*32 +$GPGGA,121027,5231.7,N,1317.81,E,1,07,1.3,50.6,M,39.2,M,,*74 +$GPRMC,121027,A,5231.7,N,1317.81,E,33.0,354.0,030308,11.2,W,A*09 +$GPGGA,121028,5231.71,N,1317.81,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,121028,A,5231.71,N,1317.81,E,33.0,349.0,030308,11.2,W,A*3b +$GPGGA,121029,5231.72,N,1317.81,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,121029,A,5231.72,N,1317.81,E,31.1,348.0,030308,11.2,W,A*3b +$GPGGA,121030,5231.72,N,1317.8,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,121030,A,5231.72,N,1317.8,E,30.1,343.0,030308,11.2,W,A*08 +$GPGGA,121031,5231.73,N,1317.8,E,1,07,1.3,50.6,M,39.2,M,,*71 +$GPRMC,121031,A,5231.73,N,1317.8,E,28.2,345.0,030308,11.2,W,A*04 +$GPGGA,121032,5231.74,N,1317.8,E,1,07,1.3,50.6,M,39.2,M,,*75 +$GPRMC,121032,A,5231.74,N,1317.8,E,24.8,341.0,030308,11.2,W,A*02 +$GPGGA,121033,5231.74,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121033,A,5231.74,N,1317.79,E,20.4,348.0,030308,11.2,W,A*34 +$GPGGA,121034,5231.75,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121034,A,5231.75,N,1317.79,E,16.0,347.0,030308,11.2,W,A*3c +$GPGGA,121035,5231.75,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121035,A,5231.75,N,1317.79,E,14.6,354.0,030308,11.2,W,A*3b +$GPGGA,121036,5231.75,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,121036,A,5231.75,N,1317.79,E,3.9,336.0,030308,11.2,W,A*05 +$GPGGA,121037,5231.75,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,121037,A,5231.75,N,1317.79,E,2.9,290.0,030308,11.2,W,A*08 +$GPGGA,121038,5231.76,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121038,A,5231.76,N,1317.79,E,2.9,343.0,030308,11.2,W,A*0b +$GPGGA,121039,5231.76,N,1317.79,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,121039,A,5231.76,N,1317.79,E,13.6,344.0,030308,11.2,W,A*32 +$GPGGA,121040,5231.76,N,1317.78,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121040,A,5231.76,N,1317.78,E,17.5,339.0,030308,11.2,W,A*30 +$GPGGA,121041,5231.77,N,1317.78,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121041,A,5231.77,N,1317.78,E,19.9,352.0,030308,11.2,W,A*3f +$GPGGA,121042,5231.78,N,1317.78,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,121042,A,5231.78,N,1317.78,E,21.9,344.0,030308,11.2,W,A*3f +$GPGGA,121043,5231.79,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,121043,A,5231.79,N,1317.77,E,23.3,343.0,030308,11.2,W,A*3f +$GPGGA,121044,5231.8,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*77 +$GPRMC,121044,A,5231.8,N,1317.77,E,23.3,356.0,030308,11.2,W,A*0a +$GPGGA,121045,5231.81,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,121045,A,5231.81,N,1317.77,E,17.5,342.0,030308,11.2,W,A*3e +$GPGGA,121046,5231.81,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121046,A,5231.81,N,1317.77,E,11.2,352.0,030308,11.2,W,A*3d +$GPGGA,121047,5231.81,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121047,A,5231.81,N,1317.77,E,1.9,340.0,030308,11.2,W,A*05 +$GPGGA,121048,5231.81,N,1317.77,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,121048,A,5231.81,N,1317.77,E,1.9,343.0,030308,11.2,W,A*09 +$GPGGA,121049,5231.81,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,121049,A,5231.81,N,1317.76,E,1.5,324.0,030308,11.2,W,A*04 +$GPGGA,121050,5231.81,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121050,A,5231.81,N,1317.76,E,2.4,313.0,030308,11.2,W,A*0a +$GPGGA,121051,5231.81,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,121051,A,5231.81,N,1317.76,E,11.7,347.0,030308,11.2,W,A*3b +$GPGGA,121052,5231.82,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,121052,A,5231.82,N,1317.76,E,17.5,345.0,030308,11.2,W,A*3d +$GPGGA,121053,5231.82,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121053,A,5231.82,N,1317.76,E,19.4,345.0,030308,11.2,W,A*33 +$GPGGA,121054,5231.83,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121054,A,5231.83,N,1317.76,E,19.4,350.0,030308,11.2,W,A*31 +$GPGGA,121055,5231.83,N,1317.76,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121055,A,5231.83,N,1317.76,E,21.9,348.0,030308,11.2,W,A*3f +$GPGGA,121056,5231.84,N,1317.75,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121056,A,5231.84,N,1317.75,E,24.3,344.0,030308,11.2,W,A*3b +$GPGGA,121057,5231.85,N,1317.75,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121057,A,5231.85,N,1317.75,E,25.3,342.0,030308,11.2,W,A*3c +$GPGGA,121058,5231.86,N,1317.75,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,121058,A,5231.86,N,1317.75,E,27.7,351.0,030308,11.2,W,A*34 +$GPGGA,121059,5231.86,N,1317.74,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,121059,A,5231.86,N,1317.74,E,28.7,346.0,030308,11.2,W,A*3d +$GPGGA,121100,5231.87,N,1317.74,E,1,07,1.3,50.6,M,39.2,M,,*42 +$GPRMC,121100,A,5231.87,N,1317.74,E,30.6,347.0,030308,11.2,W,A*38 +$GPGGA,121101,5231.88,N,1317.74,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,121101,A,5231.88,N,1317.74,E,31.6,340.0,030308,11.2,W,A*30 +$GPGGA,121102,5231.89,N,1317.73,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,121102,A,5231.89,N,1317.73,E,32.6,341.0,030308,11.2,W,A*37 +$GPGGA,121103,5231.9,N,1317.73,E,1,07,1.3,50.6,M,39.2,M,,*70 +$GPRMC,121103,A,5231.9,N,1317.73,E,34.0,340.0,030308,11.2,W,A*0f +$GPGGA,121104,5231.91,N,1317.72,E,1,07,1.3,50.6,M,39.2,M,,*47 +$GPRMC,121104,A,5231.91,N,1317.72,E,35.0,341.0,030308,11.2,W,A*38 +$GPGGA,121105,5231.92,N,1317.72,E,1,07,1.3,50.6,M,39.2,M,,*45 +$GPRMC,121105,A,5231.92,N,1317.72,E,35.5,342.0,030308,11.2,W,A*3c +$GPGGA,121106,5231.93,N,1317.71,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121106,A,5231.93,N,1317.71,E,35.0,338.0,030308,11.2,W,A*35 +$GPGGA,121107,5231.94,N,1317.7,E,1,07,1.3,50.6,M,39.2,M,,*73 +$GPRMC,121107,A,5231.94,N,1317.7,E,34.0,336.0,030308,11.2,W,A*0d +$GPGGA,121108,5231.94,N,1317.7,E,1,07,1.3,50.6,M,39.2,M,,*7c +$GPRMC,121108,A,5231.94,N,1317.7,E,32.6,337.0,030308,11.2,W,A*03 +$GPGGA,121109,5231.95,N,1317.69,E,1,07,1.3,50.6,M,39.2,M,,*44 +$GPRMC,121109,A,5231.95,N,1317.69,E,29.6,339.0,030308,11.2,W,A*3f +$GPGGA,121110,5231.96,N,1317.69,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,121110,A,5231.96,N,1317.69,E,29.2,339.0,030308,11.2,W,A*30 +$GPGGA,121111,5231.97,N,1317.68,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,121111,A,5231.97,N,1317.68,E,25.8,333.0,030308,11.2,W,A*3d +$GPGGA,121112,5231.97,N,1317.68,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,121112,A,5231.97,N,1317.68,E,25.3,339.0,030308,11.2,W,A*3f +$GPGGA,121113,5231.98,N,1317.68,E,1,07,1.3,50.6,M,39.2,M,,*43 +$GPRMC,121113,A,5231.98,N,1317.68,E,20.9,343.0,030308,11.2,W,A*33 +$GPGGA,121114,5231.98,N,1317.67,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121114,A,5231.98,N,1317.67,E,19.4,339.0,030308,11.2,W,A*31 +$GPGGA,121115,5231.99,N,1317.67,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121115,A,5231.99,N,1317.67,E,17.5,341.0,030308,11.2,W,A*31 +$GPGGA,121116,5231.99,N,1317.67,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,121116,A,5231.99,N,1317.67,E,16.5,344.0,030308,11.2,W,A*36 +$GPGGA,121117,5232,N,1317.66,E,1,07,1.3,50.6,M,39.2,M,,*65 +$GPRMC,121117,A,5232,N,1317.66,E,14.6,324.0,030308,11.2,W,A*1c +$GPGGA,121118,5232,N,1317.66,E,1,07,1.3,50.6,M,39.2,M,,*6a +$GPRMC,121118,A,5232,N,1317.66,E,12.6,332.0,030308,11.2,W,A*12 +$GPGGA,121119,5232,N,1317.66,E,1,07,1.3,50.6,M,39.2,M,,*6b +$GPRMC,121119,A,5232,N,1317.66,E,14.1,342.0,030308,11.2,W,A*15 +$GPGGA,121120,5232.01,N,1317.66,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,121120,A,5232.01,N,1317.66,E,16.5,339.0,030308,11.2,W,A*3a +$GPGGA,121121,5232.01,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,121121,A,5232.01,N,1317.65,E,16.5,335.0,030308,11.2,W,A*34 +$GPGGA,121122,5232.01,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,121122,A,5232.01,N,1317.65,E,16.5,322.0,030308,11.2,W,A*31 +$GPGGA,121123,5232.02,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,121123,A,5232.02,N,1317.65,E,16.5,334.0,030308,11.2,W,A*34 +$GPGGA,121124,5232.02,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121124,A,5232.02,N,1317.64,E,19.0,331.0,030308,11.2,W,A*3d +$GPGGA,121125,5232.03,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121125,A,5232.03,N,1317.64,E,17.0,338.0,030308,11.2,W,A*3a +$GPGGA,121126,5232.03,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,121126,A,5232.03,N,1317.64,E,13.6,334.0,030308,11.2,W,A*37 +$GPGGA,121127,5232.03,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,121127,A,5232.03,N,1317.64,E,11.2,349.0,030308,11.2,W,A*3a +$GPGGA,121128,5232.03,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*46 +$GPRMC,121128,A,5232.03,N,1317.64,E,1.9,352.0,030308,11.2,W,A*05 +$GPGGA,121129,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,121129,A,5232.04,N,1317.64,E,1.9,352.0,030308,11.2,W,A*03 +$GPGGA,121130,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,121130,A,5232.04,N,1317.64,E,0.5,352.0,030308,11.2,W,A*06 +$GPGGA,121131,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,121131,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*1c +$GPGGA,121132,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,121132,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*1f +$GPGGA,121133,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121133,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*1e +$GPGGA,121134,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,121134,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*19 +$GPGGA,121135,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,121135,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*18 +$GPGGA,121136,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,121136,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*1b +$GPGGA,121137,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,121137,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*1a +$GPGGA,121138,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*40 +$GPRMC,121138,A,5232.04,N,1317.64,E,0,352.0,030308,11.2,W,A*15 +$GPGGA,121139,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*41 +$GPRMC,121139,A,5232.04,N,1317.64,E,1.0,352.0,030308,11.2,W,A*0b +$GPGGA,121140,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4f +$GPRMC,121140,A,5232.04,N,1317.64,E,7.8,357.0,030308,11.2,W,A*0e +$GPGGA,121141,5232.04,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4e +$GPRMC,121141,A,5232.04,N,1317.64,E,15.6,357.0,030308,11.2,W,A*32 +$GPGGA,121142,5232.05,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4c +$GPRMC,121142,A,5232.05,N,1317.64,E,16.5,14.0,030308,11.2,W,A*04 +$GPGGA,121143,5232.05,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,121143,A,5232.05,N,1317.64,E,18.5,17.0,030308,11.2,W,A*08 +$GPGGA,121144,5232.06,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*48 +$GPRMC,121144,A,5232.06,N,1317.65,E,20.9,21.0,030308,11.2,W,A*0f +$GPGGA,121145,5232.06,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*49 +$GPRMC,121145,A,5232.06,N,1317.65,E,20.9,18.0,030308,11.2,W,A*04 +$GPGGA,121146,5232.07,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121146,A,5232.07,N,1317.65,E,19.4,18.0,030308,11.2,W,A*01 +$GPGGA,121147,5232.07,N,1317.65,E,1,07,1.3,50.6,M,39.2,M,,*4a +$GPRMC,121147,A,5232.07,N,1317.65,E,17.5,348.0,030308,11.2,W,A*39 +$GPGGA,121148,5232.08,N,1317.64,E,1,07,1.3,50.6,M,39.2,M,,*4b +$GPRMC,121148,A,5232.08,N,1317.64,E,11.7,333.0,030308,11.2,W,A*30 +$GPGGA,121149,5232.08,N,1317.63,E,1,07,1.3,50.6,M,39.2,M,,*4d +$GPRMC,121149,A,5232.08,N,1317.63,E,7.8,315.0,030308,11.2,W,A*0a diff --git a/CanController/tcpclusterdatacontrol.cpp b/CanController/tcpclusterdatacontrol.cpp new file mode 100644 index 0000000..a9aadca --- /dev/null +++ b/CanController/tcpclusterdatacontrol.cpp @@ -0,0 +1,554 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "tcpclusterdatacontrol.h" +#include <QHostAddress> +#include <QDebug> +#include <QTimer> + +TCPClusterDataControl::TCPClusterDataControl(QObject *parent) + : ClusterDataControlInterface(parent), + m_frontLeftDoorOpen(false), + m_frontRightDoorOpen(false), + m_rearLeftDoorOpen(false), + m_rearRightDoorOpen(false), + m_hoodOpen(false), + m_trunkOpen(false), + m_headLight(false), + m_parkLight(false), + m_rightTurnLight(false), + m_leftTurnLight(false), + m_hazardSignal(false), + m_brake(false) +{ + connect(&m_tcpSocket, &QAbstractSocket::stateChanged, + this, &TCPClusterDataControl::onConnectionStateChanged); + connect(&m_tcpSocket, static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)> (&QAbstractSocket::error), + this, &TCPClusterDataControl::handleTcpError); + + connectToServer(); +} + +TCPClusterDataControl::~TCPClusterDataControl() +{ + m_tcpSocket.close(); +} + +static bool printIP = true; + +void TCPClusterDataControl::connectToServer() +{ + QByteArray simu = qgetenv("QT_CLUSTER_SIMU"); + QHostAddress simuAddr("127.0.0.1"); + + if (!simu.isEmpty()) { + if (!simuAddr.setAddress(QString(simu))) { + qWarning("Failed to set simulator address! Falling back to localhost"); + simuAddr.setAddress("127.0.0.1"); + } + } + + if (printIP) { + printIP = false; + qDebug() << "Connecting to" << simuAddr; + } + + m_tcpSocket.connectToHost(simuAddr,32123); +} + +void TCPClusterDataControl::onConnectionStateChanged(QAbstractSocket::SocketState socketState) +{ + if (socketState == QAbstractSocket::UnconnectedState) { + QTimer::singleShot(1000,Qt::VeryCoarseTimer, this, SLOT(connectToServer())); + } else if (socketState == QAbstractSocket::ConnectedState) { + qDebug() << "Connected"; + emit dataReset(); + } +} + +void TCPClusterDataControl::handleTcpError(QAbstractSocket::SocketError socketError) +{ + Q_UNUSED(socketError); + qWarning() << "TCP Error:" << m_tcpSocket.errorString(); +} + +int TCPClusterDataControl::carId() const +{ + return m_carId; +} + +bool TCPClusterDataControl::headLight() const +{ + return m_headLight; +} + +bool TCPClusterDataControl::parkLight() const +{ + return m_parkLight; +} + +bool TCPClusterDataControl::rightTurnLight() const +{ + return m_rightTurnLight; +} + +bool TCPClusterDataControl::leftTurnLight() const +{ + return m_leftTurnLight; +} + +int TCPClusterDataControl::gear() const +{ + return m_gear; +} + +bool TCPClusterDataControl::lightFailure() const +{ + return m_lightFailure; +} + +bool TCPClusterDataControl::frontLeftDoorOpen() const +{ + return m_frontLeftDoorOpen; +} + +bool TCPClusterDataControl::frontRightDoorOpen() const +{ + return m_frontRightDoorOpen; +} + +bool TCPClusterDataControl::rearLeftDoorOpen() const +{ + return m_rearLeftDoorOpen; +} + +bool TCPClusterDataControl::rearRightDoorOpen() const +{ + return m_rearRightDoorOpen; +} + +bool TCPClusterDataControl::hoodOpen() const +{ + return m_hoodOpen; +} + +bool TCPClusterDataControl::trunkOpen() const +{ + return m_trunkOpen; +} + +bool TCPClusterDataControl::flatTire() const +{ + return m_flatTire; +} + +double TCPClusterDataControl::direction() const +{ + return m_direction; +} + +double TCPClusterDataControl::longitude() const +{ + return m_longitude; +} + +double TCPClusterDataControl::latitude() const +{ + return m_latitude; +} + +double TCPClusterDataControl::vehicleSpeed() const +{ + return m_vehicleSpeed; +} + +bool TCPClusterDataControl::hazardSignal() const +{ + return m_hazardSignal; +} + +bool TCPClusterDataControl::brake() const +{ + return m_brake; +} + +double TCPClusterDataControl::oilTemp() const +{ + return m_oilTemp; +} + +int TCPClusterDataControl::oilPressure() const +{ + return m_oilPressure; +} + +double TCPClusterDataControl::batteryPotential() const +{ + return m_batteryPotential; +} + +double TCPClusterDataControl::gasLevel() const +{ + return m_gasLevel; +} + +int TCPClusterDataControl::rpm() const +{ + return m_rpm; +} + +int TCPClusterDataControl::engineTemp() const +{ + return m_engineTemp; +} + +void TCPClusterDataControl::setVehicleSpeed(double vehicleSpeed) +{ + if (m_vehicleSpeed == vehicleSpeed) + return; + + QString msg("vehicleSpeed:" + QString::number(vehicleSpeed) + " "); + write(msg.toLatin1()); + + m_vehicleSpeed = vehicleSpeed; + emit vehicleSpeedChanged(vehicleSpeed); +} + +void TCPClusterDataControl::setLatitude(double latitude) +{ + if (m_latitude == latitude) + return; + + QString msg("latitude:" + QString::number(latitude) + " "); + write(msg.toLatin1(), msg.length()); + + m_latitude = latitude; + emit latitudeChanged(latitude); +} + +void TCPClusterDataControl::setLongitude(double longitude) +{ + if (m_longitude == longitude) + return; + + QString msg("longitude:" + QString::number(longitude) + " "); + write(msg.toLatin1()); + + m_longitude = longitude; + emit longitudeChanged(longitude); +} + +void TCPClusterDataControl::setDirection(double direction) +{ + if (m_direction == direction) + return; + + QString msg("direction:" + QString::number(direction) + " "); + write(msg.toLatin1()); + + m_direction = direction; + emit directionChanged(direction); +} + +void TCPClusterDataControl::setFlatTire(bool flatTire) +{ + if (m_flatTire == flatTire) + return; + + QString msg("flatTire:" + QString::number(flatTire) + " "); + write(msg.toLatin1()); + + m_flatTire = flatTire; + emit flatTireChanged(flatTire); +} + +void TCPClusterDataControl::setFrontLeftDoorOpen(bool doorOpen) +{ + if (m_frontLeftDoorOpen == doorOpen) + return; + + QString msg("frontLeftDoorOpen:" + QString::number(doorOpen) + " "); + write(msg.toLatin1()); + + m_frontLeftDoorOpen = doorOpen; + emit frontLeftDoorOpenChanged(doorOpen); +} + +void TCPClusterDataControl::setFrontRightDoorOpen(bool doorOpen) +{ + if (m_frontRightDoorOpen == doorOpen) + return; + + QString msg("frontRightDoorOpen:" + QString::number(doorOpen) + " "); + write(msg.toLatin1()); + + m_frontRightDoorOpen = doorOpen; + emit frontRightDoorOpenChanged(doorOpen); +} + +void TCPClusterDataControl::setRearLeftDoorOpen(bool doorOpen) +{ + if (m_rearLeftDoorOpen == doorOpen) + return; + + QString msg("rearLeftDoorOpen:" + QString::number(doorOpen) + " "); + write(msg.toLatin1()); + + m_rearLeftDoorOpen = doorOpen; + emit rearLeftDoorOpenChanged(doorOpen); +} + +void TCPClusterDataControl::setHoodOpen(bool doorOpen) +{ + if (m_hoodOpen == doorOpen) + return; + + QString msg("hoodOpen:" + QString::number(doorOpen) + " "); + write(msg.toLatin1()); + + m_hoodOpen = doorOpen; + emit hoodOpenChanged(doorOpen); +} + +void TCPClusterDataControl::setTrunkOpen(bool doorOpen) +{ + if (m_trunkOpen == doorOpen) + return; + + QString msg("trunkOpen:" + QString::number(doorOpen) + " "); + write(msg.toLatin1()); + + m_trunkOpen = doorOpen; + emit rearRightDoorOpenChanged(doorOpen); +} + +void TCPClusterDataControl::setRearRightDoorOpen(bool doorOpen) +{ + if (m_rearRightDoorOpen == doorOpen) + return; + + QString msg("rearRightDoorOpen:" + QString::number(doorOpen) + " "); + write(msg.toLatin1()); + + m_rearRightDoorOpen = doorOpen; + emit rearRightDoorOpenChanged(doorOpen); +} + +void TCPClusterDataControl::setLightFailure(bool lightFailure) +{ + if (m_lightFailure == lightFailure) + return; + + QString msg("lightFailure:" + QString::number(lightFailure) + " "); + write(msg.toLatin1()); + + m_lightFailure = lightFailure; + emit lightFailureChanged(lightFailure); +} + +void TCPClusterDataControl::setGear(int gear) +{ + if (m_gear == gear) + return; + + QString msg("gear:" + QString::number(gear) + " "); + write(msg.toLatin1()); + + m_gear = gear; + emit gearChanged(gear); +} + +void TCPClusterDataControl::setLeftTurnLight(bool leftTurnLight) +{ + if (m_leftTurnLight == leftTurnLight) + return; + + QString msg("leftTurnLight:" + QString::number(leftTurnLight) + " "); + write(msg.toLatin1()); + + m_leftTurnLight = leftTurnLight; + emit leftTurnLightChanged(leftTurnLight); +} + +void TCPClusterDataControl::setRightTurnLight(bool rightTurnLight) +{ + if (m_rightTurnLight == rightTurnLight) + return; + + QString msg("rightTurnLight:" + QString::number(rightTurnLight) + " "); + write(msg.toLatin1()); + + m_rightTurnLight = rightTurnLight; + emit rightTurnLightChanged(rightTurnLight); +} + +void TCPClusterDataControl::setHeadLight(bool headLight) +{ + if (m_headLight == headLight) + return; + + QString msg("headLight:" + QString::number(headLight) + " "); + write(msg.toLatin1()); + + m_headLight = headLight; + emit headLightChanged(headLight); +} + +void TCPClusterDataControl::setParkLight(bool parkLight) +{ + if (m_parkLight == parkLight) + return; + + QString msg("parkLight:" + QString::number(parkLight) + " "); + write(msg.toLatin1()); + + m_parkLight = parkLight; + emit parkLightChanged(parkLight); +} + +void TCPClusterDataControl::setCarId(int carId) +{ + if (m_carId == carId) + return; + + QString msg("carId:" + QString::number(carId) + " "); + write(msg.toLatin1()); + + m_carId = carId; + emit carIdChanged(carId); +} + +void TCPClusterDataControl::setHazardSignal(bool hazardSignal) +{ + if (m_hazardSignal == hazardSignal) + return; + + QString msg("hazardSignal:" + QString::number(hazardSignal) + " "); + write(msg.toLatin1()); + + m_hazardSignal = hazardSignal; + emit hazardSignalChanged(hazardSignal); +} + +void TCPClusterDataControl::setBrake(bool brake) +{ + if (m_brake == brake) + return; + + QString msg("brake:" + QString::number(brake) + " "); + write(msg.toLatin1()); + + m_brake = brake; + emit brakeChanged(brake); +} + +void TCPClusterDataControl::setOilTemp(double oilTemp) +{ + if (m_oilTemp == oilTemp) + return; + + QString msg("oilTemp:" + QString::number(oilTemp) + " "); + write(msg.toLatin1()); + + m_oilTemp = oilTemp; + emit oilTempChanged(oilTemp); +} + +void TCPClusterDataControl::setOilPressure(int oilPressure) +{ + if (m_oilPressure == oilPressure) + return; + + QString msg("oilPressure:" + QString::number(oilPressure) + " "); + write(msg.toLatin1()); + + m_oilPressure = oilPressure; + emit oilPressureChanged(oilPressure); +} + +void TCPClusterDataControl::setBatteryPotential(double batteryPotential) +{ + if (m_batteryPotential == batteryPotential) + return; + + QString msg("batteryPotential:" + QString::number(batteryPotential) + " "); + write(msg.toLatin1()); + + m_batteryPotential = batteryPotential; + emit batteryPotentialChanged(batteryPotential); +} + +void TCPClusterDataControl::setGasLevel(double gasLevel) +{ + if (m_gasLevel == gasLevel) + return; + + QString msg("gasLevel:" + QString::number(gasLevel) + " "); + write(msg.toLatin1()); + + m_gasLevel = gasLevel; + emit gasLevelChanged(gasLevel); +} + +void TCPClusterDataControl::setRpm(int rpm) +{ + if (m_rpm == rpm) + return; + + QString msg("rpm:" + QString::number(rpm) + " "); + write(msg.toLatin1()); + + m_rpm = rpm; + emit rpmChanged(rpm); +} + +void TCPClusterDataControl::setEngineTemp(int engineTemp) +{ + if (m_engineTemp == engineTemp) + return; + + QString msg("engineTemp:" + QString::number(engineTemp) + " "); + write(msg.toLatin1()); + + m_engineTemp = engineTemp; + emit engineTempChanged(engineTemp); +} + +void TCPClusterDataControl::write(const char *data, qint64 length) +{ + if ((m_tcpSocket.state() == QTcpSocket::ConnectedState)) { + m_tcpSocket.write(data, length); + } +} + +void TCPClusterDataControl::write(const char *data) +{ + if ((m_tcpSocket.state() == QTcpSocket::ConnectedState)) { + m_tcpSocket.write(data); + } +} diff --git a/CanController/tcpclusterdatacontrol.h b/CanController/tcpclusterdatacontrol.h new file mode 100644 index 0000000..c3e2422 --- /dev/null +++ b/CanController/tcpclusterdatacontrol.h @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TCPCLUSTERDATACONTROL_H +#define TCPCLUSTERDATACONTROL_H + +#include "clusterdatacontrolinterface.h" + +#include <QTcpSocket> + +class TCPClusterDataControl : public ClusterDataControlInterface +{ + Q_OBJECT + +public: + TCPClusterDataControl(QObject *parent = 0); + ~TCPClusterDataControl(); + + int carId() const; + bool headLight() const; + bool parkLight() const; + bool rightTurnLight() const; + bool leftTurnLight() const; + int gear() const; + bool lightFailure() const; + bool frontLeftDoorOpen() const; + bool frontRightDoorOpen() const; + bool rearLeftDoorOpen() const; + bool rearRightDoorOpen() const; + bool hoodOpen() const; + bool trunkOpen() const; + bool flatTire() const; + double direction() const; + double longitude() const; + double latitude() const; + double vehicleSpeed() const; + bool hazardSignal() const; + bool brake() const; + double oilTemp() const; + int oilPressure() const; + double batteryPotential() const; + double gasLevel() const; + int rpm() const; + int engineTemp() const; + +public slots: + void connectToServer(); + void onConnectionStateChanged(QAbstractSocket::SocketState socketState); + void handleTcpError(QAbstractSocket::SocketError socketError); + + void setVehicleSpeed(double vehicleSpeed); + void setLatitude(double latitude); + void setLongitude(double longitude); + void setDirection(double direction); + void setFlatTire(bool flatTire); + void setFrontLeftDoorOpen(bool doorOpen); + void setFrontRightDoorOpen(bool doorOpen); + void setRearLeftDoorOpen(bool doorOpen); + void setRearRightDoorOpen(bool doorOpen); + void setHoodOpen(bool doorOpen); + void setTrunkOpen(bool doorOpen); + void setLightFailure(bool lightFailure); + void setGear(int gear); + void setLeftTurnLight(bool leftTurnLight); + void setRightTurnLight(bool rightTurnLight); + void setHeadLight(bool headLight); + void setParkLight(bool parkLight); + void setCarId(int carId); + void setHazardSignal(bool hazardSignal); + void setBrake(bool brake); + void setOilTemp(double oilTemp); + void setOilPressure(int oilPressure); + void setBatteryPotential(double batteryPotential); + void setGasLevel(double gasLevel); + void setRpm(int rpm); + void setEngineTemp(int engineTemp); + +private: + void write(const char *, qint64 ); + void write(const char *); + +private: + QTcpSocket m_tcpSocket; + bool m_frontLeftDoorOpen; + bool m_frontRightDoorOpen; + bool m_rearLeftDoorOpen; + bool m_rearRightDoorOpen; + bool m_hoodOpen; + bool m_trunkOpen; + bool m_headLight; + bool m_parkLight; + bool m_rightTurnLight; + bool m_leftTurnLight; + bool m_hazardSignal; + bool m_brake; +}; + +#endif // TCPCLUSTERDATACONTROL_H diff --git a/CanController/valuetypes.h b/CanController/valuetypes.h new file mode 100644 index 0000000..ccea580 --- /dev/null +++ b/CanController/valuetypes.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt multiscreen demo application. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef VALUETYPES +#define VALUETYPES + +namespace NMEAType +{ + enum { + NMEAStart = 0x01, + NMEAEnd = 0x0f, + + GeoBaseStart = 0x10, + GeoBaseEnd = 0x1f, + + GGAStart = 0x20, + GGAEnd = 0x2f, + + RMCStart = 0x30, + RMCEnd = 0x3f, + }; + + enum Type { + UndefinedType = 0, + GGAType, + RMCType + }; + + enum Value { + UTCTime = NMEAStart, + CheckSum, + + Latitude = GeoBaseStart, + Longitude, + + GGAQuality = GGAStart, + GGASatellites, + GGADilution, + GGAAltitude, + GGAGeoid, + + RMCActive = RMCStart, + RMCSpeed, + RMCAngle, + RMCDate, + RMCVariation + + }; +} + +#endif // VALUETYPES + |