2024-08-26 18:25:21 +08:00
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:math';
|
2024-08-28 17:56:53 +08:00
|
|
|
import 'dart:ui';
|
|
|
|
import 'package:cpnav/pages/pass_track/controller.dart';
|
2024-08-26 18:25:21 +08:00
|
|
|
import 'package:get/get.dart';
|
|
|
|
import 'package:gnss/gnss.dart';
|
2024-08-26 18:58:33 +08:00
|
|
|
import 'package:scence_map/controllers/controller.dart';
|
2024-08-26 18:25:21 +08:00
|
|
|
|
|
|
|
import '../models/pilePoint/coord_trans.dart';
|
2024-08-28 17:56:53 +08:00
|
|
|
import '../pages/aim_point/aimPointer.dart';
|
2024-08-26 18:25:21 +08:00
|
|
|
|
|
|
|
class GnssController extends GetxController {
|
|
|
|
late final Gnss gnss;
|
2024-08-26 18:58:33 +08:00
|
|
|
late ScenceMapController mapController;
|
2024-08-28 17:56:53 +08:00
|
|
|
late SightController sight;
|
|
|
|
|
2024-08-26 18:25:21 +08:00
|
|
|
LocationData? locationData;
|
|
|
|
late Pos3D pilerCenter;
|
2024-08-26 18:58:33 +08:00
|
|
|
late DeviceItem device;
|
2024-08-26 18:25:21 +08:00
|
|
|
var locationUpdate = 0.obs;
|
|
|
|
// late final PilerPointCalculate pilerCenterPoint;
|
|
|
|
//三个定义
|
|
|
|
var maindrilldistance = 2.0.obs; //主天线与车心距离
|
|
|
|
var auxdrilldistance = 2.0.obs; //副天线与车心距离
|
|
|
|
var offsetangle = 0.0.obs; //主副连线与车身夹角
|
|
|
|
late final CoordTrans coordTrans;
|
|
|
|
Timer? timer;
|
2024-08-28 17:56:53 +08:00
|
|
|
checkDistance() {
|
|
|
|
Offset pilerCenterPoint = Offset(device.x, device.y);
|
|
|
|
if (sight.selectedPilePoint == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
var offset = Offset(sight.selectedPilePoint!.x, sight.selectedPilePoint!.y);
|
|
|
|
if (mapController.calculateDistance(pilerCenterPoint, offset) < 0.9) {
|
|
|
|
if (!sight.isCardVisible.value) {
|
|
|
|
print("距离小于1m");
|
|
|
|
sight.isCardVisible.value = true;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!sight.isCardVisible.value) {
|
|
|
|
print("距离大于1m");
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
sight.isCardVisible.value = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-26 18:25:21 +08:00
|
|
|
|
|
|
|
@override
|
|
|
|
void onInit() async {
|
|
|
|
super.onInit();
|
2024-08-26 18:58:33 +08:00
|
|
|
mapController = Get.find<ScenceMapController>();
|
2024-08-28 17:56:53 +08:00
|
|
|
|
|
|
|
sight = Get.find<SightController>();
|
2024-08-26 18:58:33 +08:00
|
|
|
device = DeviceItem(
|
|
|
|
name: 'GNSS',
|
|
|
|
TID: 1001,
|
|
|
|
type: 2,
|
|
|
|
height: 3.0,
|
|
|
|
width: 3.0,
|
2024-08-27 18:08:05 +08:00
|
|
|
lat: 3790616.710,
|
|
|
|
lon: 577046.048,
|
2024-08-26 18:58:33 +08:00
|
|
|
image: ['assets/images/pilerCar.png']);
|
|
|
|
mapController.addDevice(device);
|
2024-08-26 18:25:21 +08:00
|
|
|
// pilerCenterPoint = PilerPointCalculate(
|
|
|
|
// maindrilldistance.value,
|
|
|
|
// auxdrilldistance.value,
|
|
|
|
// offsetangle.value,
|
|
|
|
// );
|
|
|
|
// 调用 pilerPos3D 方法
|
|
|
|
|
2024-08-27 18:08:05 +08:00
|
|
|
// pilerCenter = Pos3D(4196544.959, 517639.709, 0.0);
|
|
|
|
|
2024-08-26 18:25:21 +08:00
|
|
|
// 插入定时器测试代码
|
|
|
|
timer = Timer.periodic(Duration(seconds: 1), (Timer timer) {
|
2024-08-26 18:58:33 +08:00
|
|
|
device.x += 0.2;
|
|
|
|
device.y += 0.2;
|
|
|
|
device.rotation = device.rotation + pi / 180; // 确保旋转角度在0-360度之间
|
|
|
|
device.update.value++;
|
2024-08-28 17:56:53 +08:00
|
|
|
checkDistance();
|
2024-08-26 18:25:21 +08:00
|
|
|
});
|
|
|
|
|
|
|
|
gnss = Gnss(port: "/dev/ttysWK2", baudrate: 115200);
|
|
|
|
// gnss = Gnss(port: "COM1", baudrate: 115200);
|
|
|
|
gnss.start();
|
|
|
|
gnss.locationStream.listen((location) {
|
|
|
|
locationData = location;
|
|
|
|
// print(locationData);
|
|
|
|
// var xyh = coordTrans.d2p(CoordBLH(
|
|
|
|
// B: location.latitude, L: location.longitude, H: location.altitude));
|
|
|
|
// pilerCenter = pilerCenterPoint.pilerPos3D(xyh, location.heading,
|
|
|
|
// location.pitch, location.baseLength, offsetangle.value);
|
|
|
|
// print(
|
|
|
|
// 'X: ${pilerCenter.X}, Y: ${pilerCenter.Y}, Rotation: ${pilerCenter.rotation}');
|
2024-08-28 17:56:53 +08:00
|
|
|
// CheckDistance();
|
2024-08-26 18:25:21 +08:00
|
|
|
locationUpdate.value++;
|
|
|
|
});
|
|
|
|
|
|
|
|
coordTrans = CoordTrans(TransOptions(L0: 108.5, elevation: 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void dispose() {
|
|
|
|
gnss.dispose();
|
|
|
|
super.dispose();
|
|
|
|
timer?.cancel();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class Pos3D {
|
|
|
|
double X;
|
|
|
|
double Y;
|
|
|
|
double rotation;
|
|
|
|
|
|
|
|
Pos3D(this.X, this.Y, this.rotation);
|
|
|
|
}
|
|
|
|
|
|
|
|
// class PilerPointCalculate {
|
|
|
|
// final double mainDrillDistance; //主天线与钻头距离
|
|
|
|
|
|
|
|
// final double auxDrillDistance; //副天线与钻头距离
|
|
|
|
// final double offsetangle;
|
|
|
|
// PilerPointCalculate(
|
|
|
|
// this.mainDrillDistance,
|
|
|
|
// this.auxDrillDistance,
|
|
|
|
// this.offsetangle,
|
|
|
|
// );
|
|
|
|
// // 计算副天线的坐标
|
|
|
|
// Offset auxPointCalculate(
|
|
|
|
// CoordXYH mainPoint, double baseLength, double pitch, double heading) {
|
|
|
|
// // 将角度转换为弧度
|
|
|
|
// double pitchRad = pitch * pi / 180;
|
|
|
|
// double headingRad = (270 - heading) * pi / 180; //(270-)
|
|
|
|
|
|
|
|
// // 计算水平投影距离
|
|
|
|
// double dXY = baseLength * cos(pitchRad);
|
|
|
|
|
|
|
|
// // 计算副天线的坐标
|
|
|
|
// double x2 = mainPoint.X + dXY * cos(headingRad);
|
|
|
|
// double y2 = mainPoint.Y + dXY * sin(headingRad);
|
|
|
|
// return Offset(x2, y2);
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // 计算交点
|
|
|
|
// List findIntersections(CoordXYH mainPoint, Offset auxPoint) {
|
|
|
|
// // 计算第二个点 b 的坐标
|
|
|
|
// // Offset auxPoint = _auxPointCalculate(mainPoint, baseLength, pitch, heading);
|
|
|
|
|
|
|
|
// double dx = auxPoint.dx - mainPoint.X;
|
|
|
|
// double dy = auxPoint.dy - mainPoint.Y;
|
|
|
|
// double d = sqrt(dx * dx + dy * dy);
|
|
|
|
|
|
|
|
// if (d > mainDrillDistance + auxDrillDistance ||
|
|
|
|
// d < (mainDrillDistance - auxDrillDistance).abs()) {
|
|
|
|
// // 圆不相交
|
|
|
|
// return [];
|
|
|
|
// }
|
|
|
|
|
|
|
|
// double a_ = (mainDrillDistance * mainDrillDistance -
|
|
|
|
// auxDrillDistance * auxDrillDistance +
|
|
|
|
// d * d) /
|
|
|
|
// (2 * d);
|
|
|
|
// double h = sqrt(mainDrillDistance * mainDrillDistance - a_ * a_);
|
|
|
|
|
|
|
|
// double x2 = mainPoint.X + a_ * (dx / d);
|
|
|
|
// double y2 = mainPoint.Y + a_ * (dy / d);
|
|
|
|
|
|
|
|
// double rx = -dy * (h / d);
|
|
|
|
// double ry = dx * (h / d);
|
|
|
|
|
|
|
|
// Offset intersection1 = Offset(x2 + rx, y2 + ry);
|
|
|
|
// Offset intersection2 = Offset(x2 - rx, y2 - ry);
|
|
|
|
|
|
|
|
// return [intersection1, intersection2];
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // 计算车心
|
|
|
|
// Pos3D pilerPos3D(CoordXYH mainPoint, double heading, double pitch,
|
|
|
|
// double baseLength, double offsetangle) {
|
|
|
|
// // 找到两个可能的车心点
|
|
|
|
// Offset auxPoint = auxPointCalculate(mainPoint, baseLength, pitch, heading);
|
|
|
|
// List intersections = findIntersections(mainPoint, auxPoint);
|
|
|
|
|
|
|
|
// if (intersections.isEmpty) {
|
|
|
|
// throw Exception('无法找到车心点,圆不相交');
|
|
|
|
// }
|
|
|
|
|
|
|
|
// // 以主点为起点连线到副点作为横轴
|
|
|
|
// double dx = auxPoint.dx - mainPoint.X;
|
|
|
|
// double dy = auxPoint.dy - mainPoint.Y;
|
|
|
|
|
|
|
|
// // 横轴逆时针旋转90度为纵轴
|
|
|
|
// double verticalX = -dy;
|
|
|
|
// double verticalY = dx;
|
|
|
|
|
|
|
|
// // 选择位于纵轴正半轴的点作为最终的车心坐标
|
|
|
|
// Offset intersection = (intersections[1].dx - mainPoint.X) * verticalX +
|
|
|
|
// (intersections[1].dy - mainPoint.Y) * verticalY >
|
|
|
|
// 0
|
|
|
|
// ? intersections[1]
|
|
|
|
// : intersections[0];
|
|
|
|
|
|
|
|
// double rotation = (atan2(dy, dx) * 180 / pi) + 90 + offsetangle;
|
|
|
|
|
|
|
|
// return Pos3D(intersection.dx, intersection.dy, rotation);
|
|
|
|
// }
|
|
|
|
// }
|