Đi đến nội dung chính

Ghi chép kỹ thuật

Head unit báo tốc độ bằng 0 dù xe đang chạy 60

Location.hasSpeed() trả về true, giá trị trả về là 0,0 — mãi mãi. Vì sao chuyện này phổ biến đến vậy trên màn hình Android lắp thêm, và cách app phát hiện ra.

Trên bàn làm việc, đọc tốc độ từ Android là một dòng code. Trên head unit lắp thêm ở Việt Nam, đó là chỗ hỏng đầu tiên.

Nguyên nhân nằm ở câu NMEA

Module GPS nói chuyện với hệ điều hành bằng các câu NMEA. Vị trí nằm trong câu $GPGGA, còn tốc độ và hướng nằm trong $GPRMC. Rất nhiều module rẻ tiền chỉ parse $GPGGA — đủ để chấm một điểm lên bản đồ, tức là đủ cho phần lớn app.

Điều tệ hơn: driver vẫn khai báo trường tốc độ là hợp lệ. location.hasSpeed() trả về true, và location.speed trả về 0.0f. Không có ngoại lệ nào được ném ra, không có cờ lỗi nào được bật. App tin vào con số đó thì đồng hồ tốc độ đứng im vĩnh viễn — trên đúng nhóm máy phổ biến nhất.

Không thể chỉ kiểm tra 'tốc độ bằng 0'

Xe dừng đèn đỏ cũng cho tốc độ bằng 0. Cần một tín hiệu phân biệt được 'đang đứng yên' với 'driver hỏng', và tín hiệu đó là khoảng cách giữa hai điểm định vị liên tiếp: xe đang chạy thì hai fix cách nhau vài chục mét, dù driver nói gì đi nữa.

Cách app xử lý

SpeedEstimator chạy song song hai nguồn:

  • Nguồn driver — giá trị location.speed lấy nguyên.
  • Nguồn tự tính — khoảng cách giữa hai fix chia cho khoảng thời gian giữa chúng.

Bình thường app dùng nguồn driver vì nó mượt hơn. Nhưng mỗi khi nguồn tự tính cho thấy xe rõ ràng đang chạy mà driver vẫn báo 0, app đếm thêm một mẫu. Sau khoảng tám mẫu như vậy, kết luận là driver hỏng và chuyển hẳn sang nguồn tự tính, không quay lại nữa trong phiên đó.

Vì sao là tám chứ không phải hai: một fix nhiễu đơn lẻ có thể tạo ra khoảng cách giả. Tám mẫu liên tiếp thì không.

Người lái nhìn thấy gì

Khi đã chuyển nguồn, màn hình hiện dòng 'Tốc độ tính từ GPS'. Đây không phải thông báo lỗi — nó nói cho người lái biết con số đang dựa trên cái gì, để nếu thấy tốc độ trễ hơn bình thường thì hiểu vì sao. Trạng thái này bình thường trên rất nhiều head unit.