Update environment generated file
This commit is contained in:
@@ -0,0 +1,301 @@
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:nmea/nmea.dart';
|
||||
import 'package:terepi_seged/eov/convert_coordinate.dart';
|
||||
import 'package:terepi_seged/eov/eov.dart';
|
||||
import 'package:terepi_seged/gnss_sentences/gngga.dart';
|
||||
import 'package:terepi_seged/gnss_sentences/gngst.dart';
|
||||
import 'package:terepi_seged/gnss_sentences/gnrmc.dart';
|
||||
|
||||
class RtcmTestController extends GetxController {
|
||||
String gpsAddress = "E8:31:CD:14:8B:B2";
|
||||
String gpsName = "TiGNSS Rover-8BB2";
|
||||
Rx<bool> gpsIsConnected = false.obs;
|
||||
RxBool ntripIsConnected = false.obs;
|
||||
RxInt ntripDataPacketNumbers = 0.obs;
|
||||
String _messageBuffer = "";
|
||||
late BluetoothConnection connection;
|
||||
late Socket socket;
|
||||
late StreamSubscription socketStreamSubscription;
|
||||
RxInt gpsReceivedData = 0.obs;
|
||||
RxBool hasGpsValidData = false.obs;
|
||||
DateTime lastGpsRefreshTime = DateTime.now();
|
||||
String utcOfPositionFix = "";
|
||||
String utcDateOfPositionFix = "";
|
||||
RxInt ntripReceivedData = 0.obs;
|
||||
final NmeaDecoder nmeaDecoder = NmeaDecoder();
|
||||
|
||||
NumberFormat formatEov = NumberFormat("##0,000.0", "hu-HU");
|
||||
NumberFormat formatWgs84Sec = NumberFormat('00.000', 'hu-HU');
|
||||
|
||||
RxDouble gpsLatitude = 0.0.obs;
|
||||
RxString gpsLatitudeDirection = "".obs;
|
||||
RxDouble gpsLongitude = 0.0.obs;
|
||||
RxString gpsLongitudeDirection = "".obs;
|
||||
RxDouble gpsAltitude = 0.0.obs;
|
||||
RxInt gpsQuality = 0.obs;
|
||||
RxDouble gpsLatitudeError = 0.0.obs;
|
||||
RxDouble gpsLongitudeError = 0.0.obs;
|
||||
RxDouble gpsAltitudeError = 0.0.obs;
|
||||
Rx<DateTime> gpsDateTime = DateTime(2000).obs;
|
||||
Rx<Eov> eov = Eov(0, 0).obs;
|
||||
RxInt latDegree = 0.obs;
|
||||
RxInt latMin = 0.obs;
|
||||
RxDouble latSec = 0.0.obs;
|
||||
RxInt longDegree = 0.obs;
|
||||
RxInt longMin = 0.obs;
|
||||
RxDouble longSec = 0.0.obs;
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
//Loading, Success, Error handle with 1 line of code
|
||||
nmeaDecoder
|
||||
..registerTalkerSentence("GGA", (line) => Gngga(raw: line))
|
||||
..registerTalkerSentence("RMC", (line) => Gnrmc(raw: line))
|
||||
..registerTalkerSentence("GST", (line) => Gngst(raw: line));
|
||||
}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
super.onClose();
|
||||
FlutterBluetoothSerial.instance.setPairingRequestHandler(null);
|
||||
if (gpsIsConnected.value) {
|
||||
connection.close();
|
||||
// connection = null;
|
||||
print("BluetoothTestController dispose ....");
|
||||
}
|
||||
}
|
||||
|
||||
void connectToGps() {
|
||||
if (gpsIsConnected == false) {
|
||||
BluetoothConnection.toAddress(gpsAddress).then((value) {
|
||||
connection = value;
|
||||
gpsIsConnected.value = true;
|
||||
print("GPS is connected ...");
|
||||
|
||||
connection.input!.listen(_onDataReceived);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void disconnectFromGps() {
|
||||
if (gpsIsConnected.value) {
|
||||
connection.close();
|
||||
gpsIsConnected.value = false;
|
||||
print("GPS is disconnected ....");
|
||||
}
|
||||
if (ntripIsConnected.value) {
|
||||
disconnectFromNtripServer();
|
||||
}
|
||||
}
|
||||
|
||||
void connectToNtripServer() async {
|
||||
socket = await Socket.connect(InternetAddress('3.23.52.207'), 2101,
|
||||
timeout: const Duration(seconds: 5));
|
||||
socket.asBroadcastStream;
|
||||
ntripIsConnected.value = true;
|
||||
|
||||
socket.encoding = ascii;
|
||||
print("Connected to ntrip server ....");
|
||||
|
||||
String header = "GET /KOVARIK HTTP/1.1\r\n";
|
||||
header += "User-Agent: SharpGps iter.dk\r\n";
|
||||
header += "Accept: */*\r\nConnection: close\r\n";
|
||||
header += "Authorization: Basic ${_toBase64("info@mail.app-dev.hu:")}\r\n";
|
||||
header += "Host:rtk2go.com:2101\r\n";
|
||||
header += "Ntrip-Vesrsion:Ntrip/2.0\r\n";
|
||||
header += "\r\n";
|
||||
|
||||
// listen for responses from the server
|
||||
socketStreamSubscription = socket.listen(
|
||||
// handle data from the server
|
||||
(Uint8List data) {
|
||||
// "ICY 200 OK" - first response
|
||||
final serverResponse = String.fromCharCodes(data);
|
||||
ntripReceivedData.value = data.length;
|
||||
ntripDataPacketNumbers.value++;
|
||||
if (gpsIsConnected.value) {
|
||||
if (data.length > 12) {
|
||||
connection.output.add(data);
|
||||
}
|
||||
}
|
||||
print('Server: $ntripReceivedData');
|
||||
},
|
||||
|
||||
// handle errors
|
||||
onError: (error) {
|
||||
print(error);
|
||||
socket.destroy();
|
||||
},
|
||||
|
||||
// handle server ending connection
|
||||
onDone: () async {
|
||||
print('Server left.');
|
||||
socketStreamSubscription.cancel();
|
||||
await socket.flush();
|
||||
ntripIsConnected.value = false;
|
||||
ntripReceivedData.value = 0;
|
||||
socket.destroy();
|
||||
},
|
||||
);
|
||||
|
||||
socket.add(_convertStringToUint8List(header));
|
||||
}
|
||||
|
||||
void disconnectFromNtripServer() async {
|
||||
socketStreamSubscription.cancel();
|
||||
await socket.flush();
|
||||
socket.close();
|
||||
socket.destroy();
|
||||
ntripReceivedData.value = 0;
|
||||
ntripIsConnected.value = false;
|
||||
print("Disconnect from ntrip server....");
|
||||
}
|
||||
|
||||
void _onDataReceived(Uint8List data) {
|
||||
String sentence = "";
|
||||
|
||||
print("Bluetooth received -> ${data.length} byte(s)");
|
||||
String dataString = String.fromCharCodes(data);
|
||||
int index = data.indexOf(13);
|
||||
|
||||
if (~index != 0) {
|
||||
sentence = _messageBuffer + dataString.substring(0, index);
|
||||
_messageBuffer = dataString.substring(index);
|
||||
} else {
|
||||
_messageBuffer = _messageBuffer + dataString;
|
||||
}
|
||||
|
||||
// print("Message ($count): $sentence");
|
||||
_processGnssMessage(sentence);
|
||||
}
|
||||
|
||||
String _toBase64(String str) {
|
||||
final bytes = ascii.encode(str);
|
||||
final base64Str = base64.encode(bytes);
|
||||
|
||||
return base64Str;
|
||||
}
|
||||
|
||||
Uint8List _convertStringToUint8List(String str) {
|
||||
final List<int> codeUnits = str.codeUnits;
|
||||
final Uint8List unit8List = Uint8List.fromList(codeUnits);
|
||||
return unit8List;
|
||||
}
|
||||
|
||||
void _processGnssMessage(String message) {
|
||||
LineSplitter lineSplitter = const LineSplitter();
|
||||
List<String> lines = lineSplitter.convert(message);
|
||||
|
||||
if (lines.isEmpty) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (String line in lines) {
|
||||
if (line.trim().isEmpty) {
|
||||
continue;
|
||||
}
|
||||
if (line.startsWith("\$GNGGA")) {
|
||||
final sentence = nmeaDecoder.decode(line);
|
||||
if (sentence!.valid && sentence is Gngga) {
|
||||
hasGpsValidData.value = sentence.gpsQualityIndicator > 0;
|
||||
if (hasGpsValidData.value) {
|
||||
if (DateTime.now().difference(lastGpsRefreshTime).inSeconds >= 2) {
|
||||
lastGpsRefreshTime = DateTime.now();
|
||||
utcOfPositionFix = sentence.utcOfPositionFix;
|
||||
gpsLatitude.value = sentence.latitude;
|
||||
gpsLatitudeDirection.value = sentence.latitudeDirection;
|
||||
gpsLongitude.value = sentence.longitude;
|
||||
gpsLongitudeDirection.value = sentence.longitudeDirection;
|
||||
gpsAltitude.value = sentence.altitudeAboveMeanSeaLevel;
|
||||
gpsQuality.value = sentence.gpsQualityIndicator;
|
||||
eov.value = ConvertCoordinate.ConvertWgsToEov(
|
||||
gpsLatitude.value, gpsLongitude.value);
|
||||
latDegree.value = ConvertCoordinate.toDegree(gpsLatitude.value);
|
||||
latMin.value = ConvertCoordinate.toMinute(gpsLatitude.value);
|
||||
latSec.value = ConvertCoordinate.toSecond(gpsLatitude.value);
|
||||
longDegree.value = ConvertCoordinate.toDegree(gpsLongitude.value);
|
||||
longMin.value = ConvertCoordinate.toMinute(gpsLongitude.value);
|
||||
longSec.value = ConvertCoordinate.toSecond(gpsLongitude.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (line.startsWith("\$GNGST") && hasGpsValidData.value) {
|
||||
final sentence = nmeaDecoder.decode(line);
|
||||
if (sentence!.valid && sentence is Gngst) {
|
||||
gpsLatitudeError.value = sentence.latitudeError;
|
||||
gpsLongitudeError.value = sentence.longitudeError;
|
||||
gpsAltitudeError.value = sentence.heightError;
|
||||
}
|
||||
}
|
||||
if (line.startsWith("\$GNRMC") && hasGpsValidData.value) {
|
||||
final sentence = nmeaDecoder.decode(line);
|
||||
if (sentence!.valid && sentence is Gnrmc) {
|
||||
utcDateOfPositionFix = sentence.date;
|
||||
if (utcDateOfPositionFix.isNotEmpty && utcOfPositionFix.isNotEmpty) {
|
||||
gpsDateTime.value = DateTime(
|
||||
2000 +
|
||||
int.parse(
|
||||
"${utcDateOfPositionFix[4]}${utcDateOfPositionFix[5]}"),
|
||||
int.parse(
|
||||
"${utcDateOfPositionFix[2]}${utcDateOfPositionFix[3]}"),
|
||||
int.parse(
|
||||
"${utcDateOfPositionFix[0]}${utcDateOfPositionFix[1]}"),
|
||||
int.parse("${utcOfPositionFix[0]}${utcOfPositionFix[1]}"),
|
||||
int.parse("${utcOfPositionFix[2]}${utcOfPositionFix[3]}"),
|
||||
int.parse("${utcOfPositionFix[4]}${utcOfPositionFix[5]}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String getGpsQualityIndicator({required int quality}) {
|
||||
String qualityStr = "Invalid";
|
||||
switch (quality) {
|
||||
case 0:
|
||||
{
|
||||
qualityStr = "Invalid";
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
qualityStr = "Standard GPS (2D/3D)";
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
{
|
||||
qualityStr = "Differential GPS";
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
qualityStr = "RTK Fix";
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
{
|
||||
qualityStr = "RTK Float";
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
{
|
||||
qualityStr = "Estimated (DR) Fix";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
qualityStr = "Invalid (-1)";
|
||||
}
|
||||
}
|
||||
return qualityStr;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:terepi_seged/pages/rtcm_test/presentation/controllers/rtcm_test_controller.dart';
|
||||
|
||||
class RtcmTestView extends GetView<RtcmTestController> {
|
||||
const RtcmTestView({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
color: Colors.white,
|
||||
child: Scaffold(
|
||||
extendBody: true,
|
||||
backgroundColor: Colors.black.withOpacity(0.05),
|
||||
appBar: AppBar(
|
||||
elevation: 0.0,
|
||||
title: const Text('RtcmTest'),
|
||||
leading: IconButton(
|
||||
icon: const Icon(Icons.arrow_back_ios),
|
||||
color: Colors.white,
|
||||
onPressed: () {
|
||||
Get.back();
|
||||
},
|
||||
),
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
const Center(
|
||||
child: Text("RTCM teszt view"),
|
||||
),
|
||||
ListTile(
|
||||
title: Text(controller.gpsName),
|
||||
subtitle: Obx(() => controller.gpsIsConnected.value
|
||||
? const Text("Connected",
|
||||
style: TextStyle(color: Colors.green))
|
||||
: const Text(
|
||||
"Disconnected",
|
||||
style: TextStyle(color: Colors.red),
|
||||
)),
|
||||
trailing: Obx(() => ElevatedButton(
|
||||
child: Text(controller.gpsIsConnected.value
|
||||
? "Disconnect"
|
||||
: "Connect"),
|
||||
onPressed: () {
|
||||
if (controller.gpsIsConnected.value) {
|
||||
controller.disconnectFromGps();
|
||||
} else {
|
||||
controller.connectToGps();
|
||||
}
|
||||
},
|
||||
)),
|
||||
),
|
||||
ListTile(
|
||||
title: const Text("NTRIP Server (KOVARIK)"),
|
||||
subtitle: Obx(() => controller.ntripIsConnected.value
|
||||
? const Text("Connected",
|
||||
style: TextStyle(color: Colors.green))
|
||||
: const Text(
|
||||
"Disconnected",
|
||||
style: TextStyle(color: Colors.red),
|
||||
)),
|
||||
trailing: Obx(() => ElevatedButton(
|
||||
child: Text(controller.ntripIsConnected.value
|
||||
? "Disconnect"
|
||||
: "Connect"),
|
||||
onPressed: () {
|
||||
if (controller.ntripIsConnected.value) {
|
||||
controller.disconnectFromNtripServer();
|
||||
} else {
|
||||
controller.connectToNtripServer();
|
||||
}
|
||||
},
|
||||
)),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
"Received ${controller.gpsReceivedData} byte(s) from GNSS device")))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
"Received ${controller.ntripReceivedData} byte(s) from ntrip server ${controller.ntripDataPacketNumbers}")))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
"GPS quality -> ${controller.getGpsQualityIndicator(quality: controller.gpsQuality.value)} ")))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
"GpsDateTime -> ${controller.gpsDateTime} (UTC)")))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
'Lat: ${controller.latDegree.value}°${controller.latMin.value.toString().padLeft(2, '0')}\'${controller.formatWgs84Sec.format(controller.latSec.value)}" - Long: ${controller.longDegree.value}°${controller.longMin.value.toString().padLeft(2, '0')}\'${controller.formatWgs84Sec.format(controller.longSec.value)}"')))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
"EovX: ${controller.formatEov.format(controller.eov.value.Y)} - EovY: ${controller.formatEov.format(controller.eov.value.X)}")))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
"Altitude -> ${controller.gpsAltitude} (m)")))),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Obx(() => Text(
|
||||
"Hor. error: ${max(controller.gpsLatitudeError.value, controller.gpsLongitudeError.value)} (m) - Vert. error: ${controller.gpsAltitudeError} (m)"))))
|
||||
],
|
||||
)));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user