OpenHarmony无人机MAVSDK开源库适配方案分享

MAVSDK 是 PX4 开源团队贡献的基于 MavLink 通信协议的用于无人机应用开发的 SDK,支持多种语言如 C/C++、python、Java 等。通常用于无人机间、地面站与通信设备的消息传输。

MAVLink 是一种非常轻量级的消息传递协议,用于与无人机(以及机载无人机组件之间)进行通信。MAVLink 遵循现代混合发布-订阅和点对点设计模式,数据流作为主题发送/发布,而任务协议或参数协议等配置子协议是点对点的重传。其中 MAVLink 1 每个数据包只有 8 个字节的开销,包括开始标志和数据包丢弃检测。MAVLink 2 只有 14 字节的开销。由于 MAVLink 不需要任何额外的成帧,因此非常适合通信带宽非常有限的应用程序。

当我们想要在 OpenHarmony 上做无人机相关工作时,在通信方面需要面临 MAVLink 的移植适配工作。因此接下来我们将分享如何将 MAVSDK 移植至 OpenHarmony 系统当中。


MAVSDK Github 开源地址:GitHub - mavlink/MAVSDK: API and library for MAVLink compatible systems written in C++17

接下来讲解如何把 MAVSDK 开源库添加至 OpenHarmony 工程中进行编译。(此方法与其他开源库移植方法基本一致)

本次移植通过新建子系统 mavsdk,在子系统下添加名为 mavsdk 的组件,并在该组件下添加名为 MAVSDK 的模块,OpenHarmony 系统层级顺序如下:子系统-> 组件-> 模块,下文中将都以此为顺序进行叙述。

表 1:添加到工程后的目录结构

路径描述
ohos/build/subsystem_config.json子系统配置
ohos/productdefine/common/products/ohos-arm64.json板级相关
ohos/third_party/MAVSDK/bundle.json在子系统中添加组件配置
ohos/third_party/MAVSDK/BUILD.gn三方库模块化,将其加入组件中的 gn 文件

subsystem_config.json

首先在 ohos/build/subsystem 中添加 subsystem 节点。

"mavsdk": {   "path": "third_party/MAVSDK", "name": "mavsdk"}

ohos-arm64.json 文件

在 ohos/productdefine/common/products/ohos-arm64.json 文件中添加板级相关的信息。

"mavsdk:MAVSDK":{} 

如下图所示:

Bundle.json 文件

在 ohos/third 目录下添加 bundle.json 文件,以便系统可以添加名为 MAVSDK 的组件。

对于此文件要点如注释所见(编译时去除注释以保证配置文件整洁性)

{"name": "@ohos/MAVSDK","description": "","version": "","license": "","publishAs": "","segment": {"destPath": "third_party/MAVSDK"},"dirs": {},"scripts": {},"readmePath": {},"component": {"name": "MAVSDK","subsystem": "mavsdk","syscap": [],"features": [],"adapted_system_type": [],"rom": "","ram": "","deps": {"components": [ "jsoncpp","zlib"//此处添加了要用的三方库,后续的build.gn中还会有所体现。],"third_party": ["jsoncpp","zlib"]},"build": {"sub_component": [  "//third_party/mavsdk:MAVSDK","//third_party/mavsdk:mavsdk_test"],//此处添加了接下来要编译的组件,一个是代码主仓组件,一个是代码的测试文件组件"inner_kits": [],"test": ["//third_party/mavsdk:mavsdk_test"]}}}

BUILD.gn 文件

在完成上述步骤后,下面需要在 ohos/third 目录添加 BUILD.gn,根据不同的系统生成静态或者动态库,注意点如下:

文件作用
build.make生成目标的源文件
depend.make需要依赖的其他 C 源文件
flags.makecflags 相关的一些标志
link.txt链接库相关信息

① 注意移植时的 cflags、cflags 应从原始的编译文件(例如 cmake 过程中 build 的生成文件:在 cmake 生成 makefile 的过程中分析 build.make、depend.make、flags.make、link.txt 等得出三方库对应的依赖关系)中获取相关的标志位

② 注意移植的源文件及头文件地址可以使用当前 build.gn 所在路径下相对位置,例如/src 与 build.gn 在同一路径下则路径可以直接应用 src/....

③ 注意 deps 若引用的是组件内的其他模块,例如其他 build.gn 文件中的组件或当前 build.gn 中位于此 deps 前的其他组件可以使用 ”:module 进行模块依赖,若是引用组件外的其他组件则需要使用 ”bundle

import("//build/ohos.gni")  
import("//build/test.gni")config("mavsdk_cflag_config") {#编译时的标志位cflags = [  "-fexceptions","-Wextra","-Wshadow","-Wno-strict-aliasing","-Wformat=2","-Wextra","-Wno-unused-lambda-capture","-Wno-pragmas","-Wno-unknown-warning-option","-Wduplicated-cond","-Wnull-dereference","-Wduplicated-branches","-Wlogical-op", "-Wno-old-style-cast","-pthread",]cflags_cc = [ "-frtti" ] #fix:[OHOS ERROR] ../../prebuilts/clang/ohos/linux-x86_64/llvm/bin/../include/libcxx-ohos/include/c++/v1/memory:3566:16: error: use of dynamic_cast requires -frttildflags = [ "-fPIC","-g","-shared","-Wl","-soname" ]
}ohos_source_set("libmavsdk_source") {configs = [":mavsdk_cflag_config"]deps = [ "//third_party/curl:curl"  ] #需要包含的源文件sources = ["src/mavsdk/core/call_every_handler.cpp" ,"src/mavsdk/core/connection.cpp" ,"src/mavsdk/core/connection_result.cpp" ,"src/mavsdk/core/curl_wrapper.cpp" ,"src/mavsdk/core/crc32.cpp" ,"src/mavsdk/core/system.cpp" ,"src/mavsdk/core/system_impl.cpp" ,"src/mavsdk/core/fs.cpp" ,"src/mavsdk/core/mavsdk.cpp" ,"src/mavsdk/core/mavsdk_impl.cpp" ,"src/mavsdk/core/http_loader.cpp" ,"src/mavsdk/core/mavlink_channels.cpp" ,"src/mavsdk/core/mavlink_command_receiver.cpp" ,"src/mavsdk/core/mavlink_command_sender.cpp" ,"src/mavsdk/core/mavlink_ftp.cpp" ,"src/mavsdk/core/mavlink_mission_transfer.cpp" ,"src/mavsdk/core/mavlink_parameters.cpp" ,"src/mavsdk/core/mavlink_receiver.cpp" ,"src/mavsdk/core/mavlink_request_message_handler.cpp" ,"src/mavsdk/core/mavlink_statustext_handler.cpp" ,"src/mavsdk/core/mavlink_message_handler.cpp" ,"src/mavsdk/core/ping.cpp" ,"src/mavsdk/core/plugin_impl_base.cpp" ,"src/mavsdk/core/serial_connection.cpp" ,"src/mavsdk/core/tcp_connection.cpp" ,"src/mavsdk/core/timeout_handler.cpp" ,"src/mavsdk/core/udp_connection.cpp" ,"src/mavsdk/core/log.cpp" ,"src/mavsdk/core/cli_arg.cpp" ,"src/mavsdk/core/geometry.cpp" ,"src/mavsdk/core/request_message.cpp" ,"src/mavsdk/core/mavsdk_time.cpp" ,"src/mavsdk/core/timesync.cpp" ,"src/mavsdk/plugins/action/action.cpp" ,"src/mavsdk/plugins/action/action_impl.cpp" ,"src/mavsdk/plugins/action_server/action_server.cpp" ,"src/mavsdk/plugins/action_server/action_server_impl.cpp" ,"src/mavsdk/plugins/calibration/calibration.cpp" ,"src/mavsdk/plugins/calibration/calibration_impl.cpp" ,"src/mavsdk/plugins/calibration/calibration_statustext_parser.cpp" ,"src/mavsdk/plugins/camera/camera.cpp" ,"src/mavsdk/plugins/camera/camera_impl.cpp" ,"src/mavsdk/plugins/camera/camera_definition.cpp" ,"src/mavsdk/plugins/camera/camera_definition_files/generated/camera_definition_files.cpp" ,"src/mavsdk/plugins/component_information/component_information.cpp" ,"src/mavsdk/plugins/component_information/component_information_impl.cpp" ,"src/mavsdk/plugins/component_information_server/component_information_server.cpp" ,"src/mavsdk/plugins/component_information_server/component_information_server_impl.cpp" ,"src/mavsdk/plugins/failure/failure.cpp" ,"src/mavsdk/plugins/failure/failure_impl.cpp" ,"src/mavsdk/plugins/follow_me/follow_me.cpp" ,"src/mavsdk/plugins/follow_me/follow_me_impl.cpp" ,"src/mavsdk/plugins/ftp/ftp.cpp" ,"src/mavsdk/plugins/ftp/ftp_impl.cpp" ,"src/mavsdk/plugins/geofence/geofence.cpp" ,"src/mavsdk/plugins/geofence/geofence_impl.cpp" ,"src/mavsdk/plugins/gimbal/gimbal.cpp" ,"src/mavsdk/plugins/gimbal/gimbal_impl.cpp" ,"src/mavsdk/plugins/gimbal/gimbal_protocol_v1.cpp" ,"src/mavsdk/plugins/gimbal/gimbal_protocol_v2.cpp" ,"src/mavsdk/plugins/info/info.cpp" ,"src/mavsdk/plugins/info/info_impl.cpp" ,"src/mavsdk/plugins/log_files/log_files.cpp" ,"src/mavsdk/plugins/log_files/log_files_impl.cpp" ,"src/mavsdk/plugins/manual_control/manual_control.cpp" ,"src/mavsdk/plugins/manual_control/manual_control_impl.cpp" ,"src/mavsdk/plugins/mavlink_passthrough/mavlink_passthrough.cpp" ,"src/mavsdk/plugins/mavlink_passthrough/mavlink_passthrough_impl.cpp" ,"src/mavsdk/plugins/mission/mission.cpp" ,"src/mavsdk/plugins/mission/mission_impl.cpp" ,"src/mavsdk/plugins/mission_raw/mission_raw.cpp" ,"src/mavsdk/plugins/mission_raw/mission_raw_impl.cpp" ,"src/mavsdk/plugins/mission_raw/mission_import.cpp" ,"src/mavsdk/plugins/mission_raw_server/mission_raw_server.cpp" ,"src/mavsdk/plugins/mission_raw_server/mission_raw_server_impl.cpp" ,"src/mavsdk/plugins/mocap/mocap.cpp" ,"src/mavsdk/plugins/mocap/mocap_impl.cpp" ,"src/mavsdk/plugins/offboard/offboard.cpp" ,"src/mavsdk/plugins/offboard/offboard_impl.cpp" ,"src/mavsdk/plugins/param/param.cpp" ,"src/mavsdk/plugins/param/param_impl.cpp" ,"src/mavsdk/plugins/param_server/param_server.cpp" ,"src/mavsdk/plugins/param_server/param_server_impl.cpp" ,"src/mavsdk/plugins/server_utility/server_utility.cpp" ,"src/mavsdk/plugins/server_utility/server_utility_impl.cpp" ,"src/mavsdk/plugins/shell/shell.cpp" ,"src/mavsdk/plugins/shell/shell_impl.cpp" ,"src/mavsdk/plugins/telemetry/telemetry.cpp" ,"src/mavsdk/plugins/telemetry/telemetry_impl.cpp" ,"src/mavsdk/plugins/telemetry/math_conversions.cpp" ,"src/mavsdk/plugins/telemetry_server/telemetry_server.cpp" ,"src/mavsdk/plugins/telemetry_server/telemetry_server_impl.cpp" ,"src/mavsdk/plugins/tracking_server/tracking_server.cpp" ,"src/mavsdk/plugins/tracking_server/tracking_server_impl.cpp" ,"src/mavsdk/plugins/transponder/transponder.cpp" ,"src/mavsdk/plugins/transponder/transponder_impl.cpp" ,"src/mavsdk/plugins/rtk/rtk.cpp" ,"src/mavsdk/plugins/rtk/rtk_impl.cpp" ,"src/mavsdk/plugins/tune/tune.cpp" ,"src/mavsdk/plugins/tune/tune_impl.cpp"]#需要包含的头文件include_dirs = ["src/mavsdk/core","src/mavsdk/core/include/mavsdk","src/mavsdk/plugins/action/include","src/mavsdk/plugins/action_server/include","src/mavsdk/plugins/calibration/include","src/mavsdk/plugins/camera/include","src/mavsdk/plugins/camera/camera_definition_files/generated","src/mavsdk/plugins/component_information/include","src/mavsdk/plugins/component_information_server/include","src/mavsdk/plugins/failure/include","src/mavsdk/plugins/follow_me/include","src/mavsdk/plugins/ftp/include","src/mavsdk/plugins/geofence/include","src/mavsdk/plugins/gimbal/include","src/mavsdk/plugins/info/include","src/mavsdk/plugins/log_files/include","src/mavsdk/plugins/manual_control/include","src/mavsdk/plugins/mavlink_passthrough/include","src/mavsdk/plugins/mission/include","src/mavsdk/plugins/mission_raw/include","src/mavsdk/plugins/mission_raw_server/include","src/mavsdk/plugins/mocap/include","src/mavsdk/plugins/offboard/include","src/mavsdk/plugins/param/include","src/mavsdk/plugins/param_server/include","src/mavsdk/plugins/rtk/include","src/mavsdk/plugins/server_utility/include","src/mavsdk/plugins/shell/include","src/mavsdk/plugins/telemetry/include","src/mavsdk/plugins/telemetry_server/include","src/mavsdk/plugins/tracking_server/include","src/mavsdk/plugins/transponder/include","src/mavsdk/plugins/tune/include","src/mavsdk/plugins/action","src/mavsdk/plugins/action_server","src/mavsdk/plugins/calibration","src/mavsdk/plugins/camera","src/mavsdk/plugins/component_information","src/mavsdk/plugins/component_information_server","src/mavsdk/plugins/failure","src/mavsdk/plugins/follow_me","src/mavsdk/plugins/ftp","src/mavsdk/plugins/geofence","src/mavsdk/plugins/gimbal","src/mavsdk/plugins/info","src/mavsdk/plugins/log_files","src/mavsdk/plugins/manual_control","src/mavsdk/plugins/mavlink_passthrough","src/mavsdk/plugins/mission","src/mavsdk/plugins/mission_raw","src/mavsdk/plugins/mission_raw_server","src/mavsdk/plugins/mocap","src/mavsdk/plugins/offboard","src/mavsdk/plugins/param","src/mavsdk/plugins/param_server","src/mavsdk/plugins/rtk","src/mavsdk/plugins/server_utility","src/mavsdk/plugins/shell","src/mavsdk/plugins/telemetry","src/mavsdk/plugins/telemetry_server","src/mavsdk/plugins/tracking_server","src/mavsdk/plugins/transponder","src/mavsdk/plugins/tune","src/third_party/mavlink","src/third_party/mavlink/mavlink/src/mavlink/include/mavlink/v2.0","src/third_party/mavlink/mavlink/src/mavlink/include/mavlink/v2.0/common","//third_party/jsoncpp/include","//third_party/curl/include","//third_party/tinyxml2","//third_party/zlib",]
}ohos_shared_library("MAVSDK") {deps = [    ":libmavsdk_source","//third_party/curl:curl_shared","//third_party/openssl:libssl_shared","//third_party/openssl:libcrypto_shared","//third_party/jsoncpp:jsoncpp","//third_party/tinyxml2:tinyxml2"]         #依赖的三方库part_name = "MAVSDK"subsystem_name = "mavsdk"output_name = "libmavsdk"}ohos_executable("takeoff_and_land") {use_exceptions = trueoutput_name = "takeoff_and_land" # 可选,模块输出名include_dirs = ["src/third_party/mavlink/mavlink/src/mavlink/include","src/mavsdk/core/include/mavsdk","src/mavsdk/plugins/action/include","src/mavsdk/plugins/telemetry/include"]sources = ["examples/takeoff_and_land/takeoff_and_land.cpp","examples/takeoff_and_land/autopilot_interface.cpp",]deps = ["//third_party/MAVSDK:MAVSDK"]part_name = "MAVSDK"subsystem_name = "MAVSDK"}
#演示编译部分
ohos_executable("offboard") {  use_exceptions = trueoutput_name = "offboard" # 可选,模块输出名include_dirs = ["src/third_party/mavlink/mavlink/src/mavlink/include","src/mavsdk/core/include/mavsdk","src/mavsdk/plugins/offboard/include","src/mavsdk/plugins/action/include","src/mavsdk/plugins/telemetry/include"]sources = ["examples/offboard/offboard.cpp",]deps= ["//third_party/MAVSDK:MAVSDK"]part_name = "MAVSDK"subsystem_name = "MAVSDK"}#编译测试文件
ohos_unittest("mavsdk_test") {module_out_path = "MAVSDK/mavsdk_test" testonly = trueuse_exceptions = trueinclude_dirs = [ "src/mavsdk/core/include/mavsdk","src/mavsdk/plugins/action/include","src/mavsdk/plugins/action_server/include","src/mavsdk/plugins/calibration/include","src/mavsdk/plugins/camera/include","src/mavsdk/plugins/camera/camera_definition_files/generated","src/mavsdk/plugins/component_information/include","src/mavsdk/plugins/component_information_server/include","src/mavsdk/plugins/failure/include","src/mavsdk/plugins/follow_me/include","src/mavsdk/plugins/ftp/include","src/mavsdk/plugins/geofence/include","src/mavsdk/plugins/gimbal/include","src/mavsdk/plugins/info/include","src/mavsdk/plugins/log_files/include","src/mavsdk/plugins/manual_control/include","src/mavsdk/plugins/mavlink_passthrough/include","src/mavsdk/plugins/mission/include","src/mavsdk/plugins/mission_raw/include","src/mavsdk/plugins/mission_raw_server/include","src/mavsdk/plugins/mocap/include","src/mavsdk/plugins/offboard/include","src/mavsdk/plugins/param/include","src/mavsdk/plugins/param_server/include","src/mavsdk/plugins/rtk/include","src/mavsdk/plugins/server_utility/include","src/mavsdk/plugins/shell/include","src/mavsdk/plugins/telemetry/include","src/mavsdk/plugins/telemetry_server/include","src/mavsdk/plugins/tracking_server/include","src/mavsdk/plugins/transponder/include","src/mavsdk/plugins/tune/include","src/mavsdk/core","src/mavsdk/plugins/action","src/mavsdk/plugins/action_server","src/mavsdk/plugins/calibration","src/mavsdk/plugins/camera","src/mavsdk/plugins/component_information","src/mavsdk/plugins/component_information_server","src/mavsdk/plugins/failure","src/mavsdk/plugins/follow_me","src/mavsdk/plugins/ftp","src/mavsdk/plugins/geofence","src/mavsdk/plugins/gimbal","src/mavsdk/plugins/info","src/mavsdk/plugins/log_files","src/mavsdk/plugins/manual_control","src/mavsdk/plugins/mavlink_passthrough","src/mavsdk/plugins/mission","src/mavsdk/plugins/mission_raw","src/mavsdk/plugins/mission_raw_server","src/mavsdk/plugins/mocap","src/mavsdk/plugins/offboard","src/mavsdk/plugins/param","src/mavsdk/plugins/param_server","src/mavsdk/plugins/rtk","src/mavsdk/plugins/server_utility","src/mavsdk/plugins/shell","src/mavsdk/plugins/telemetry","src/mavsdk/plugins/telemetry_server","src/mavsdk/plugins/tracking_server","src/mavsdk/plugins/transponder","src/mavsdk/plugins/tune","src/third_party/mavlink","src/third_party/curl/curl/src/curl/include","src/third_party/install/include","src/third_party/mavlink/mavlink/src/mavlink/include/mavlink/v2.0","src/third_party/mavlink/mavlink/src/mavlink/include/mavlink/v2.0/common",]sources = ["src/mavsdk/core/mavsdk_time_test.cpp" ,"src/mavsdk/core/mavsdk_math_test.cpp" ,"src/mavsdk/core/mavlink_channels_test.cpp" ,"src/mavsdk/core/unittests_main.cpp" ,"src/mavsdk/core/timeout_handler_test.cpp" ,"src/mavsdk/core/call_every_handler_test.cpp" ,"src/mavsdk/core/curl_test.cpp" ,"src/mavsdk/core/cli_arg_test.cpp" ,"src/mavsdk/core/locked_queue_test.cpp" ,"src/mavsdk/core/safe_queue_test.cpp" ,"src/mavsdk/core/mavsdk_test.cpp" ,"src/mavsdk/core/mavlink_mission_transfer_test.cpp" ,"src/mavsdk/core/mavlink_statustext_handler_test.cpp" ,"src/mavsdk/core/geometry_test.cpp" ,"src/mavsdk/core/ringbuffer_test.cpp" ,"src/mavsdk/plugins/calibration/calibration_statustext_parser_test.cpp" ,"src/mavsdk/plugins/camera/camera_definition_test.cpp" ,"src/mavsdk/plugins/mission_raw/mission_import_test.cpp" ,"src/mavsdk/plugins/telemetry/math_conversions_test.cpp"]deps = ["//third_party/MAVSDK:MAVSDK","//third_party/googletest:gmock_main","//third_party/googletest:gtest_main"]part_name = "MAVSDK"
}

通过以上操作以后,就可以在 OpenHarmony 编译源码了:

./build.sh --product-name rpi4 --build-target=MAVSDK --ccache

编译完成以后可以在 out/rpi4/mavsdk/MAVSDK 目录下看到编译生成的 libmavsdk.z.so 文件。

同时,还可以在 ohos/out/rpi4/tests/unittest/MAVSDK/mavsdk_test/mavsdk_test 目录下看到我们编译的测试文件,如下所示:

接下来把编译完成的 so 及测试文件到 RPI4 开发板中,运行测试文件验证整个库的移植情况。

最后

有很多小伙伴不知道学习哪些鸿蒙开发技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?而且学习时频繁踩坑,最终浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有必要的。 

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。

希望这一份鸿蒙学习资料能够给大家带来帮助,有需要的小伙伴自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线

  •  HarmonOS基础技能

  • HarmonOS就业必备技能 
  •  HarmonOS多媒体技术

  • 鸿蒙NaPi组件进阶

  • HarmonOS高级技能

  • 初识HarmonOS内核 
  • 实战就业级设备开发

有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)鸿蒙(OpenHarmony )开发入门教学视频,内容包含:ArkTS、ArkUI、Web开发、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开发入门教学视频》

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

OpenHarmony北向、南向开发环境搭建

图片

 《鸿蒙开发基础》

  • ArkTS语言
  • 安装DevEco Studio
  • 运用你的第一个ArkTS应用
  • ArkUI声明式UI开发
  • .……

图片

 《鸿蒙开发进阶》

  • Stage模型入门
  • 网络管理
  • 数据管理
  • 电话服务
  • 分布式应用开发
  • 通知与窗口管理
  • 多媒体技术
  • 安全技能
  • 任务管理
  • WebGL
  • 国际化开发
  • 应用测试
  • DFX面向未来设计
  • 鸿蒙系统移植和裁剪定制
  • ……

图片

《鸿蒙进阶实战》

  • ArkTS实践
  • UIAbility应用
  • 网络案例
  • ……

图片

 获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料

总结

总的来说,华为鸿蒙不再兼容安卓,对中年程序员来说是一个挑战,也是一个机会。只有积极应对变化,不断学习和提升自己,他们才能在这个变革的时代中立于不败之地。 

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

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

相关文章

目标检测评价标准

主要借鉴:https://github.com/rafaelpadilla/Object-Detection-Metrics?tabreadme-ov-file 主要评价指标、术语: Intersection Over Union (IOU):两个检测框交集面积与并集面积的比值 True Positive (TP):IOU大于阈值的检测框…

计算机网络——30SDN控制平面

SDN控制平面 SDN架构 数据平面交换机 快速、简单,商业化交换设备采用硬件实现通用转发功能流表被控制器计算和安装基于南向API,SDN控制器访问基于流的交换机 定义了哪些可以被控制哪些不能 也定义了和控制器的协议 SDN控制器(网络OS&#…

计算机基础系列 —— 虚拟机代码翻译器(1)

“Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.” ―Linus Torvalds 文中提到的所有实现都可以参考:nand2tetris_sol,但是最好还是自己学习课程实现一…

Spring Cloud GateWay——网关的基本使用

1. 为什么所有的请求先到网关呢? 有了网关就可以对请求进行路由,路由到具体的微服务,减少外界对接微服务的成本,比如:400电话,路由的试可以根据请求路径进行路由、根据host地址进行路由等, 当微…

ios应用内支付

用uniapp开发iOS应用内支付 准备前端代码服务器端处理如果iOS支付遇到问题实在解决不了,可以联系我帮忙解决,前端后端都可以解决(添加的时候一定要备注咨询iOS支付问题) 准备前端代码 获取支付通道 (uni.getProvider) uni.getPr…

上岸美团了!

Hello,大家好,最近春招正在如火如荼,给大家分享一份美团的面经,作者是一份某双非的硕(只如初见668),刚刚通过了美团的3轮面试,已经拿到offer,以下是他的一些分享。 一面&…

module ‘numpy‘ has no attribute ‘int‘

在 NumPy 中,如果遇到了错误提示 "module numpy has no attribute int",这通常意味着正在尝试以错误的方式使用 NumPy 的整数类型。从 NumPy 1.20 版本开始,numpy.int 已经不再是一个有效的属性,因为 NumPy 不再推荐使用…

mongodb sharding分片模式的集群数据库,日志治理缺失导致写入数据库报错MongoWriteConcernException的问题总结(上)

一、背景 常见的mongodb集群模式有以下三种: 主从复制(Master-Slave)模式副本集(Replica Set)模式分片(Sharding)模式 公司测试环境搭建的集群采用分片模式,有同事反馈说&#xf…

数据结构——链表(双向链表)

大家好,我是小峰,今天给大家讲解的是双向链表,我们先来看看链表的结构。 链表分类 这里带头是哨兵位的头节点 3. 循环与非循环 我们排列一些就可以看出链表的结构种类 这些链表的操作大都差不多 我们今天讲解的是双向带头循环链表 带头双向…

BGP实训

BGP基础配置实训 实验拓扑 注:如无特别说明,描述中的 R1 或 SW1 对应拓扑中设备名称末尾数字为 1 的设备,R2 或 SW2 对应拓扑中设备名称末尾数字为2的设备,以此类推;另外,同一网段中,IP 地址的主…

【数据挖掘】实验5:数据预处理(2)

验5:数据预处理(2) 一:实验目的与要求 1:熟悉和掌握数据预处理,学习数据清洗、数据集成、数据变换、数据规约、R语言中主要数据预处理函数。 二:实验知识点总结 1:数据集成是将多个…

boost::asio::ip::tcp/udp::socket::release 函数为什么限制 Windows 8.1 才可以调用?

如本文题目所示,这是因为只有在 Windows 8.1(Windows Server 2012 RC)及以上 Windows 操作版本才提供了运行时,修改/删除完成端口关联的ABI接口。 boost::asio 在 release 函数底层实现之中是调用了 FileReplaceCompletionInform…