【LuatOS-air551G】6 定位并绘制路线图--初版

本文探讨了如何使用合宙air551G定位模块与st7735 LCD屏配合,展示实时路线的过程,重点讲述了浮点型参数处理、坐标转换导致的crash问题,以及如何通过缩放和重绘解决地图显示问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

本章整理一下使用合宙air551G定位并在st7735 屏幕上显示实时路线的一些问题。

前期准备

硬件

  1. 显示:st7735屏幕
  2. MCU:esp32开发板
  3. 定位:air551G定位板
  4. 串口调试:usb2ttl

工具

  1. 下载代码:luatools
  2. 定位板调试:naviTrack(也可以不用,直接通过esp32的串口输出读取)

代码

st7735的初始化代码
uart调试代码
坐标转换:

  1. WGS84转BD09——https://www.openluat.com/GPS-Offset.html
  2. 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)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值