3

HelloKun--开源鸿蒙车机系统OHCar

 1 year ago
source link: https://os.51cto.com/article/713739.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

HelloKun--开源鸿蒙车机系统OHCar-51CTO.COM

HelloKun--开源鸿蒙车机系统OHCar
作者:Hello_Kun 2022-07-11 16:11:11
便捷而又炫酷的智慧生活极致体验,由OpenHarmony为你打造。再想象一下,通过OHCar,对话家里的MRobot,为你开启下一段贴心服务!
b7942ca005d1a4b2e12546f131a7d0aeae43ca.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

一、OHCar ?

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

想象一下,现在你正忙完一天的工作准备下班回家,担心车辆能源不足?天气太热或太冷?于是在走到楼下停车位上的Dream Car前,拿出鸿蒙手机打开车辆专属的管家APP,提前检测剩余能量百分比,打开车载空调。到达车前的你不愿意掏出钥匙,顺手用手机碰一碰车门,只需点击弹出窗口中的解锁按钮即可进入车中。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区
#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

坐进驾驶舱,OHCar又一次为你开启贴心服务。加载页面中红黑经典表盘与激情澎湃背景视频,短暂而又丝滑的过度只为让你忘却一天的疲惫。进入系统后,手指轻轻一戳,一键唤醒你的DreamCar。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区
#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

出发前,你打算先来一首音乐,或者刷一段冰冰的甜美笑容,又或者看一段Jay的最新MV,这些,OHCar都能给你。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区
#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区
#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

当然,安全出行第一步。嫌弃屏幕太暗?打开设置,亮度一步到位。终于,你已经释放掉50%的疲惫感,准备一脚油门回到家中。别急,马路拥挤,实时导航能不能有? 当然,OHCar一直为你保驾护航。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区
#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

下班回家的路上,一切操作丝般顺滑,你享受着空调,听着Jay的音乐,踩着油门一路向北!

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区
#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

便捷而又炫酷的智慧生活极致体验,由OpenHarmony为你打造。再想象一下,通过OHCar,对话家里的​​MRobot​​,为你开启下一段贴心服务!

二、OHCar项目简介

1、项目说明

  • Dayu200体验官活动之初决定做车载中控,设想是在汽车模型中实现车辆信息监测、无钥匙解锁、车辆控制能力、导航地图以及影音娱乐等功能,并配备移动端车辆管家。OHCar便是该设想的落地,基于现有开源鸿蒙的系统能力,基本实现了上述功能,只需手机碰一碰解锁车辆,还可在APP中控制车载空调、查看剩余电量、获取车辆位置等信息,进入车辆后,可在dayu200上操控车辆,仪表区、车载APP、系统设置一应俱全。
  • 从技术角度而言,车机中使用ArkUI框架中的ets语言开发,结合条件渲染,让Video、Web等组件实现同框显示,自定义数据类实现动画;智能车控硬件方面,dayu200做车辆中控,再使用两个hi3861 iot核心板、一个Arduino Nano协同实现车辆控制,电源测量模块获取电量,GPS模块测量位置信息,笔记本风扇模拟车载空调,为实现影音功能,使用音频解码与放大板实现音响。总的来说,OHCar软硬件均属鸿蒙生态,展示出开源鸿蒙在车载系统中极具潜力。本文从OHCar的功能角度分解说明项目,并在其中讲解使用到的关键技术,更多技术细节移步Gitee仓库。demo视频​​OHCar视频​​。
  • 注:
    dayu200: OH系统版本:OpenHarmony3.1Release ;IDE: 3.0.0.900 ; APP:ArkUI -ets。
    hi3861: OpenHarmony 1.0.1 Release ,C语言。
    车管家(手机端): HarmonyOS API 6 ,JS语言。

2、OHCar软硬件简介

OHCar项目框架组成如下图,dayu200作为上层的控制终端,提供车辆仪表信息显示、影音娱乐等服务,使用TCP传输驾驶员的操控指令;②号hi3861接收到数据后进行预处理(如获取车辆温湿度,车内烟雾监测),非本地指令则通过uart转给车辆底层的mcu;①号hi3861则提供无钥匙解锁、电量、定位的信息获取、车载空调操控等功能。底层mcu直接负责车辆的操控,如电机控制,实时性强,同时也方便实现软硬件隔离。各模块分工明确但又紧密配合。所有各模块(除dayu200外)均安装于经典2003款 Ferrari Enzo 模型中,只为直观展示上述功能。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

三、OHCar车载系统实现

以APP形式模拟OHCar车载系统,APP基于ArkUI框架中的est语言开发,运行在dayu200之上,APP包括系统启动页、操控UI页、系统设置页、本地视频播放页。启动页是模拟车载系统开机;操控UI页面包含系统展示窗、车载APP(音乐、地图、Blibili)、仪表盘、车辆操控。系统设置页目前支持屏幕亮度调节功能;本地视频播放页用于播放视频文件,提高影音娱乐功能。

车载系统模拟APP架构总结如下图:

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

打开DevEco Studio 3.0.0.900, 新建一个基于ets的工程,API为8。详情见​​环境搭建​​。下面对OHCar项目中的关键功能模块的实现进行说明。

1、系统启动页面

系统启动页模拟车机开机启动画面,使用到Video组件展示加载视频,Canvas绘制表盘,结合定时器实现指针摆动,最后使用Stack容器实现覆盖效果。关键代码如下,具体实现可参考这篇帖子​​首页aito视频&Canvas绘制仪表盘​​。

Stack()
     {
          Video({
            src: this.srcs,
            previewUri: this.previewUris,
            currentProgressRate: this.currentProgressRates,
            controller: this.controller
          }).width('100%').height('100%')
            .objectFit(ImageFit.Cover)
            .autoPlay(true)
            .controls(this.controlsss)
            .onFinish(() => {
              console.error('onFinish');
             router.push({url:'pages/gauge'})
            })
          // 仪表盘
          Row({ space: 0 }) {
          //油门表
          MyGauge()
       Column() {
              Canvas(this.car_gauge)
                .width('45%')
                .height('20%')
                .backgroundColor('#000000')
                .onReady(() => {
                  //表环-车速
                 this.car_gauge.clearRect(-100, -100, 600, 600);
                 this.car_gauge.beginPath()
                 this.car_gauge.translate(0, 0)
                 this.car_gauge.shadowBlur = 30
                 this.car_gauge.shadowColor = this.car_gauge_col
                 this.car_gauge.arc(this.gauge_speed_x, this.gauge_speed_y, 100, 0, 6.28)
                 this.car_gauge.fillStyle = 'black'
                 this.car_gauge.fill()
                 this.car_gauge.closePath()
            //数字环、指针 操作类似,略过
        //车速
             Text(this.car_velocity+" KM/H")
                .fontSize(40).height(40).fontStyle(FontStyle.Italic).textAlign(TextAlign.Center)
                .backgroundColor('black').fontColor('white')
      }
       //电量表
            Gauge({ value: this.fuel_value, min: 0, max: 120 })
              .startAngle(240)
              .endAngle((this.fuel_value))
              .colors([[0x5BA854, 0.5],[0xCFB53B, 0.5],[0xF01020, 0.5] ])
              .strokeWidth(30)
              .width(120)
              .height(120)
              .margin({top:30})
      }
    }
  }

2、操控页面——系统展示窗

操控UI页面的系统展示窗模拟车辆的中控屏,用于显示车辆状态、内置app。使用条件渲染将自定义component(音乐、地图、Blibili)展示出来。内置车载APP用web组件模拟(dayu200 联网后可实现网页加载。)

关键实现代码如下:

Column({ space:0 }) {
            if(this.display_flag==1) {
              Video({
                src: this.srcs,
                currentProgressRate: this.currentProgressRates,
                controller: this.controller
              })
                .width('100%')
                .height('80%')
                .objectFit(ImageFit.Fill)
                .autoPlay(this.autoPlays)
                .controls(this.controlsss)
                .onStart(() => {
                  console.error('onStart');
                })
            }
            else if(this.display_flag==2)
            {
              Column()
              {
                qqmusic()
              }.height('80%').alignItems(HorizontalAlign.Center)
            }
            else if(this.display_flag==3)
            {
                Column()
                {
                  amap()
                }.height('80%').alignItems(HorizontalAlign.Center)
            }
            else if(this.display_flag==4)
            {
                Column()
                {
                  Bilibili()
                }.height('80%').alignItems(HorizontalAlign.Center)
           }
//web实现如下:
@Component
struct Bilibili {
  @State message: string = 'Hello World'
  controller: WebController = new WebController();
  build() {
      Column()
      {
        Web({ src: 'https://www.bilibili.com/', controller: this.controller })
      }
      .width('100%')
      .height('100%')
    .backgroundColor('black')
  }
}

3、操控页面——仪表盘

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

车辆仪表区用于模拟车机的仪表盘,从左到右依次用于展示能源余量、时速、油门大小。其中时速表盘、油门大小可随操控按钮(2.4节介绍)动态加载。时速表盘使用Canvas画布实现,油门表使用Gauge组件实现。具体实现可参考这篇帖子​​首页aito视频&Canvas绘制仪表盘​​。

4、操控页面——车辆控制

车辆控制区用于模拟车辆实际操控,如一键启动、驾驶(油门、方向、刹车)、开门、灯光、甚至是升降Dream Car的尾翼。UI使用Buttom、Image基础组件布局,实现比较简单。控件触发事件后,调用Socket接口,将控制量发送到目标ip中(hi3861中),下面代码举例说明如何将一键启动触发后将消息通过socket接口发送出去,关于Socket tcp通信实现可参考该文档​​Socket连接​​。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区
tcpSend() {
    tcp.getState().then((data) => {
      if (data.isConnected) {
        //发送消息
        tcp.send(
          { data: this.message_send, }
        ).then(() => {
          prompt.showToast({message:"send message successful"})
        }).catch((error) => {
          prompt.showToast({message:"send failed"})
        })
      } else {
        prompt.showToast({message:"tcp not connect"})
      }
    })
  }
 //一键启动
          Button({ type: ButtonType.Circle, stateEffect: true }) {
            Image($r('app.media.engine')).objectFit(ImageFit.Contain)
          }
          .width(90)
          .height(90)
          .margin({ top: 1, left: 80 })
          .backgroundColor(this.engine_btn_col)
          .onClick(() => {
            this.car_gauge_col = 'white'
            this.srcs = $r('app.media.ferrari_start')
            this.controller.start()
            this.click_times += 1
            this.tcpConnect()
            if (this.click_times % 2 != 0) {
              this.engine_btn_col = 0x32c5ef
              this.update_canvas();
            }
            else
            {
              this.engine_btn_col = 0xCBD3D0
              this.click_times = 0;
            }
            prompt.showToast({
              message: "Start Engine:" + this.car_velocity,
            })
          })

5、系统设置与视频播放

系统设置功能页面主要使用brightness接口调节屏幕亮度。另外,还使用class自定义车辆信息类,为动态展示车辆提供参考。视频播放使用Video组件实现,音频的输出经过车载的音频放大器播放,关键代码如下:

import brightness from '@ohos.brightness';
 Row()
        {
          Text('亮度').fontColor('blue').fontSize('35').width('10%').borderRadius(30).margin({top:10,left:30})

          Slider({
            value: this.brightness,
            min: 100,
            max: 255,
            step: 1,
            style: SliderStyle.OutSet
          })
            .width('80%').height('100%') .blockColor('blue').trackColor(Color.Black)    
            .onChange((value: number, mode: SliderChangeMode) => {
              this.brightness = value
              brightness.setValue(this.brightness);
              console.info('value:' + value + 'mode:' + mode.toString())
            }).width('75%')
          Text(this.brightness.toFixed(0)).fontSize(30).width('15%').fontColor('blue')
        }.height('10%').backgroundColor('white')

四、OHCar车辆管家介绍

智能时代,车载系统不应该仅仅是独立的系统,基于OpenHarmony的OHCar可为用户提供优质全面的服务。车辆管家运行于HarmonyOS 2.0 的移动端,依托NFC短距通信协议,通过碰一碰的交互方式,将手机和OHCar连接起来。然后通过手机端的原子化服务能力,快速完成配网、连接OHCar,提供无钥匙开门、监测车辆信息的服务。 类似的开发案例可参考本人这篇教程 ​​碰一碰系列分享总贴​​。

1、UI开发

UI布局使用js开发,具体方式参考该文档 ​​JS开发APP​​。车辆管家UI直观,展示信息如下图,电量、位置信息的获取来自于hi3861端,空调、车门控制消息也发送至hi3861端。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

2、碰一碰与数据传输

车辆管家的技术核心是调用JS接口完成设备配网、消息发送。获取设备ID、发送消息接口核心代码如下(可参考本贴​​JS通信接口​​):

//需引入 import {getApp} from '../../common.js';  
 sendMessage()
    {
        var message = this.app_msg;
        let commonInfo = {
            sessionId: getApp(this).ConfigParams.deviceInfo.sessionId
        };
        getApp(this).NetConfig.sendMessage(commonInfo, message,(result)=>{
            if(result.code ==0) {  prompt.showToast({message:'发送成功'})}
            else{prompt.showToast({message:'发送失败'})}
            });
    },

五、OHCar南向开发

南向开发分为三部分,分别对应车载系统UI南向开发、车辆管家APP南向开发、车辆硬件实时控制系统实现(电机、灯光等)。

1、车载系统协同

车载系统协同依靠dayu200与hi3861之间的TCP通信,南向开发也主要是针对该通信数据进行处理,hi3861端作为TCP服务器,接收dayu200发送的操作指令。hi3861也可采集车辆温湿度、烟雾信息,有需求可上报至dayu200端。如何建立二者之间的TCP连接可参考本人这篇教程 ​​#DAYU200#体验官Hi3861与dayu200通信​​ 。下图是南向功能框架。

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

下面给出将dayu200数据发送值车载mcu、将温湿度烟雾发送至dayu200的关键代码:

while (1)
    {
      AHT20_Calibrate();
      AHT20_StartMeasure();
      AHT20_GetMeasureResult(&EnvData.temp_val, &EnvData.humi_val);
      EnvData.ppm_val = Get_MQ2_PPM();
      if ((ret = recv(new_fd, recvbuf, sizeof(recvbuf), 0)) == -1)
      {
        printf("recv error \r\n");
      }
      printf("recv :%s\r\n", recvbuf);
      const unsigned char msg_cmd = recvbuf[0];
      //hi_uart_write(1, &msg_cmd, 1);
      UartWrite(1, &msg_cmd, 1);
      if (msg_cmd == 'x')
      {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0);
        hi_udelay(80000);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 1);
      }
      if (msg_cmd == 'y')
      {
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0);
        hi_udelay(80000);
        GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 1);
      }
      Float2String(buf, EnvData.humi_val, 2);
      if ((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1)
      {
        perror("send : ");
      }
      Float2String(buf, EnvData.ppm_val, 2);
      if ((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1)
      {
        perror("send : ");
      }
      Float2String(buf, EnvData.ppm_val, 2);
      if ((ret = send(new_fd, buf, strlen(buf) + 1, 0)) == -1)
      {
        perror("send : ");
      }
      GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_14, 0);
      GpioSetOutputVal(WIFI_IOT_IO_NAME_GPIO_8, 0);
      sleep(1);
    }

2、车辆管家协同

车载系统协同依靠移动端NFC短距通信,碰一碰车门上的NFC标签后,启动原子化服务后与hi3861通信,hi3861将GPS模块采集位置信息、电压采集模块采集汽车电量传输至车辆管家APP端;同时也可接收开门指令,实现无钥匙解锁。该部分南向工程架构如下(详细见附件):

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

NAN配网关键接口如下,具体参考本人这篇教程​​设备配网​​。

include:
│   ├── netcfg.h   // 无感配网注册相关接口
│   ├── network_config_service.h //无感配网相关头文件。
libs:
├── libs
│   ├── libhilinkadapter_3861.a // 无感配网相关库文件。
│   └── libnetcfgdevicesdk.a // 无感配网相关库文件。
src:
    ├── netcfg.c // NAN相关操作和联网动作
const char *g_ssid = "OHCar     ";
const char *g_pinCode = "11111111";
const char *g_productId = "1";
const char *g_sn = "0123/.,.,4567890123450123456789012345";
···
devInfo[0].key = "productId";
devInfo[1].key = "sn";
devInfo[0].value = g_productId;
devInfo[1].value = g_sn;
ret = StartNetCfg(devInfo, DEVICE_INFO_NUM, NETCFG_SOFTAP_NAN); //SoftAP and NAN模式 
//上报电量、位置信息、控制模拟空调
    if (strcmp(app_msg, "turn off air") == 0)
    {
        IoTGpioSetOutputVal(FAN_IO1, IOT_GPIO_VALUE0);
        IoTPwmStart(1, 0, 80000);
        printf("turn off air \r\n");
        app_msg[0] = '9';
        return;
    }
    if (strcmp(app_msg, "car location") == 0)
    {
        // Bluetooth_read(location2app, 18)   //室内GPS信号弱
        strncpy(location2app, "N:110.20  E:19.220 addr", 18);
        SendRawData(&location2app); // 将消息发到FA
        printf("car location\r\n");
        app_msg[0] = '9';
        return;
    }
    if (strcmp(app_msg, "car fuel") == 0)
    {
        fuel_val = GetVoltage();
        float percent_vol = 1000 * fuel_val / FULL_FUEL;
        Float2String(percent_vol, &temp_str, 2);
        strncpy(fuel2app, temp_str, 5);
        SendRawData(&fuel2app); // 将消息发到FA
        printf("get car fuel \r\n");
        app_msg[0] = '9';
        return;
    }

3、车辆控制

#DAYU200体验官#【HelloKun】开源鸿蒙车机系统OHCar-开源基础软件社区

2

车辆电机、车门、尾翼以及灯光控制使用另一块io接口多一些的mcu实现(5组灯光、6个舵机),mcu实时接收两块hi3861的控制指令,完成最底层的控制。从车载系统到车辆管家,再到hi3861,最终到mcu,遵循的报文如下,有助于了解项目:

typedef enum MSG_CMD {
  MOVE_GO = 'a',
  MOVE_BACK,
  MOVE_LEFT,
  MOVE_RIGHT, //移动
  OPEN_LEFT_DOOR,
  CLOSE_LEFT_DOOR,
  OPEN_RIGHT_DOOR,
  CLOSE_RIGHT_DOOR,//车门
  SPOILER_UP,
  SPOILER_DOWN,  //尾翼
  MOVE_GO_LIGHT,
  MOVE_BACK_LIGHT,
  WARRING_LIGHT_ON,
  WARRING_LIGHT_OFF
};

从技术上讲,实际的车载系统比文中说的要复杂、严苛很多。不过openHarmony作为万物互联时代下的产物,未来用于车载系统还是值得期待的。借此项目可了解openHarmony以及在dayu200上的开发方式,学习ARkUI框架、est语言。

都说田家少闲月,五月人倍忙,自从疫情之后很多事被打乱,一到窗口期就是“5月",不知不觉dayu200体验官活动也接近尾声,感谢平台的支持与各位老师的直播分享,让我天马行空想法得以实现。

附件说明:

OHCar_CenterSystem:dayu200运行的车载系统-源码。

OHCar_phone_app: 移动端车辆管家-源码。

OHCar_nfc: 车辆管家南向开发-源码。

OHCar_tcp: 车载系统南向开发-源码。

文章相关附件可以点击下面的原文链接前往下载

https://ost.51cto.com/resource/2161。

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​​。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK