当前位置: 首页 > news >正文

(三) 搞定SOME/IP通信之CommonAPI库

本章主要介绍在SOME/IP通信过程中的另外一个IPC通信利剑,CommonAPI库,文章将从如下几个角度让读者了解什么是CommonAPI, 以及库在实际工作中的作用

文中资源:vsomeip+commonapi+指导文档与demo源码

SOME/IP通信之CommonAPI

  • CommonAPI库是什么
  • CommonAPI库的编译
  • 写个Demo实战一下

CommonAPI库是什么

CommonAPI是GENIVI组织开发的一个基于C++的应用API库,没错,跟vsomeip协议栈是一个爹。其主要提供给使用通讯中间件传输数据的分布式应用来操作通讯中间件的接口。主要的作用是使使用CommonAPI进行IPC通信的的应用能够隔离底层协议栈的差异。比如使用CommonAPI时,我们的底层协议栈可以是vsomeip,也可以是DBUS等. 他的架构如下:
在这里插入图片描述
从图中可以看到,CommonAPI C++ 框架分为两个主要部分:

CommonAPI Core: 这部分与中间件无关,包含了跨不同中间件技术共享的基本 API、类和组件。它提供了构建应用程序所需的基本通信机制和抽象,而不与特定的中间件协议绑定。

CommonAPI Binding: 这部分与特定中间件相关,并包含了每种支持的中间件协议的实现细节。

通过将Core与Binding分开,CommonAPI C++ 允许开发人员使用与中间件无关的核心编写他们的应用程序逻辑,使其代码更具可移植性,不会紧密绑定到特定的中间件。然后,他们可以选择特定的绑定,将他们的应用程序适配到所需的中间件技术,而无需重写整个应用程序逻辑。

这种关注点分离使得开发更容易,可以在具有不同中间件要求的各种汽车系统中部署应用程序。它通过在中间件无关逻辑和特定中间件实现细节之间提供明确的分离,促进了可重用性和模块化。

图右边的四个框架,分别代表了Core层的代码生成工具,以及接口描述语言(fidl), Binding层的代码生成工具,以及接口描述语言(fdepl),即:

Code Generator Tools  <-->   *.fidl
Code Generator Binding Tools <--> *.fdepl

关于fidl跟fdepl文件是什么,如果你做过android开发,那么对aidl文件以及hidl文件会比较熟悉,这个fidl跟fdepl文件也是跟aidl&hidl的作用类似,我们将通信行为的接口以及参数定义在文件中,通过CommonAPI提供的Code Generators,即可将这些文件转成对应的C++接口。上层在在进行IPC接口时,只需要调用这些C++中的接口即可

CommonAPI库的编译

因为我们是基于android系统来使用CommonAPI通信,故使用ndk+gradle来编译库

编译环境

操作系统:win11
Gradle: 7.3.3
cmake版本:3.18.1

下载源码
这里包含两部分,一个是CommonAPI Core,一个是CommonAPI Binding分别对应如下两个库:

capicxx-core-runtime
capicxx-someip-runtime

下载完成后,将文件夹拷贝到上一篇文章提供的附件工程中的external目录下面,放好后如下所示:
在这里插入图片描述

修改CMakeList
然后我们需要修改工程根目录下的CMakeLists.txt文件, 注意是工程根目录,不是模块根目录,修改后内容如下所示:

cmake_minimum_required(VERSION 3.10)project(SOMEIP)list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output/${ANDROID_ABI})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/output/${ANDROID_ABI})
set(FETCHCONTENT_SOURCE_DIR_BOOST ${CMAKE_CURRENT_SOURCE_DIR}/external/boost_1_71_0)
add_subdirectory(external/boost-cmake)
add_subdirectory(external/vsomeip)
add_subdirectory(external/capicxx-core-runtime-master)
add_subdirectory(external/capicxx-someip-runtime-master)
add_subdirectory(app/src/main/cpp)

external/capicxx-core-runtime-master/CMakeLists.txt

#添加编译标记,不然会编译报错(-Wno-ignored-attributes -Wno-deprecated-declarations)
IF(MSVC)message("using MSVC Compiler")add_definitions(-DCOMMONAPI_INTERNAL_COMPILATION -DCOMMONAPI_DLL_COMPILATION)add_compile_options(/EHsc /wd4996)
ELSE ()set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wformat -Wformat-security -Wconversion -fexceptions -fstrict-aliasing -fstack-protector -fasynchronous-unwind-tables -fno-omit-frame-pointer -Werror -DCOMMONAPI_INTERNAL_COMPILATION -fvisibility=hidden -Wno-ignored-attributes -Wno-deprecated-declarations")
ENDIF(MSVC)

external/capicxx-core-runtime-master/CMakeLists.txt

if ("${USE_INSTALLED_COMMONAPI}" STREQUAL "ON")FIND_PACKAGE(CommonAPI 3.2.0 REQUIRED CONFIG NO_CMAKE_PACKAGE_REGISTRY)
else()
# 注释掉REQUIRED
#    FIND_PACKAGE(CommonAPI 3.2.0 REQUIRED CONFIG NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)FIND_PACKAGE(CommonAPI 3.2.0)
endif()# maintainer-clean target去掉
if(NOT ANDROID)
add_custom_target(maintainer-clean COMMAND rm -rf *)
endif()

在根目录的cmake文件夹下再按照cmake的find_package规则添加两个文件,FindCommonAPI.cmake, 跟FindCommonAPI-SomeIP.cmake 两个文件

然后启动编译,就可以在工程根目录的output目录下看到库基本已经全部输出了
在这里插入图片描述

写个Demo实战一下

上面库编译完成了,书接上回的vsomeip demo,我们需要将someip_server跟someip_client这两个库改造以下,不直接使用vsomeip协议栈的API, 改为CommonAPI的方式来实现。

在写代码之前,咱们来回顾一下之前使用vsomeip协议栈API写的例子,我们定义了一个天气服务,然后服务中提供了一个获取温度的方法,参数如下:

//服务ID
static vsomeip::service_t  weather_service_id = 0x1001;
//服务实例ID
static vsomeip::instance_t weather_service_instance_id = 0x0001;
//方法ID
static vsomeip::method_t   weather_get_temp_method_id = 0x0001;

这里我们把它改造成CommonAPI的方式,首先在cpp目录下创建如下两个文件,并填入内容:

IWeatherService.fidl

package com.commapi.testinterface IWeatherService {version { major 0 minor 1 }method getTemp {out {Int32 temp}}
}

IWeatherService.fdepl

import "platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-4-SOMEIP_deployment_spec.fdepl"
import "IWeatherService.fidl"define org.genivi.commonapi.someip.deployment for interface com.commapi.test.IWeatherService {SomeIpServiceID = 4097 //0x1001method getTemp {SomeIpMethodID = 1 //0x0001SomeIpReliable = true}
}define org.genivi.commonapi.someip.deployment for provider as Service {instance com.commapi.test.IWeatherService {InstanceId = "com.commapi.test.IWeatherService"SomeIpInstanceID = 1 //0x0001}
}

我们这里只展示使用方式,fidl&fdepl的语法,我们后面会专门起文章来介绍。

写好后,需要下载如下两个工具:
commonapi_core_generator-3.2.0
commonapi_someip_generator-3.2.0.1

下载完成后,解压到执行的目录, 然后启动cmd窗口,跳转到我们的fidl & fdepl文件所在目录,然后输入如下命令,即可:

commonapi-core-generator-windows-x86_64.exe -sk  *.fidl
commonapi-someip-generator-windows-x86_64.exe  *.fdepl

在这里插入图片描述
这里我们会发现我们的fidl文件夹下多了自动生成了一个src-gen的文件夹,内容如下:
在这里插入图片描述
接下来改造server端跟client端,第一步先把cpp跟.h文件加入到编译源文件中, 修改cpp目录下的CMakeLists.txt如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html# Sets the minimum version of CMake required to build the native library.cmake_minimum_required(VERSION 3.18.1)# Declares and names the project.
project("someip")find_package (vsomeip3 3.3.8 REQUIRED)
find_library(log-lib log)
include_directories(${VSOMEIP3_INCLUDE_DIRS})# CommonAPI
find_package(CommonAPI 3.2.0 REQUIRED)
include_directories(${COMMONAPI_INCLUDE_DIRS})# CommonAPI-SomeIP
find_package(CommonAPI-SomeIP 3.2.0 REQUIRED)
include_directories(${CommonAPI-SomeIP_INCLUDE_DIRS})# SRC-GEN
include_directories(fidl/src-gen)
file(GLOB SRC-GEN fidl/src-gen/v0/com/commapi/test/*.cpp)add_executable(someip_server# Provides a relative path to your source file(s).someip_server.cpp${SRC-GEN})target_link_libraries(someip_server ${log-lib} vsomeip3 vsomeip3-e2e vsomeip3-sd CommonAPI CommonAPI-SomeIP)add_executable(someip_client# Provides a relative path to your source file(s).someip_client.cpp${SRC-GEN})target_link_libraries(someip_client ${log-lib} vsomeip3 vsomeip3-e2e vsomeip3-sd CommonAPI CommonAPI-SomeIP)

编译文件修改完成后,再将我们之前的vsomeip的两个端代码修改为CommonAPI方式,对应两个文件如下:

服务端实现:someip_server.cpp

#include <string>
#include <csignal>
#include <unistd.h>
#include "CommonAPI/CommonAPI.hpp"
#include "v0/com/commapi/test/IWeatherServiceStubDefault.hpp"using namespace v0::com::commapi::test;class WeatherServiceStub : public IWeatherServiceStubDefault {
private:int temp = -32;
public:WeatherServiceStub() = default;~WeatherServiceStub() override = default;void getTemp(const std::shared_ptr<CommonAPI::ClientId> _client, getTempReply_t _reply) override{printf("%s : gid[%d], uid[%d]\n", __func__ , _client->getGid(), _client->getUid());_reply(temp++);}
};int main(int args, char** argc){//设置配置文件路径setenv("COMMONAPI_CONFIG", "vendor/etc/commonapi.ini",1);setenv("VSOMEIP_CONFIGURATION", "/vendor/etc/local_server.json", 1);auto runtime = CommonAPI::Runtime::get();auto weather_service = std::make_shared<WeatherServiceStub>();auto server_register = runtime->registerService("local","com.commapi.test.IWeatherService",weather_service,"someip_server");printf("register weather service : %d\n", server_register);while(true){usleep(1000 * 1000);}return 1;
}

客户端实现:someip_client.cpp

#include <string>
#include <csignal>
#include <unistd.h>
#include "thread"
#include "CommonAPI/CommonAPI.hpp"
#include "v0/com/commapi/test/IWeatherService.hpp"
#include "v0/com/commapi/test/IWeatherServiceProxy.hpp"using namespace v0::com::commapi::test;int main(int args, char** argc){setenv("COMMONAPI_CONFIG", "vendor/etc/commonapi.ini",1);setenv("VSOMEIP_CONFIGURATION", "/vendor/etc/local_client.json", 1);auto runtime = CommonAPI::Runtime::get();auto app = runtime->buildProxy<IWeatherServiceProxy>("local","com.commapi.test.IWeatherService","someip_client");while(true){if(!app->isAvailable()){printf("connecting failed, retry\n");sleep(1);continue;}break;}app->getProxyStatusEvent().subscribe([&app](CommonAPI::AvailabilityStatus status){if(status == CommonAPI::AvailabilityStatus::AVAILABLE){printf("service available\n");std::thread t1([&app]{for(int i=0; i<10; i++){CommonAPI::CallStatus callStatus;int32_t temp;CommonAPI::CallInfo callInfo;app->getTemp(callStatus, temp, &callInfo);printf("CallStatus = %d, getTemp: %d\n",callStatus, temp);}});t1.detach();}});while(true){usleep(1000 * 1000);}return 1;
}

我这里为了方便仅测试单机模式(双机模式一样的,只是配置不一样)
修改服务端配置local_server.json

{"unicast":"127.0.0.1","logging":{"level":"debug","console":"true"},"applications":[{"name":"someip_server","id":"0x1000"}],"services" :[{"service" : "0x1001","instance" : "0x0001","reliable" : { "port" : "30509", "enable-magic-cookies" : "false" }}],"routing":"someip_server","service-discovery" :{"enable" : "true","multicast" : "239.224.224.245","port" : "30490","protocol" : "udp","initial_delay_min" : "10","initial_delay_max" : "100","repetitions_base_delay" : "200","repetitions_max" : "3","ttl" : "3","cyclic_offer_delay" : "2000","request_response_delay" : "1500"}
}

修改客户端配置:local_client.json

{"unicast":"127.0.0.1","netmask" : "255.255.255.0","logging":{"level":"debug","console":"true"},"applications":[{"name":"someip_client","id":"0x1001"}],"clients" :[{"service" : "0x1001","instance" : "0x0001","reliable" : [ "41234" ]}],"service-discovery" :{"enable" : "false"}
}

然后按照上一篇vsomeip的方式,把库跟文件分别push到系统对应的目录,执行后,即可看到通信正常执行了,如下图。
在这里插入图片描述

相关文章:

(三) 搞定SOME/IP通信之CommonAPI库

本章主要介绍在SOME/IP通信过程中的另外一个IPC通信利剑&#xff0c;CommonAPI库&#xff0c;文章将从如下几个角度让读者了解什么是CommonAPI, 以及库在实际工作中的作用 文中资源&#xff1a;vsomeipcommonapi指导文档与demo源码 SOME/IP通信之CommonAPI CommonAPI库是什么C…...

windows bat脚本,使用命令行增加/删除防火墙:入站-出站,规则

常常手动设置防火墙的入站或出站规则&#xff0c;比较麻烦&#xff0c;其实可以用命令行搞定。 下面是禁用BCompare.exe连接网络的例子&#xff1a; ECHO OFF&(PUSHD "%~DP0")&(REG QUERY "HKU\S-1-5-19">NUL 2>&1)||(powershell -Comm…...

Stable Diffusion 告别复制关键词,高质量提示词自动生成插件

在使用SD时,我们经常会遇到心中无想法,或不知如何描述心中所想的图像。有时由于提示词的选择不当,生成的图片质量也不尽如人意。为此,我今天为大家推荐一个高质量的提示词自动生成插件——One Button Prompt。 下面是他生成的一些样图。 文章目录 插件安装插件说明主菜单工…...

【学习日记】【FreeRTOS】任务调度时如何考虑任务优先级——任务的自动切换

写在前面 本文开始为 RTOS 加入考虑任务优先级的自动调度算法&#xff0c;代码大部分参考野火。 本文主要是一篇学习笔记&#xff0c;加入了笔者自己对野火代码的梳理和理解。 一、基本思路 首先我们要知道&#xff0c;在 RTOS 中&#xff0c;优先级越高、越需要被先执行的的…...

C语言暑假刷题冲刺篇——day3

目录 一、选择题 二、编程题 &#x1f388;个人主页&#xff1a;库库的里昂 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C语言每日一练✨其他专栏&#xff1a;代码小游戏C语言初阶&#x1f91d;希望作者的文章能对你有…...

Taro+vue3小程序开启分享他人和分享到朋友圈

import Taro, { useShareAppMessage, useShareTimeline } from tarojs/taro;onMounted(() > {Taro.showShareMenu({withShareTicket: true,menus: [shareAppMessage, shareTimeline]}); }); useShareAppMessage((res) > {console.log(页面转发的回调)return {title: 开票…...

JAVA-Spring中IOC容器是什么?

目录 JAVA-Spring中IOC容器是什么&#xff1f;什么是IOC&#xff1f;什么是IOC容器&#xff1f;IOC和IOC容器的对比Spring框架中的IOC容器是如何工作的&#xff1f;使用XML配置的ApplicationContext使用注解的AnnotationConfigApplicationContext总结 JAVA-Spring中IOC容器是什…...

QT多屏显示程序

多屏显示的原理其实很好理解&#xff0c;就拿横向扩展来说&#xff1a; 计算机把桌面的 宽度扩展成了 w1&#xff08;屏幕1的宽度&#xff09; w2(屏幕2的宽度) 。 当一个窗口的起始横坐标 > w1&#xff0c;则 他就被显示在第二个屏幕上了。 多屏虚拟成一个桌面&#xff0…...

python使用xlwt时,报ValueError: More than 4094 XFs (styles)

在写表格时&#xff0c;遇到如下报错 一、报错原因 xlwt最多只能有4094个样式&#xff0c;超出这个样式数量就报错了。 二、解决办法 &#xff08;1&#xff09;去掉样式的要求...

GitHub 打不开解决方案

GitHub 这几年国内普通用户越来越难以访问&#xff0c;github 作为全球最大的开源平台&#xff0c;里面有用的内容很多&#xff0c;不管是对专业用户还是普通用户&#xff0c;无法访问都是很严重的问题。 1.GitHub 加速镜像 kgithub 是一个公益加速项目&#xff0c;仅需在 gi…...

Java网络编程(一)网络基础

概述 计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统、网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递 网络分类 局域网(LAN) 局域网是一种在小区域内使用的,由多台计算机组成的网络,覆盖范围…...

matlab使用教程(17)—多项式的定义和运算

1.创建并计算多项式 此示例说明如何在 MATLAB 中将多项式表示为向量以及根据相关点计算多项式。 1.1 表示多项式 MATLAB 将多项式表示为行向量&#xff0c;其中包含按降幂排序的系数。例如&#xff0c;三元素向量 p [p2 p1 p0]; 表示多项式 创建一个向量以表示二次多项式…...

华为认证 | 这门HCIA认证正式发布!

华为认证云服务工程师HCIA-Cloud Service V3.5&#xff08;中文版&#xff09;自2023年8月11日起&#xff0c;正式在中国区发布。 01 发布概述 基于“平台生态”战略&#xff0c;围绕“云-管-端”协同的新ICT技术架构&#xff0c;华为公司打造了覆盖ICT领域的认证体系&#xf…...

【Docker】Docker安装 MySQL 8.0,简洁版-快速安装使用

今天&#xff0c;使用docker安装mysql数据库进行一个测试&#xff0c;结果网上找了一篇文章&#xff0c;然后。。。。坑死我… 特总结本篇安装教程&#xff0c;主打一个废话不多说&#xff01; 坑&#xff1a;安装成功&#xff0c;客户端工具连接不上数据库》。。。 正文&…...

CSS自己实现一个步骤条

前言 步骤条是一种用于引导用户按照特定流程完成任务的导航条&#xff0c;在各种分步表单交互场景中广泛应用。例如&#xff1a;在HIS系统-门诊医生站中的接诊场景中&#xff0c;我们就可以使用步骤条来实现。她的执行步骤分别是&#xff1a;门诊病历>遗嘱录入>完成接诊…...

Visual Studio 2019 解决scanf函数报错问题

前言 Visual Studio 2019 解决scanf函数报错问题 博主博客链接&#xff1a;https://blog.csdn.net/m0_74014525 关注博主&#xff0c;后期持续更新系列文章 *****感谢观看&#xff0c;希望对你有所帮助***** 系列文章 第一篇&#xff1a;Visual Studio 2019 详细安装教程&…...

亚马逊无限买家号如何注册?

如果想要拥有大批量的亚马逊买家号&#xff0c;可以使用亚马逊鲲鹏系统进行自动注册操作。在注册之前我们需要先准备好账号所需要的资料&#xff1b; 1、Ip&#xff1a;软件系统支持11个亚马逊站点使用&#xff0c;因此注册哪一个国家的买家号时就需要购买相应国家的ip&#x…...

前端框架学习-ES6新特性(尚硅谷web笔记)

ECMASript是由 Ecma 国际通过 ECMA-262 标准化的脚本程序设计语言。javaScript也是该规范的一种实现。 新特性目录 笔记出处&#xff1a;b站ES6let 关键字const关键字变量的解构赋值模板字符串简化对象写法箭头函数rest参数spread扩展运算符Promise模块化 ES8async 和 await E…...

普陀发布新规服务元宇宙企业 和数软件发展元宇宙场景落地

近日&#xff0c;数智中国AIGC科技周2023全球元宇宙大会上海站活动现场“半马苏河”元宇宙企业科创政策包正式发布。政策包在普陀原有科创政策基础上进行了叠加升级&#xff0c;一共涵盖了十条专项服务元宇宙企业的专项政策&#xff0c;简称普陀“元十条”。 普陀“元十条”从…...

Kotlin差异化分析,let,run,with,apply及also

作用域函数是Kotlin比较重要的一个特性&#xff0c;共分为以下5种&#xff1a;let、run、with、apply 以及 also&#xff0c;这五个函数的工作方式可以说非常相似&#xff0c;但是我们需要了解的是这5种函数的差异&#xff0c;以便在不同的场景更好的利用它。 读完这篇文章您将…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

微信小程序之bind和catch

这两个呢&#xff0c;都是绑定事件用的&#xff0c;具体使用有些小区别。 官方文档&#xff1a; 事件冒泡处理不同 bind&#xff1a;绑定的事件会向上冒泡&#xff0c;即触发当前组件的事件后&#xff0c;还会继续触发父组件的相同事件。例如&#xff0c;有一个子视图绑定了b…...

以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:

一、属性动画概述NETX 作用&#xff1a;实现组件通用属性的渐变过渡效果&#xff0c;提升用户体验。支持属性&#xff1a;width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项&#xff1a; 布局类属性&#xff08;如宽高&#xff09;变化时&#…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...