前言
本章整理一下使用合宙air551G定位并在st7735 屏幕上显示实时路线的一些问题。
前期准备
硬件
- 显示:st7735屏幕
- MCU:esp32开发板
- 定位:air551G定位板
- 串口调试:usb2ttl
工具
- 下载代码:luatools
- 定位板调试:naviTrack(也可以不用,直接通过esp32的串口输出读取)
代码
st7735的初始化代码
uart调试代码
坐标转换:
- WGS84转BD09——https://www.openluat.com/GPS-Offset.html
- BD转lcd坐标
代码思路
大致的代码编写流程如下:
1,调试esp32的uart,使用sscom查看uart的读写
2,调整WGS84转BD09的python源码为lua,这个小改就行
3,BD转lcd坐标
4,lcd坐标点显示
比较繁琐的在于BD09转lcd坐标:
我是先取一个起始点的经纬度坐标,将其作为参考点P00作为原点。
后续定位到的点坐标与之相减得到偏移值BD_cur_bias。
基于一个刻度scale_max(偏移值最大值/固定值)对偏移值进行归一化,得到比例Ref_cur_bias
根据比例计算出该偏移值距离lcd中心点(64,64)几个像素点
最后映射到lcd的坐标范围(0,0)-(128,128)
小结一下:BD坐标 --> 差值 --> 归一化比值 --> 原点的lcd偏移 --> 换算lcd点位
画布缩小放大:
此外考虑到定位的百度坐标基于参考点偏移值可能超过刻度,效果就是点无法在当前的lcd屏幕中显示,所以又增加了一个重绘的函数。当超过限定的刻度时,对所有坐标进行重新计算。
这个就相当于我们对地图进行缩小。
画布左移右移:
调整P00的lcd点位,比如原来是(64,64),改为(128,0)
先从百度的拾取坐标系统先定点了学校的几个角坐标,然后绘制图形。
再结合WGS转BD,再转lcd。
最后通过uart获取WGS坐标就可以了。
思路大致是这样的,不过遇到几个问题。
问题
lua浮点型参数双精度
计算时number为小数时,仅保留7位有效数字以及一个小数点,所以计算会有误差。
lcd画点会导致crash
[2022-02-12 15:21:18.439] I/user.74 23 69 23
[2022-02-12 15:21:18.455] Guru Meditation Error: Core 0 panic'ed (Store access fault). Exception was unhandled.
[2022-02-12 15:28:01.448] I/user.68 64 64 64
[2022-02-12 15:28:01.448] Guru Meditation Error: Core 0 panic'ed (Store access fault). Exception was unhandled.
[2022-02-12 15:30:12.171] I/user.64 64 58 64
[2022-02-12 15:30:12.202] Guru Meditation Error: Core 0 panic'ed (Store access fault). Exception was unhandled.
当使用lcd.drawline()时,如果输入坐标的x或者y相同,会导致重启,这个目前不知道怎么解决。
效果
合宙air551G定位及轨迹绘制
运行代码
--- 模块功能:gsensor- esp32_air551G
-- @module air551G
-- @author youkai
-- @release 2022.01.23
-- LuaTools需要PROJECT和VERSION这两个信息
PROJECT = "esp32_mpu6050"
VERSION = "1.0.0"
log.info("main", PROJECT, VERSION)
-- sys库是标配
_G.sys = require("sys")
function init_esp32_st7735 ()
-- spi test ok
-- spi clk is io2, cs is IO7
spi_lcd = spi.deviceSetup(2,7,0,0,8,20000000,spi.MSB,1,1)
log.info("SPI OK")
log.info("lcd.init",
-- st7735 + esp32
lcd.init("st7735",{port = "device",pin_dc = 6, pin_pwr = 11,pin_rst = 10,direction = 0,w = 128,h = 160,xoffset = 0,yoffset = 0},spi_lcd))
log.info("LCD OK")
end
function init_lvgl()
LCD_W, LCD_H = 128,160
-- LCD_W, LCD_H = spi_lcd.getSize()
log.info("lcd", "size", LCD_W, LCD_H )
log.info("init lvgl")
if lvgl.init(128,160) == true then
log.debug("lvgl init ok.")
else
log.debug("lvgl init error.")
end
end
require("t5_uart_air551")
require("t5_draw_bd")
log.info("end require")
--添加硬狗防止程序卡死
-- wdt.init(15000)--初始化watchdog设置为15s
-- sys.timerLoopStart(wdt.feed, 10000)--10s喂一次狗
-- ----------------setup start----------------------
-- 初始化屏幕
init_esp32_st7735 ()
init_lvgl()
-- ----------------setup end------------------------
T1_BD_xy_lib = 0
T2_realtime = 1
-- ================main start================
sys.taskInit(function()
-- ps:有wait不能放在外面
-- display_line ()
-- print("aaaaa")
-- lcd.drawLine(21,22, 21, 47,0x001F)
-- sys.wait(1000)
-- print("bbbb")
-- lcd.update()
-- 测试固定百度经纬度标
if T1_BD_xy_lib == 1 then
init_status()
test_lib()
end
-- 测试实时
if T2_realtime == 1 then
init_rt_test()
end
sys.wait(1500)
while 1 do
if T2_realtime == 1 then
realtime_test()
end
sys.wait(10)
end
end)
-- ================main end==================
sys.run()
require("t5_wgs2lcd")
-- init status
xy_list_BD_temp = {
{119.477546,32.20058},
{119.473719,32.206519},
{119.472255,32.206282},
{119.472237,32.202448},
{119.47795,32.197712},
{119.478418,32.196398},
{119.481714,32.197773},
{119.481481,32.198377},
{119.48069,32.198453}
}
xy_list_BD_temp_num = 0
xy_list_BD_temp_num_max = 0
function table_leng(t)
local leng=0
for k, v in pairs(t) do
leng=leng+1
end
log.info("xy_list_BD_temp len = ",xy_list_BD_temp_num)
return leng
end
LCD_list = {}
LCD_list_temp_num = 0
function draw_line()
-- lcd.clear()
-- sys.wait(1000)
-- 画点,圆半径为2
-- log.info("lcd.drawCircle", lcd.drawCircle(cur_LCD[1],cur_LCD[2],1,0xF800))
log.info("lcd.drawCircle", lcd.drawCircle(LCD_list[2*xy_list_BD_temp_num-1],LCD_list[2*xy_list_BD_temp_num],1,0xF800))
-- 显示坐标信息(lcd/经纬度)
m = cur_BD[1].." , "..cur_BD[2]
-- log.info(type(m),m)
lcd.fill(0, 130, 129, 160) -- 清除显示文本内容
lcd.setFont(lcd.font_opposansm8) --设置字体
lcd.drawStr(0,140,m) -- 显示经纬度
log.info("xy_list_BD_temp_num",xy_list_BD_temp_num)
-- -- 首尾相接
if xy_list_BD_temp_num == xy_list_BD_temp_num_max then
print("xxxxx ebd",xy_list_BD_temp_num)
print(LCD_list[3],LCD_list[4],LCD_list[2*xy_list_BD_temp_num-1],LCD_list[2*xy_list_BD_temp_num])
log.info("lcd.drawLine", lcd.drawLine(LCD_list[3],LCD_list[4],LCD_list[2*xy_list_BD_temp_num-1],LCD_list[2*xy_list_BD_temp_num],0x001F))
-- print(LCD_list[2*xy_list_BD_temp_num-3],LCD_list[2*xy_list_BD_temp_num-2],LCD_list[2*xy_list_BD_temp_num-1],LCD_list[2*xy_list_BD_temp_num])
log.info("lcd.drawLine", lcd.drawLine(LCD_list[2*xy_list_BD_temp_num-1],LCD_list[2*xy_list_BD_temp_num],LCD_list[2*xy_list_BD_temp_num-3],LCD_list[2*xy_list_BD_temp_num-2],0x001F))
end
-- -- 绘制线
if xy_list_BD_temp_num > 1 and xy_list_BD_temp_num < xy_list_BD_temp_num_max then
print("xxxxx",xy_list_BD_temp_num)
log.info(LCD_list[2*xy_list_BD_temp_num-3],LCD_list[2*xy_list_BD_temp_num-2],LCD_list[2*xy_list_BD_temp_num-1],LCD_list[2*xy_list_BD_temp_num])
log.info("lcd.drawLine", lcd.drawLine(LCD_list[2*xy_list_BD_temp_num-3],LCD_list[2*xy_list_BD_temp_num-2],LCD_list[2*xy_list_BD_temp_num-1],LCD_list[2*xy_list_BD_temp_num],0x001F))
m_lcd = LCD_list[2*xy_list_BD_temp_num-3]..","..LCD_list[2*xy_list_BD_temp_num-2].." "..LCD_list[2*xy_list_BD_temp_num-1]..","..LCD_list[2*xy_list_BD_temp_num]
lcd.drawStr(0,155,m_lcd)
end
sys.wait(100) -- 为什么删了就会清空屏幕
end
function init_status()
log.info("init_status 1 ---------------")
-- 首先要设置起始点
init_P00( 119.478979,32.199603 )
set_scale_max( 0.01012100 )
-- 仅用于测试计算该值
xy_list_BD_temp_num_max = table_leng(xy_list_BD_temp)
xy_list_BD_num_max = xy_list_BD_temp_num_max
log.info("init_status 0 ---------------")
end
function test_lib()
log.info("test 1 ---------------")
for i = 1, xy_list_BD_temp_num_max, 1 do
xy_list_BD_temp_num = xy_list_BD_temp_num + 1 -- 记录了多少个点
cur_BD[1] = xy_list_BD_temp[i][1] -- 测试,从表中取出点
cur_BD[2] = xy_list_BD_temp[i][2]
-- 设置当前值
log.info("---------lcd point",i,cur_BD[1],cur_BD[2])
a , b = BD2lcd()
-- print(a , b)
-- table.insert(LCD_list,a)
-- table.insert(LCD_list,b)
-- draw_line()
realtime_draw_line()
print("LCD_list:"..table.concat( LCD_list, ","))
-- GGA_bias2lcd_point() -- 执行转换坐标函数
-- 若最大值更新执行
-- redraw_line()
-- sys.wait(1000)
end
print("LCD_list:"..table.concat( LCD_list, ","))
-- 加上判定
redraw_pic()
-- log.info("xy_list_BD_temp_num",xy_list_BD_temp_num)
log.info("test 0 ---------------")
end
function redraw_pic()
-- print("BD_range",BD_x_max,BD_x_min,BD_y_max,BD_y_min)
range_x = BD_x_max-BD_x_min
range_y = BD_y_max-BD_y_min
if range_x > range_y then
range_bias = range_x
Map_size_max_x = 128
Map_size_max_y = range_y/range_bias*128
else
range_bias = range_y
Map_size_max_x = range_x/range_bias*128
Map_size_max_y = 128
end
if range_bias ~= scale_max then
status_redraw = 1
lcd.clear()
set_scale_max( range_bias )
LCD_max = 128
P00_LCD[1] = math.floor((P00_BD[1]-BD_x_min)/range_x*128)
P00_LCD[2] = math.floor((BD_y_max-P00_BD[2])/range_y*128)
-- set_scale_max( 0.00738400*2 )
-- LCD_max = 64
-- P00_LCD = {64,64}
print("P00_LCD",table.concat(P00_LCD , " , " ))
LCD_list = {}
-- LCD_list = {}
xy_list_BD_temp_num = 0
LCD_list_num = 0
LCD_list_temp_num = 0
test()
else
return
end
end
-- uartid = 1 -- 根据实际设备选取不同的uartid
-- --初始化
-- local result = uart.setup(
-- uartid,--串口id
-- 115200,--波特率
-- 8,--数据位
-- 1--停止位
-- )
-- require("t5_change_draw")
-- require("t5_wgs2lcd")
tag_uart = "test5_uart"
id = 1
len = 1024
get_gga_time = 1000
data_time = ""
data_longitude = "" -- 经度
data_latitude = "" -- 纬度
data_GGA = ""
data_GGA_status = ""
GGA_list = {}
GGA_list["time"] = data_time
GGA_list["x"] = data_longitude
GGA_list["y"] = data_latitude
GGA_list["status"]= data_GGA_status
function rt_init_uart_air551()
-- uart.on(1, "recv", function(id, len)
-- local data = uart.read(1, 1024)
-- log.info("uart2", data)
-- -- libgnss.parse(data)
-- end)
log.info(tag_uart,"init_uart_air551")
uart.setup(1, 115200)
uart_air551_NMEA_set()
-- 定时发送数据
-- timex = sys.timerLoopStart(uart_air551_send,1000)
-- log.info(tag_uart,"time:",timex)
sys.wait(1000)
-- func1: 接收数据,只要收到就接收
-- uart.on(id, "receive",rt_uart_air551_receive)
status_rt_receive = 0
num_rt_receive = 0 --记录当前多少次触发
-- func2: 定时接收
timex = sys.timerLoopStart(rt_uart_air551_receive,get_gga_time)
log.info(tag_uart,"time:",timex)
end
function init_uart_air551()
-- uart.on(1, "recv", function(id, len)
-- local data = uart.read(1, 1024)
-- log.info("uart2", data)
-- -- libgnss.parse(data)
-- end)
log.info(tag_uart,"init_uart_air551")
uart.setup(1, 115200)
uart_air551_NMEA_set()
-- 定时发送数据
-- timex = sys.timerLoopStart(uart_air551_send,1000)
-- log.info(tag_uart,"time:",timex)
sys.wait(1000)
-- func1: 接收数据,只要收到就接收
-- uart.on(id, "receive",uart_air551_receive)
-- func2: 定时接收
timex = sys.timerLoopStart(uart_air551_receive,get_gga_time)
log.info(tag_uart,"time:",timex)
init_air551G_cont() -- 暂时先不显示,后期改进两个界面
end
function uart_air551_send()
-- log.info("uart_air551_send")
uart.write(id, "test")
end
-- 下发命令
function uart_air551_NMEA_set()
log.info("uart_air551_NMEA_set")
uart.write(id, "$PGKC242,0,0,0,1*2A\r\n") --只接收GGA数据。注意需要传入回车符
end
-- 获取串口数据
function rt_uart_air551_receive()
log.info("uart_air551_receive start---------------")
local s = ""
s = uart.read(id, len)
print("#s",#s)
if #s > 0 then -- #s 是取字符串的长度
-- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
-- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
-- log.info("uart", "receive", id, #s, s) -- 这句将接收的都打印出来
status_rt_receive = 1
num_rt_receive = num_rt_receive+1
log.info("get air551","uart", "receive", id, #s)--",s"加上显示串口接收值
-- log.info("uart", "receive", id, #s, s:toHex())
else
return -1
end
data_GGA = get_gga(s)
-- log.info("data_GGA",data_GGA)
get_gga_longitude_latitude(data_GGA)
-- 尝试在uart接收触发时执行画点命令
-- realtime_test()
status_rt_receive = 0
log.info("uart_air551_receive end---------------")
return
end
-- 获取串口数据
function uart_air551_receive()
log.info("uart_air551_receive start---------------")
local s = ""
s = uart.read(id, len)
print("#s",#s)
if #s > 0 then -- #s 是取字符串的长度
-- 如果传输二进制/十六进制数据, 部分字符不可见, 不代表没收到
-- 关于收发hex值,请查阅 https://doc.openluat.com/article/583
-- log.info("uart", "receive", id, #s, s) -- 这句将接收的都打印出来
log.info("get air551","uart", "receive", id, #s,s)
-- log.info("uart", "receive", id, #s, s:toHex())
end
data_GGA = get_gga(s)
log.info("data_GGA",data_GGA)
get_gga_longitude_latitude(data_GGA)
log.info("uart_air551_receive end---------------")
end
--测试数据提取
function test_string_get()
string_temp = "xxxxx$GNGGA,000004.811,XXX,N,XXX,E,0,0,,143.01,M,6.99,M,,*6D\r$GNGGA,000003.811,*6A"
temp_start = string.find(string_temp,'$GNGGA',1)
temp_end = string.find(string_temp,'\r',1)
temp_gga = string.sub(string_temp,temp_start,temp_end-1)
log.info("temp_x:",temp_start,temp_end,temp_gga)
end
-- 提取一组数据
function get_gga(value)
temp_start = string.find(value,'GGA',1)-3
temp_end = string.find(value,'\r',1)
-- print(type(temp_start),type(temp_end))
temp_gga = string.sub(value,temp_start,temp_end-1)
-- log.info("temp_value:",temp_start,temp_end,temp_gga)
return temp_gga
end
function get_gga_longitude_latitude(value_gga)
-- log.info(type(value_gga))
if value_gga == "" then --数据第一次异常
return -1
end
-- 获取GGA数据
-- log.info("L2_temp",L2_temp)
L2_temp = string.sub(value_gga,8) -- +8是因为"$gngga"
-- 获取时间
data_time_h = string.sub(L2_temp,1,2)
data_time_m = string.sub(L2_temp,3,4)
data_time_s = string.sub(L2_temp,4,5)
-- data_time_h = string.t(data_time_h)
data_time_h = math.floor(data_time_h +8)
-- log.info(type(data_time_h),data_time_h)
if data_time_h >= 24 then
data_time_h = data_time_h -24
end
-- data_time_h = tostring(data_time_h)
if data_time_h <10 then
data_time_h = '0'..data_time_h
end
-- log.info(type(data_time_h),data_time_h)
-- data_time_h = tostring(data_time_h)
-- data_time_h = string.(8 + string.toValue(data_time_h))
data_time = data_time_h..":"..data_time_m..":"..data_time_s
-- 获取纬度
L2_temp_x_start = string.find(L2_temp,',',1)+1
L2_temp_x_end = string.find(L2_temp,',N',1)-1
data_longitude = string.sub(L2_temp,L2_temp_x_start,L2_temp_x_end)
-- 获取经度
L2_temp_y_start = L2_temp_x_end+4
-- +4是因为"time,xxx,N,yyy,E",",N"后面三个才是y开始
L2_temp_y_end = string.find(L2_temp,',E',1)-1
data_latitude = string.sub(L2_temp,L2_temp_y_start,L2_temp_y_end)
-- 获取定位指示",E,定位指示,"
L2_temp_status_start = L2_temp_y_end + 4
L2_temp_status_end = L2_temp_status_start
data_GGA_status = string.sub(L2_temp,L2_temp_status_start,L2_temp_status_end)
-- log.info("data_GGA_status",data_GGA_status)
if data_GGA_status == "0" then
log.info("定位指示为0,未定位")
elseif data_GGA_status == "1" then
log.info("定位指示为1,SPS 模式,定位有效")
elseif data_GGA_status == "2" then
log.info("定位指示为2,差分,SPS 模式,定位有效")
end
GGA_list["time"] = data_time
GGA_list["x"] = data_longitude
GGA_list["y"] = data_latitude
GGA_list["status"]= data_GGA_status
-- 返回时间,xy,状态
return GGA_list["time"],GGA_list["x"],GGA_list["y"],GGA_list["status"]
end
function init_air551G_cont()
air551G_cont = lvgl.cont_create(lvgl.scr_act(), nil)
lvgl.obj_set_size(air551G_cont,128,160)
lvgl.obj_set_auto_realign(air551G_cont, true)
lvgl.obj_align_origo(air551G_cont, nil, lvgl.ALIGN_CENTER, 0, 0)
lvgl.cont_set_fit(air551G_cont, lvgl.FIT_NONE) --此时cont未设置自适应状态,则内容在cont中
lvgl.cont_set_layout(air551G_cont, lvgl.LAYOUT_COLUMN_LEFT) --布局靠左
--}
log.info("scr_load",lvgl.scr_load(air551G_cont)) --显示 容器
--创建标签label
GGA_label = lvgl.label_create(air551G_cont, nil)
lvgl.label_set_text(GGA_label, "GGA_data")
lvgl.obj_set_pos(GGA_label, 2, 5)
end
function set_air551G_cont()
string_GGA = "GGA_data"..'\r'.."time: "..GGA_list["time"]..'\r'.."x: "..GGA_list["x"]..'\r'.."y: "..GGA_list["y"]..'\r'.."status: "..GGA_list["status"]
log.info("string_GGA",string_GGA)
if string_GGA == "" then
return -1
end
lvgl.label_set_text(GGA_label, string_GGA)
end
function ddmmmm2dd()
-- 计算失败
-- temp_dd_lng = string.format("%.10f", a) -- 字符转浮点
temp_dd_lng = string.format("%.10f", lng_ddmmmm) -- 字符转浮点
-- print("temp: ",temp_dd_lng ,type(temp_dd_lng))
local dd_lng_int = math.floor(temp_dd_lng/100)
local dd_lng_float = (temp_dd_lng-dd_lng_int*100)*100/60
-- log.info("dd_lng_float",type(dd_lng_float))
local dd_lng = dd_lng_int + dd_lng_float/100
print("dd_lng = ",dd_lng_int,dd_lng_float,dd_lng)
-- temp_dd_lat = string.format("%.10f", b) -- 字符转浮点
temp_dd_lat = string.format("%.10f", lat_ddmmmm) -- 字符转浮点
-- print("temp: ",temp_dd_lat)
local dd_lat_int = math.floor(temp_dd_lat/100)
local dd_lat_float = (temp_dd_lat-dd_lat_int*100)*100/60
local dd_lat = dd_lat_int + dd_lat_float/100
print("dd_lat = ",dd_lat_int,dd_lat_float,dd_lat)
return dd_lng,dd_lat
end
require("t5_BD2lcd")
require("t5_wgs2BD")
require("t5_uart_air551")
function wgs2lcd(x,y)
-- wgs ddmm格式转为BD09
BD_x , BD_y = ddmm2BD(x,y)
print(BD_x , BD_y )
set_cur(BD_x,BD_y)
temp_lcd_x ,temp_lcd_y = BD2lcd()
return temp_lcd_x ,temp_lcd_y
end
function rt_draw_line()
if LCD_list_temp_num > 2 then
-- -- 绘制线 and LCD_list_temp_num < xy_list_BD_num_max
if LCD_list_temp_num > 2 then
print("normal draw line",LCD_list_temp_num)
log.info(LCD_list[2*LCD_list_temp_num-3],LCD_list[2*LCD_list_temp_num-2],LCD_list[2*LCD_list_temp_num-1],LCD_list[2*LCD_list_temp_num])
log.info("lcd.drawLine", lcd.drawLine(LCD_list[2*LCD_list_temp_num-3],LCD_list[2*LCD_list_temp_num-2],LCD_list[2*LCD_list_temp_num-1],LCD_list[2*LCD_list_temp_num],0x001F))
end
end
end
function realtime_draw_line()
-- 画当前的点
log.info("lcd.drawCircle", lcd.drawCircle(LCD_list[2*LCD_list_temp_num-1],LCD_list[2*LCD_list_temp_num],1,0xF800))
-- 显示坐标信息(lcd/经纬度)
m_BD = "BD:"..cur_BD[1].." , "..cur_BD[2]
m_lcd = "lcd:"..LCD_list[2*LCD_list_temp_num-1].." , "..LCD_list[2*LCD_list_temp_num]
-- log.info(type(m),m)
lcd.fill(0, 130, 128, 145) -- 清除显示文本内容
lcd.fill(0, 145, 64, 160)
lcd.setFont(lcd.font_opposansm8) --设置字体
lcd.drawStr(0,140,m_BD) -- 显示经纬度
lcd.drawStr(0,155,m_lcd) -- 显示经纬度
-- log.info("LCD_list_temp_num",LCD_list_temp_num)
rt_draw_line()
sys.wait(100) -- 为什么删了就会清空屏幕
end
function init_rt_test()
-- 初始化uart
rt_init_uart_air551()
status_P00 = 0
num_uart_re = 0
end
function rt_wgs2lcd()
--获取当前经纬度及状态
rt_x ,rt_y = GGA_list["x"],GGA_list["y"] -- 待uart输入
rt_status = GGA_list["status"]
-- print(num_rt_receive)
lcd.fill(64, 145, 128, 160)
lcd.setFont(lcd.font_opposansm8)
lcd.drawStr(64,155,num_rt_receive)
-- 注意此时状态为字符型
if rt_status == "1" then
-- 未定位起始点
if status_P00 == 0 then
-- print("P00_BD")
print( "WGS_ddmm : ("..rt_x.." , "..rt_y..")" ,"status"..rt_status)
init_P00(ddmm2BD(rt_x ,rt_y))
set_scale_max( 0.0002 )
-- 清空坐标表
xy_list_BD = {}
xy_list_BD_num = 0
xy_list_BD_num_max = 0
LCD_list = {}
LCD_list_temp_num = 0
cur_BD_bias = {}
cur_Ref = {}
cur_LCD = {}
BD_x_max = 0
BD_x_min = 0
BD_y_max = 0
BD_y_min = 0
status_P00 = 1
end
-- 已经定位了起始点
if status_P00 == 1 then
print("************** point start****************")
xy_list_BD_num = xy_list_BD_num+1
-- 记录当前坐标个数
if xy_list_BD_num_max < xy_list_BD_num then
xy_list_BD_num_max = xy_list_BD_num
end
print( "WGS_ddmm : ("..rt_x.." , "..rt_y..")" ,"status"..rt_status)
-- 转换位BD09
BD_temp_x ,BD_temp_y = ddmm2BD(rt_x ,rt_y)
-- 存储百度坐标
table.insert( xy_list_BD, BD_temp_x )
table.insert( xy_list_BD, BD_temp_y )
-- 存储当前处理的百度坐标,后续运算直接用该值
cur_BD[1] = BD_temp_x
cur_BD[2] = BD_temp_y
-- 打印当前的百度坐标
print("BD_ddd : ("..cur_BD[1].." , "..cur_BD[2]..")","LCD_list_temp_num : ",LCD_list_temp_num )
-- log.info("**lcd point : ",LCD_list_temp_num,"("..cur_BD[1].." , "..cur_BD[2]..")")
-- 百度坐标转换为lcd坐标
rt_lcd_x , rt_lcd_y = BD2lcd()
realtime_draw_line()
print("LCD_list:"..table.concat( LCD_list, ","))
print("************** point end****************")
end
rt_status = "0"
else
-- print("当前未定位")
end
-- 画一个点就重绘,用于及时放大
-- rt_redraw_pic()
end
-- 获取uart数据并画点
function realtime_test()
-- print("num_rt_receive",num_rt_receive,"num_uart_re",num_uart_re)
if num_rt_receive > num_uart_re then
num_uart_re = num_rt_receive
rt_wgs2lcd()
end
end
function rt_redraw_pic()
-- print("BD_range",BD_x_max,BD_x_min,BD_y_max,BD_y_min)
-- 计算所有百度坐标的经纬度最大差值(用于映射到lcd中)
range_x = BD_x_max-BD_x_min
range_y = BD_y_max-BD_y_min
if range_x > range_y then
range_bias = range_x
Map_size_max_x = 128
Map_size_max_y = range_y/range_bias*128
else
range_bias = range_y
Map_size_max_x = range_x/range_bias*128
Map_size_max_y = 128
end
-- 重绘时如果当前的归一化度量小于最大偏移,就重新画坐标
if range_bias ~= scale_max then
print("重新绘制")
status_redraw = 1
lcd.clear()
set_scale_max( range_bias )
LCD_max = 128
P00_LCD[1] = math.floor((P00_BD[1]-BD_x_min)/range_x*128)
P00_LCD[2] = math.floor((BD_y_max-P00_BD[2])/range_y*128)
-- set_scale_max( 0.00738400*2 )
-- LCD_max = 64
-- P00_LCD = {64,64}
print("P00_LCD",table.concat(P00_LCD , " , " ))
LCD_list = {}
xy_list_BD_temp_num = 0 -- 当前处理BD点数
LCD_list_temp_num = 0 -- 当前处理的lcd点数
-- test()
else
return
end
end
-- 输入BD09转化为lcd画点坐标(0,0)-(128,128)
status_redraw = 0
-- 变量
cur_BD = {}-- /xn,yn
cur_BD_bias = {}
cur_Ref = {}
cur_LCD = {}
-- 固定量,若固定量改变则所有的都要变
P00_BD = { } -- /x0,y0
scale_max = 0.00738400 --BD最大偏移值,2scale_max 映射 128 这是图像精度,变小则图像在lcd上绘制大
LCD_max = 64 --64/128
-- LCD_max_x =
-- LCD_max_y =
P00_LCD = {64,64} --64,64(参照点在屏幕中心) / 128,0(这个是参照点在屏幕左上角) -- x0,y0在lcd上坐标偏移
P00_Ref = {0,0} --暂时用不上,默认起始点对应0,0
BD_x_max = 0
BD_x_min = 0
BD_y_max = 0
BD_y_min = 0
-- lcd坐标范围
LCD_x_max = 128
LCD_x_min = 0
LCD_y_max = 128
LCD_y_min = 0
-- 存储画点数据
LCD_list = {}
LCD_list_temp_num = 0
xy_list_BD = {
}
xy_list_BD_num = 0
xy_list_BD_num_max = 0
-- init
function init_P00(x,y)
P00_BD[1] = x
P00_BD[2] = y
print("init_P00 BD",x,y)
BD_x_max = x
BD_x_min = x
BD_y_max = y
BD_y_min = y
print("BD_range",BD_x_max,BD_x_min,BD_y_max,BD_y_min)
return x,y
end
function set_cur(x,y)
cur_BD[1] = x
cur_BD[2] = y
print("set_cur",x,y)
return x,y
end
function set_scale_max(max)
scale_max = max
print("scale_max is:",scale_max)
return 1
end
function judge_BD_range(x_c,y_c)
-- log.info("judge_BD_range 1 ---------------")
-- print(x_c,y_c)
if x_c>BD_x_max then
BD_x_max = x_c
else if x_c<BD_x_min then
BD_x_min = x_c
end
end
if y_c>BD_y_max then
BD_y_max = y_c
else if y_c<BD_y_min then
BD_y_min = y_c
end
end
-- print("BD_range",BD_x_max,BD_x_min,BD_y_max,BD_y_min)
end
-- change
function BD_cur_bias(x_c,y_c,x_0,y_0)
-- 取当前坐标最值
-- 计算基于起始点的BD偏移
if type(x_0) == "nil" or type(y_0) == "nil" then
-- print("Please set start xy.")
else
print("now start xy is ",x_0.." , "..y_0)
end
if type(x_c) == "nil" or type(y_c) == "nil"then
-- print("BD_cur_bias no input")
-- print("P00_BD",table.concat( P00_BD , ","))
-- print("cur_BD",table.concat( cur_BD , ","))
BD_bias_x = cur_BD[1]-P00_BD[1]
BD_bias_y = cur_BD[2]-P00_BD[2]
judge_BD_range(cur_BD[1],cur_BD[2])
else
-- print("BD_cur_bias has input")
BD_bias_x = x_c - x_0
BD_bias_y = y_c - y_0
judge_BD_range(x_c,y_c)
end
-- 存储当前BD偏移
cur_BD_bias[1] = BD_bias_x
cur_BD_bias[2] = BD_bias_y
-- print("BD_cur_bias",table.concat(cur_BD_bias,','))
-- print(BD_bias_x,BD_bias_y)
return BD_bias_x,BD_bias_y
end
function Ref_cur_bias(x,y,lcdmax,scalemax)
-- 归一化,计算基于 0,0的参考偏移
if type(x) == "nil" or type(y) == "nil" or type(lcdmax) == "nil" or type(scalemax) == "nil" then
-- print("Ref_cur_bias no input")
Ref_bias_x = math.floor(cur_BD_bias[1]*LCD_max/(scale_max)) -- + P00_Ref[1]
Ref_bias_y = math.floor(cur_BD_bias[2]*LCD_max/(scale_max)) -- + P00_Ref[2]
else
Ref_bias_x = math.floor(x*lcdmax/(scalemax)) -- + P00_Ref[1]
Ref_bias_y = math.floor(x*lcdmax/(scalemax)) -- + P00_Ref[2]
end
-- 存储参考偏移
cur_Ref[1] = Ref_bias_x
cur_Ref[2] = Ref_bias_y
-- print("Ref_cur_bias",table.concat(cur_Ref,','))
return Ref_bias_x,Ref_bias_y
end
function LCD_cur(x_c,y_c,x_0,y_0)
-- 归一化,计算基于 0,0的参考偏移
if type(x_c) == "nil" or type(y_c) == "nil" or type(x_0) == "nil" or type(y_0) == "nil" then
-- print("LCD_cur no input")
LCD_x = P00_LCD[1]+cur_Ref[1]
LCD_y = P00_LCD[2]-cur_Ref[2]
else
LCD_x = x_0+x_c
LCD_y = y_0-y_c
end
print("LCD_cur",LCD_x..' , '..LCD_y)
-- 防止超出屏幕
if LCD_x > LCD_x_max then
LCD_x = LCD_x_max
elseif LCD_x < LCD_x_min then
LCD_x = LCD_x_min
end
if LCD_y > LCD_y_max then
LCD_y = LCD_y_max
elseif LCD_y < LCD_y_min then
LCD_y = LCD_y_min
end
-- 存储参数
cur_LCD[1] = LCD_x
cur_LCD[2] = LCD_y
table.insert(LCD_list,LCD_x)
table.insert(LCD_list,LCD_y)
LCD_list_temp_num = LCD_list_temp_num + 1
print("LCD_list_temp_num: ", LCD_list_temp_num) -- 显示当前记录的点个数
-- print("LCD_cur",table.concat(cur_LCD,' , '))
return LCD_x,LCD_y
end
-- function BD2lcd(temp_P00_BD , temp_cur_BD, temp_scale_max , temp_LCD_max , temp_P00_LCD)
-- end
-- 直接基于全局变量运算
function BD2lcd()
-- 计算基于起始点的经纬度偏移
BD_cur_bias()
-- 归一化当前lcd坐标
Ref_cur_bias()
-- 返回计算的lcd坐标
return LCD_cur()
end
-- 方法1:直接对全局变量进行处理
-- BD2lcd()
-- 方法2:对入参进行处理
-- LCD_cur(Ref_cur_bias(BD_cur_bias(cur_BD[1],cur_BD[2],P00_BD[1],P00_BD[2]),scale_max,LCD_max),P00_LCD[1],P00_LCD[2])
-- 方法3:传入数组处理,相当于1
-- function input_all_value(cutBD,P00BD,scalemax,lcdmax,P00lcd)
-- LCD_cur(Ref_cur_bias(BD_cur_bias(cutBD[1],cutBD[2],P00BD[1],P00BD[2]),scalemax,lcdmax),P00lcd[1],P00lcd[2])
-- end
-- input_all_value(cur_BD,P00_BD,scale_max,LCD_max,P00_LCD)