OpenHarmony南向开发案例:【智能体重秤】

一、简介

本demo基于OpenHarmony3.1Beta版本开发,该样例能够接入数字管家应用,通过数字管家应用监测体重秤上报数据,获得当前测量到的体重,身高,并在应用端形成一段时间内记录的体重值,以折线图的形式表现出来,根据计算的BMI值来提醒当前身体健康状态,推送健康小知识。

1.交互流程

交互图

如上图所示,智能体重称整体方案原理图可以大致分成:智能体重称设备、数字管家应用、云平台三部分。智能体重称通过MQTT协议连接华为IOT物联网平台,从而实现命令的接收和属性上报。

2.实物简介

实物图

如上图示,左边为xr806模组,右边为超声波测距模块,echo脚连接PA19,Triq脚连接PA20,Vcc脚连接5V电源,Gnd脚接地,

14

如上图示,右边为称重模块,clk脚接PB15,dt脚接PB14,vcc脚接5V,gnd脚接地,称重传感器红色线接E+,黑色线接E-,白色线接A-,绿色线接A+

左边xr806模块左下角k1按键,长按k1按键不放,同时上电,4-5秒后松开按键,可以清除已保存得配网信息

xr806模块,在设备正常工作后,按k1按键,可以初始化当前得重量为0,高度为0

3.实物操作体验

操作图

二、 快速上手

1.硬件准备
  • xr806模组
  • hcsr04超声波模块
  • hx711称重模块带支架托盘
  • 预装HarmonyOS手机一台
2、环境准备

参照文档: XR806快速上手指导文档

3、编译前准备

鸿蒙开发文档参考:qr23.cn/AKFP8k点击或者复制转到即可。

搜狗高速浏览器截图20240326151547.png

设备侧代码下载

下载方式:使用git 命令下载,指令如下(用户也可以根据需要将该仓库fork到自己的目录下后进行下载)

cd ~
git clone git@gitee.com:openharmony-sig/knowledge_demo_smart_home.git
代码拷贝
cp -rfa  ~/knowledge_demo_smart_home/dev/team_x  ~/openharmony/vendor/
cp -rfa  ~/knowledge_demo_smart_home/dev/third_party/iot_link  ~/openharmony/third_party/
SOC代码下载替换

当前官方soc代码由于DHCP暂未适配,所以暂时不支持AP模式,这时需要下载并替换之前SOC代码。如果官方soc代码已修复该问题,可忽略此步骤。

git clone https://gitee.com/moldy-potato-chips/xr806_-ap_mode.git
mv ~/openharmony/device/soc/allwinner ~/allwinner.org			// 不建议直接删除,
cp -raf xr806_-ap_mode ~/openharmony/device/soc/allwinner

整合并修改完成后的目录结构如下图

10

修改文件
  • 修改编译依赖

打开 device/soc/allwinner/xradio/xr806/BUILD.gn,添加应用依赖(deps字段):

module_group(module_name) {modules = ["src","project","include",]configs = [":SdkLdCconfig",]deps = [ "//vendor/team_x/smart_weight_scale/demo_smart_weight_scale:smart_weight_scale" ]
}
  • 修改编译方式

将demo依赖的库编译方式(static_library)修改为(source_set):

具体依赖查看demo_smart_weight_scale目录下的BUILD.gn:

    deps = ["../../common/iot_wifi_xradio:iot_wifi","../../common/iot_cloud:iot_cloud","//third_party/cJSON:cjson","../../common/iot_boardbutton_xradio:iot_boardbutton","../../common/iot_boardled_xradio:iot_boardled_xradio",]

其中//third_party/cJSON目录下的BUILD.gn建议参照下面的修改:

source_set("cJSON") {sources = ["cJSON.c","cJSON_Utils.c",]ldflags = [ "-lm" ]
}

third_party/iot_link目录下的各级使用到的BUILD.gn也需要将编译方式修改为source_set,或者将所有需要编译的文件放在iot_link目录的BUILD.gn中,如下:

source_set("iot_link") {sources = ["link_log/link_log.c","link_misc/link_random.c","link_misc/link_ring_buffer.c","link_misc/link_string.c","network/dtls/dtls_al/dtls_al.c","network/dtls/mbedtls/mbedtls_port/dtls_interface.c","network/dtls/mbedtls/mbedtls_port/mbed_port.c","network/dtls/mbedtls/mbedtls_port/timing_alt.c","network/mqtt/mqtt_al/mqtt_al.c","network/mqtt/paho_mqtt/port/paho_mqtt_port.c","network/mqtt/paho_mqtt/port/paho_osdepends.c","network/mqtt/paho_mqtt/paho/MQTTClient-C/src/MQTTClient.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTConnectClient.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTConnectServer.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTDeserializePublish.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTFormat.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTPacket.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTSerializePublish.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTSubscribeClient.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTSubscribeServer.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTUnsubscribeClient.c","network/mqtt/paho_mqtt/paho/MQTTPacket/src/MQTTUnsubscribeServer.c","oc_mqtt/oc_mqtt_al/oc_mqtt_al.c","oc_mqtt/oc_mqtt_profile_v5/oc_mqtt_profile.c","oc_mqtt/oc_mqtt_profile_v5/oc_mqtt_profile_package.c","oc_mqtt/oc_mqtt_profile_v5/oc_mqtt_event.c","oc_mqtt/oc_mqtt_tiny_v5/oc_mqtt_tiny.c","oc_mqtt/oc_mqtt_tiny_v5/hmac.c","queue/queue.c",]cflags = [ "-Wno-unused-variable" ]cflags += [ "-Wno-unused-but-set-variable" ]cflags += [  "-Wno-sign-compare" ]cflags += [  "-Wno-unused-parameter" ]cflags += [  "-Wno-unused-function" ]ldflags = [ "-Wl,-rpath-link=//device/xradio/xr806/xr_skylark/lib" ]ldflags += [ "-lmbedtls" ]include_dirs = ["inc","link_log","link_misc","queue","oc_mqtt/oc_mqtt_tiny_v5","oc_mqtt/oc_mqtt_profile_v5","oc_mqtt/oc_mqtt_al","network/dtls/mbedtls/mbedtls_port","network/mqtt/paho_mqtt/port","network/mqtt/paho_mqtt/paho/MQTTClient-C/src","network/mqtt/paho_mqtt/paho/MQTTPacket/src","//third_party/mbedtls/include/","//third_party/mbedtls/include/","//third_party/cJSON","//kernel/liteos_m/components/cmsis/2.0","//device/xradio/xr806/xr_skylark/include/net/mbedtls-2.2.0/",]defines = ["MQTTCLIENT_PLATFORM_HEADER=paho_osdepends.h","WITH_DTLS","MBEDTLS_AES_ROM_TABLES","MBEDTLS_CONFIG_FILE="los_mbedtls_config_dtls.h"","CONFIG_DTLS_MBEDTLS_CERT","CONFIG_DTLS_MBEDTLS_PSK","CFG_MBEDTLS_MODE=PSK_CERT","CONFIG_OC_MQTT_TINY_ENABLE=1"]
}
  • 修改iot_link中的部分文件
  1. third_party/iot_link/network/mqtt/paho_mqtt/port/paho_mqtt_port.c

    测试发现,当fd为0的时候,在执行recv时会立马返回-1,因此做下面规避操作。

    static int __socket_connect(Network *n, const char *host, int port)
    {...int tmpfd = socket(AF_INET,SOCK_STREAM,0); // to skip fd = 0;fd = socket(AF_INET,SOCK_STREAM,0);if(fd == -1) {return ret;}close(tmpfd);       // to skip fd = 0;...
    }

    系统setsockopt函数未适配,因此需要做下面的修改:

    static int __socket_read(void *ctx, unsigned char *buf, int len, int timeout)
    {int fd;int ret = 0;
    #if 0struct timeval timedelay = {timeout / 1000, (timeout % 1000) * 1000};if(NULL== uf){return ret;}fd = (int)(intptr_t)ctx;  ///< socket could be zeroif (timedelay.tv_sec < 0 || (timedelay.tv_sec == 0 && timedelay.tv_usec <= 0)){timedelay.tv_sec = 0;timedelay.tv_usec = 100;}if(0 != setsockopt(fd,SOL_SOCKET,SO_RCVTIMEO,&timedelay,sizeof(struct timeval))){return ret;  //could not support the rcv timeout}int bytes = 0;while (bytes < len) {int rc = recv(fd, &buf[bytes], (size_t)(len - bytes), 0);printf("[%s|%s|%d]fd = %d, rc = %d\n", __FILE__,__func__,__LINE__, fd, rc);if (rc == -1) {if (errno != EAGAIN && errno != EWOULDBLOCK) {bytes = -1;}break;} else if (rc == 0) {bytes = 0;break;} else {bytes += rc;}}return bytes;
    #elseint bytes = 0;fd_set fdset;struct timeval timedelay = {timeout / 1000, (timeout % 1000) * 1000};if(NULL== buf){return ret;}fd = (int)(intptr_t)ctx;  ///< socket could be zeroif (timedelay.tv_sec < 0 || (timedelay.tv_sec == 0 && timedelay.tv_usec <= 0)){timedelay.tv_sec = 0;timedelay.tv_usec = 100;}timedelay.tv_sec = 2;FD_ZERO(&fdset);FD_SET(fd, &fdset);ret = select(fd + 1, &fdset, NULL, NULL, &timedelay);if (ret > 0) {while (bytes < len) {int rc = recv(fd, &buf[bytes], (size_t)(len - bytes), 0);//         printf("[%s|%s|%d]fd = %d, rc = %d, errno=%d(%s)\n", __FILE__,__func__,__LINE__, fd, rc,errno, strerror(errno));if (rc == -1) {if (errno != EAGAIN && errno != EWOULDBLOCK) {bytes = -1;}break;} else if (rc == 0) {bytes = 0;break;} else {bytes += rc;}}}return bytes;
    #endif
    }

  2. third_party/iot_link/network/dtls/mbedtls/mbedtls_port/dtls_interface.c

    在文件顶部添加打印函数定义以及添加mbedtls_calloc以及mbedtls_free的定义,否则编译会提示错误:

    #define MBEDTLS_LOG LINK_LOG_DEBUG
    #ifndef mbedtls_calloc
    #define mbedtls_calloc  calloc
    #endif
    #ifndef mbedtls_free
    #define mbedtls_free  free
    #endif

    系统部分mbedtls接口不一致,固需要注释部分接口代码:

    mbedtls_ssl_context dtls_ssl_new(dtls_establish_info_s *info, char plat_type)
    {...if (info->psk_or_cert == VERIFY_WITH_PSK){
    /*if ((ret = mbedtls_ssl_conf_psk(conf,info->v.p.psk,info->v.p.psk_len,info->v.p.psk_identity,strlen((const char *)info->v.p.psk_identity))) != 0){MBEDTLS_LOG("mbedtls_ssl_conf_psk failed: -0x%x", -ret);goto exit_fail;}
    */}...
    }int dtls_shakehand(mbedtls_ssl_context *ssl, const dtls_shakehand_info_s *info)
    {...if (MBEDTLS_SSL_IS_CLIENT == info->client_or_server){ret = mbedtls_net_connect(server_fd, info->u.c.host, info->u.c.port, info->udp_or_tcp);if( 0 != ret){ret = MBEDTLS_ERR_NET_CONNECT_FAILED;goto exit_fail;}}else{//server_fd = (mbedtls_net_context*)atiny_net_bind(NULL, info->u.s.local_port, MBEDTLS_NET_PROTO_UDP);///< --TODO ,not implement yet}...
    }void dtls_init(void)
    {(void)mbedtls_platform_set_calloc_free(calloc, free);(void)mbedtls_platform_set_snprintf(snprintf);
    //    (void)mbedtls_platform_set_printf(printf);
    }

    在iot_link/network/dtls/mbedtls/mbedtls_port/mbed_port.c文件中的dtls_imp_init()函数中,也需要注释掉未实现的接口,否则编译报错:

    int dtls_imp_init(void)
    {int ret =-1;// (void)mbedtls_platform_set_calloc_free(calloc, free); // (void)mbedtls_platform_set_snprintf(snprintf);// (void)mbedtls_platform_set_printf(printf);ret = dtls_al_install(&s_mbedtls_io);return ret;
    }

  3. 在文件iot_link/network/mqtt/paho_mqtt/port/paho_osdepends.c中添加对应timersub和timeradd的实现(系统中未实现该函数):

    // add this for "timersub" && "timeradd"
    #ifndef	timersub
    #define timersub(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec - (t)->tv_sec, \((a)->tv_usec = (s)->tv_usec - (t)->tv_usec) < 0 && \((a)->tv_usec += 1000000, (a)->tv_sec--) )
    #endif
    #ifndef	timeradd
    #define timeradd(s,t,a) (void) ( (a)->tv_sec = (s)->tv_sec + (t)->tv_sec, \((a)->tv_usec = (s)->tv_usec + (t)->tv_usec) >= 1000000 && \((a)->tv_usec -= 1000000, (a)->tv_sec++) )
    #endif

  4. 编译中会有部分头文件提示找不到,这个时候直接将其注释即可(iot_link/network/mqtt/paho_mqtt/port/paho_osdepends.h):

    #define INVALID_SOCKET SOCKET_ERROR
    // #include <sys/socket.h>
    #include <sys/param.h>
    #include <sys/time.h>
    // #include <netinet/in.h>
    // #include <netinet/tcp.h>
    // #include <arpa/inet.h>
    // #include <netdb.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <fcntl.h>
    #include <string.h>
    #include <stdlib.h>
    #endif#if defined(WIN32)
    #include <Iphlpapi.h>
    #else
    // #include <sys/ioctl.h>
    // #include <net/if.h>
    #endif

  5. 因为弱引用导致无法链接相关符号,因此需要注释以下几个文件中的弱引用。

    文件一 third_party/iot_link/network/dtls/dtls_al/dtls_al.c
    #if 0
    __attribute__((weak))  int dtls_imp_init(void)
    {LINK_LOG_DEBUG("%s:###please implement dtls by yourself####",__FUNCTION__);return -1;
    }
    #endif
    extern int dtls_imp_init(void);文件二 third_party/iot_link/network/mqtt/mqtt_al/mqtt_al.c
    #if 0
    __attribute__((weak))  int mqtt_imp_init(void)
    {LINK_LOG_DEBUG("%s:###please implement mqtt by yourself####",__FUNCTION__);return -1;
    }
    #endif
    extern int mqtt_imp_init(void);文件三 third_party/iot_link/oc_mqtt/oc_mqtt_al/oc_mqtt_al.c
    #if 0
    __attribute__ ((weak)) int oc_mqtt_imp_init(void)
    {LINK_LOG_DEBUG("%s:###please implement oc mqtt by yourself####",__FUNCTION__);return 0;
    }__attribute__ ((weak)) int oc_mqtt_demo_main(void)
    {LINK_LOG_WARN("Please implement the oc mqtt v5 demo yourself");return -1;
    }
    #endif
    extern int oc_mqtt_demo_main(void);

  • 修改GPIO查找方式

因为GPIO框架修改了设备驱动注册的管脚号,导致应用无法根据HCS的引脚操作对应的GPIO,此问题已经提issue,如果该问题已解决,可以忽略此步骤。

打开drivers/framework/support/platform/src/gpio/gpio_manager.c,将cntlr->start = start;注释即可。

static int32_t GpioManagerAdd(struct PlatformManager *manager, struct PlatformDevice *device)
{uint16_t start;struct GpioCntlr *cntlr = CONTAINER_OF(device, struct GpioCntlr, device);if ((start = GpioCntlrQueryStart(cntlr, &manager->devices)) >= GPIO_NUM_MAX) {PLAT_LOGE("GpioCntlrAdd: query range for start:%d fail:%d", cntlr->start, start);return HDF_ERR_INVALID_PARAM;}//    cntlr->start = start;DListInsertTail(&device->node, &manager->devices);PLAT_LOGI("%s: start:%u count:%u", __func__, cntlr->start, cntlr->count);return HDF_SUCCESS;
}
  • 将对应的驱动文件复制到drvier对应目录:

    因为主仓代码中未将对应的驱动文件合并到driver/adpater/platform对应的目录下,固需要手动将文件拷贝到对应目录。若主仓已合入,可忽略此步骤。

    // 拷贝gpio驱动
    cp -af device/soc/allwinner/xradio/drivers/gpio/gpio_xradio.* driver/adpater/platform/gpio// 修改driver/adpater/platform/gpio/BUILD.gn文件,加上gpio_xradio的编译hdf_driver(module_name) {sources = []if (defined(LOSCFG_SOC_COMPANY_BESTECHNIC)) {sources += [ "gpio_bes.c" ]}if (defined(LOSCFG_SOC_COMPANY_ALLWINNER)) {sources += [ "gpio_xradio.c" ]}include_dirs = [ "." ]
    }

    为了节省ram资源,可以把无用的资源先关闭,如关闭内部codec,将 device/soc/allwinner/xradio/xr806/project/prj_config.h中的PRJCONF_INTERNAL_SOUNDCARD_EN设置为0,如下:

    /* Xradio internal codec sound card enable/disable */
    #define PRJCONF_INTERNAL_SOUNDCARD_EN   0

4、代码编译
#首先可以查看一下hb的版本,如果hb版本为0.4.4版本就不需要更新。```
## 查看hb版本
hb --version## 更新hb, 以下指令需要在openharmony SDK根目录执行
pip3 uninstall ohos_build
pip3 install build/lite
```编译命令:
hb set  // 如果是第一次编译,Input code path 命令行中键入"./" 指定OpenHarmony工程编译根目录后 回车,
如下图所示,使用键盘上下键选中wifi_skylark

2

 
hb build // 如果需要全量编译,可以添加-f 选项

生成的固件保存在out/xradio/smart_weight_scale目录下

5、固件烧录

参照文档:XR806快速上手指导文档

6、设备配网
  1. 在设备上电前需准备好安装了数字管家应用的HarmonyOS手机, 并在设置中开启手机的NFC功能;
  2. 写设备NFC标签;
  3. 烧录完成后,上电。开发者在观察开发板上状态LED灯以8Hz的频率闪烁时,将手机上半部靠近开发板NFC标签处(无NFC标签的可用NFC贴纸替代);
  4. 碰一碰后手机将自动拉起数字管家应用并进入配网状态;
  5. 配网过程中需要 连接设备的AP热点,然后填写需要配置的wifi的密码;
  6. 最后点击配置,手机会将ssid以及对应的密码通过AP热点发送到设备。

配网动图

鸿蒙Next核心技术分享

1、鸿蒙基础知识←《鸿蒙NEXT星河版开发学习文档》

2、鸿蒙ArkUI←《鸿蒙NEXT星河版开发学习文档》

3、鸿蒙进阶技术←《鸿蒙NEXT星河版开发学习文档》

 4、鸿蒙就业高级技能←《鸿蒙NEXT星河版开发学习文档》 

 5、鸿蒙多媒体技术←《鸿蒙NEXT星河版开发学习文档》 

6、鸿蒙南向驱动开发←《鸿蒙NEXT星河版开发学习文档》  

7、鸿蒙南向内核设备开发←《鸿蒙NEXT星河版开发学习文档》  

 8、鸿蒙系统裁剪与移植←《鸿蒙NEXT星河版开发学习文档》  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/818835.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

html公众号页面实现点击按钮跳转到导航

实现效果&#xff1a; 点击导航自动跳转到&#xff1a; html页面代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>跳转导航</title><meta name"keywords" conten…

华为框式交换机S12700E系列配置CSS集群

搭建集群环境 a.为两台交换机上电&#xff0c;按照数据规划分别对两台框式交换机进行配置 <HUAWEI> system-view [HUAWEI] sysname Switch1 [Switch1] set css id 1 [Switch1] set css priority 150 //框1的集群优先级配置为150 [Switch1] interface css-port 1 [Sw…

java的深入探究JVM之内存结构

前言 Java作为一种平台无关性的语言&#xff0c;其主要依靠于Java虚拟机——JVM&#xff0c;我们写好的代码会被编译成class文件&#xff0c;再由JVM进行加载、解析、执行&#xff0c;而JVM有统一的规范&#xff0c;所以我们不需要像C那样需要程序员自己关注平台&#xff0c;大…

最新AI创作系统ChatGPT网站源码AI绘画,GPTs,AI换脸支持,GPT联网提问、DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;那么如何搭建部署AI创作ChatGPT&#xff1f;小编这里写一个详细图文教程吧。已支持GPT…

【RabbitMQ】RabbitMQ基础认识

文章目录 前言初识MQSpringAMQP如何首发消息&#xff1f;消费者交换机Fanout&#xff1a;广播Direct交换机Topic交换机声明队列和交换机 总结 前言 微服务一旦拆分&#xff0c;必然涉及到服务之间的相互调用&#xff0c;目前我们服务之间调用采用的都是基于OpenFeign的调用。这…

JavaSE图书管理系统

JavaSE图书管理系统 思路一.Main方法二.User包1.User类2.NormaUser类3.AdminUser类三.book包1.BookList类2.Book类四.operation包1.IOPeration接口2.AddOperation类新增图书3.BorrowOperation类借阅图书4.DelOperation类删除图书5.FindOperation类查找图书6.ReturnOperation类归…

总结|性能优化思路及常用工具及手段

性能优化是降低成本的手段之一&#xff0c;每年大促前业务平台都会组织核心链路上的应用做性能优化&#xff0c;一方面提升系统性能&#xff0c;另外一方面对腐化的代码进行清理。现结合业务平台性能优化的经验&#xff0c;探讨一下性能优化的思路及常用工具及手段。性能优化本…

jenkins(docker)安装及应用

jenkins Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具&#xff0c;起源于Hudson&#xff08;Hudson是商用的&#xff09;&#xff0c;主要用于持续、自动的构建/测试软件项目、监控外部任务的运行&#xff08;这个比较抽象&#xff0c;暂且写上&#xff0c;不做解…

稀碎从零算法笔记Day50-LeetCode:寻找峰值

LC50天成就了 题型&#xff1a;数组、滑动窗口、二分 链接&#xff1a;162. 寻找峰值 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 峰值元素是指其值严格大于左右相邻值的元素。 给你一个整数数组 nums&#xff0c;找到峰值元素并返回其索…

STM32移植嵌入式开源按键框架

目录 STM32移植嵌入式开源按键框架 MultiButton简介 multi_button.c文件 multi_button.h文件 按键事件 案例使用方法 学习剖析 STM32移植嵌入式开源按键框架 今天移植了一款嵌入式按键框架工程MultiButton&#xff0c;MultiButton是一个小巧简单易用的事件驱动型按键驱动…

Qt 3 QVariant类的使用和实例

QVariant, 类本质为 C联合(Union)数据类型&#xff0c;它可以保存很多Qt 类型的值&#xff0c;包括 QBrush、QColor、QString 等等。也能够存放Qt的容器类型的值。QVariant::StringList 是 Qt定义的一个 QVariant::type 枚举类型的变量&#xff0c;其他常用的枚举类型变量如下表…

【Qt】:对话框(二)

对话框 一.消息对话框&#xff08;QMessageBox&#xff09;1.自己构建2.使用静态函数构建 二.颜色对话框&#xff08;QDialog&#xff09;三.文件对话框&#xff08;QFileDialog&#xff09;四.字体对话框&#xff08;QFontDialog&#xff09;五.输入对话框&#xff08;QInputD…

沐风老师3DMAX物品摆放插件ObjectPlacer安装和使用方法详解

3DMAX物品摆放插件ObjectPlacer安装和使用教程 3DMAX物品摆放插件ObjectPlacer&#xff0c;一键在曲面上摆放对象&#xff0c;如摆放家具物品、种植花草树木、布设电线杆交通标志等。它的功能是将对象与几何体对象&#xff08;网格、多边形、面片或NURBS&#xff09;的面法线对…

中电金信:夯实云原生时代的系统韧性建设——中电金信混沌工程金融业实践

IT系统建设在经历过单机、集中、分布式的演变历程后&#xff0c;系统运维演练、故障模拟测试的复杂度也不断提高。在复杂的分布式系统中&#xff0c;基础设施、应用平台都可能产生不可预知的故障&#xff0c;在不能确知故障根源的情况下&#xff0c;我们无法阻止故障的发生。更…

3D可视化技术:研发基地的科技新篇章

在科技日新月异的今天&#xff0c;我们生活在一个充满无限可能性的时代。而在这个时代中&#xff0c;3D可视化技术正以其独特的魅力&#xff0c;引领着科技领域的新一轮变革。 3D可视化技术通过三维图像的方式&#xff0c;将现实世界或虚拟世界中的物体、场景等以立体、逼真的形…

Mockito单元测试

文章目录 Mockito单元测试 为什么要使用Mock?导入依赖import导入包使用Mock模拟测试某个类中的某个方法是否可以成功执行使用Mock模拟某个类的方法&#xff0c;自己给这个方法返回我们指定的值使用Mock模拟某个方法调用后会抛出指定的异常使用Mock模拟测试某个类中的某个方法(…

04—常用方法和正则表达式

一、字符串 1.length 属性返回字符串的长度(字符数)。 2.在字符串中查找字符串 indexOf() 字符串使用 indexOf() 来定位字符串中某一个指定的字符首次出现的位置 如果没找到对应的字符函数返回-1 lastIndexOf() 方法在字符串末尾开始查找字符串出现的位置。 3.replace() 方…

网络字节序

什么是网络字节序 网络字节序是网络传输的过程中所采用的字节序,那么网络传输的过程中一般都采用什么字节序呢? 答案是大端字节序。 字节序分为大端和小端,他们代表多字节数值在内存中的存储方式。下面咱们讲解一下什么是大端,什么是小端? 大端字节序:数值的最高位字…

Linux安装docker(含Centos系统和Ubuntu系统)

一、Centos系统 1. 卸载旧版本依赖 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 2. 设置仓库 安装所需的软件包。yum-utils 提供了 yum-config-manager &…

实时传输,弹性优先——物联网通讯打造数据上传新标杆

随着信息技术的飞速发展&#xff0c;物联网技术已经成为连接物理世界和数字世界的桥梁。在物联网领域&#xff0c;数据上传的速度、稳定性和灵活性是评价通讯技术优劣的重要指标。近年来&#xff0c;物联网通讯在实时传输、弹性优先方面取得了显著进展&#xff0c;为数据上传树…