首页/新闻资讯/正文详情

树莓派4B+DroneKit实战:用Python控制无人机精准飞行正方形航线

发布时间:2026/9/25 1:26:46 来源:云帆数科 栏目:资讯中心
树莓派4B+DroneKit实战:用Python控制无人机精准飞行正方形航线
上周我把树莓派4B和Pixhawk接到一起用DroneKit写了段Python脚本让无人机在操场草坪上飞了一个规规矩矩的正方形。说实话整个过程比我想象中曲折先是串口权限折腾了半天后来又发现DroneKit的安装依赖有个老坑等到真正看到飞机起飞、转弯、落回起点的时候心里那块石头才落地。这篇文章就是那次实战的完整记录。不管你是刚摸到树莓派4B的新手还是已经会飞航线但想用代码接管飞控的爱好者这篇内容都能帮你省掉至少两三次返工。我会把树莓派环境搭建、DroneKit的安装避坑、串口连接、正方形航线的坐标计算以及整个飞行代码一次讲清楚最后附上我踩过的那些典型问题的排查办法。1. 整体设计与实现思路先把话说在前面用树莓派4B做无人机的地面站或机载电脑本质上就是让一块巴掌大的Linux开发板通过MAVLink协议和飞控通信。DroneKit是一个基于Python的开发库它把MAVLink的复杂报文封装成了接近自然语言的函数调用比如vehicle.arm()、vehicle.simple_goto()这样我们就可以用脚本控制飞机的起飞、导航、降落。这个方案的价值在于所有逻辑都在代码里航线想改成三角形、五角星或者任意多边形只要改坐标数据就行不需要重新规划遥控器操作。1.1 为什么选树莓派4B DroneKit先说硬件这块。树莓派4B拥有四核Cortex-A72处理器运行Ubuntu或者树莓派官方系统都绰绰有余。DroneKit本身对CPU的要求很低真正吃资源的是如果你在树莓派上跑MAVProxy、日志记录、摄像头图像处理这些附加任务。4B的2GB内存起步版本完全够用如果打算后续加机器视觉功能建议选4GB或8GB版本。软件层面选择DroneKit而不是直接写MAVLink字节流原因很简单效率。直接操作pymavlink需要自己组包、解析、处理消息ID先不说学习成本光是排查一个报文到底有没有被飞控正确执行就够头疼的。DroneKit把这层封装掉了暴露出来的API基本是面向任务的比如simple_goto()就是“飞到这个经纬度高度”底层怎么发SET_POSITION_TARGET_GLOBAL_INT你不用管。飞控端推荐使用ArduPilot固件。DroneKit对ArduPilot的支持最完整Pixhawk、Cube、Jetson载板都没问题。PX4固件虽然部分兼容但很多消息协议不一致特别是simple_goto在PX4上的表现并不稳定容易出各种奇怪问题本文的实操部分默认就是ArduPilot。1.2 正方形飞行任务的流程拆解飞正方形听起来简单实际执行包含几个必须严格控制的关键阶段飞控连接树莓派通过USB接数传模块或者直接连接飞控的TELEM口建立MAVLink通信。解锁与起飞脚本发出arm命令让飞控解锁电机然后控制飞机垂直上升到设定高度。依次导航四个角以起飞点为基准按照“东北、东南、西南、西北”的顺序依次调用simple_goto飞往正方形四个顶点。返航与降落飞完最后一个点后返回起点然后触发vehicle.mode VehicleMode(LAND)原地降落。设计这个流程时有几个问题需要考虑清楚。起飞点并不一定适合作为正方形的第一个顶点因为起飞位置可能有障碍物或者地形倾斜。所以实际操作中我会让飞机先垂直上升然后飞到第一个角的坐标再从第一个角开始走正方形。这样正方形的位置可以偏移到一个相对平坦、开阔的区域飞行体验和安全性都会好很多。2. 树莓派4B环境准备与Python开发环境搭建这部分内容看起来基础但恰恰是很多新手耗时最久的环节。我遇到过不少人在树莓派上装了好几个Python版本结果DroneKit装到错误的解释器里或者系统自带的Python和Ubuntu版本不匹配。下面直接给出我验证过可行的方案。2.1 系统选择与烧录树莓派4B的系统我推荐两种:树莓派官方Raspberry Pi OS64位版和Ubuntu Server 22.04 LTS。如果你只想专注跑DroneKit官方系统更省心因为驱动、固件、Python环境都比较齐全。如果用Ubuntu建议选Server版因为桌面环境对无人机地面站场景没有额外帮助反而占用性能。系统烧录推荐用树莓派官方的Raspberry Pi Imager工具在电脑上选择镜像后直接写入SD卡。烧录完成后注意这个细节在SD卡根目录创建一个空的ssh文件无扩展名才能通过SSH远程登录。另外首次开机建议接上显示器和键盘完成Wi-Fi配置或者提前在wpa_supplicant.conf里写好网络信息这样开机就能直接SSH进去。我在这次实战里用的是树莓派官方系统Bookworm版本。顺便提醒一句新版系统默认Python是3.11对DroneKit的某些依赖可能会有兼容性问题后面安装一节我会专门说怎么处理。2.2 Python环境与VS Code远程开发树莓派系统默认自带Python 3先用python3 --version确认版本只要不是太老就能用。我建议用venv创建一个独立的虚拟环境避免系统级的site-packages被搞乱。操作非常直接sudo apt update sudo apt install -y python3-venv python3-pip mkdir ~/drone_project cd ~/drone_project python3 -m venv venv source venv/bin/activate虚拟环境激活后命令行前缀会变成(venv)这时候装的包全部隔离在当前项目里。我习惯这样做因为DroneKit的依赖项比较老和系统包冲突时不会影响其他开发。代码编辑我强烈推荐在电脑上用VS Code搞定树莓派上只负责运行。VS Code的Remote-SSH插件可以连到树莓派代码实时同步调试体验很接近本地开发。配置方法就是在扩展市场搜索Remote-SSH然后添加树莓派的IP和登录用户非常方便。2.3 DroneKit安装与那个著名的坑现在到了本次项目最典型的坑点。执行pip install dronekit乍一看命令很常规但如果你用的是Python3.9以上版本这个命令会卡在Collecting pymavlink这一步很久甚至最终报编译错误。这个问题的根源是DroneKit 2.9.2版本对pymavlink的版本要求写得太宽泛pip会尝试去安装最新版的pymavlink而新版pymavlink会去编译一些C扩展缺少编译工具链时就直接失败。解决办法是用--no-deps参数跳过自动依赖安装然后手动装兼容版本的依赖pip install --no-deps dronekit pip install pymavlink2.4.41 pip install future pip install monotonic pip install pyserial pip install netifaces这几个依赖缺一不可。pymavlink负责MAVLink协议的编解码future是Python2/3兼容层monotonic用于计时pyserial是串口通信的基础netifaces处理网络接口。手动指定pymavlink版本为2.4.41是因为这个版本和DroneKit磨合得最好不会出现奇奇怪怪的兼容报错。注意如果系统里已经有旧版pymavlink最好先pip uninstall pymavlink再装不然两个版本并存会让树莓派在解析MAVLink消息时彻底混乱。装完之后顺手验证一下python -c from dronekit import connect; print(DroneKit OK)能打印出OK说明DroneKit已经可以正常导入了。3. 飞控连接与关键参数配置环境装好之后最大的挑战是让树莓派稳定地和飞控建立通信。这一节我按硬件连接、飞控参数、软件确认三条线来说。3.1 通过USB数传模块连接飞控树莓派和飞控之间最推荐的方式是USB数传模块。USB数传一端插在飞控的TELEM口另一端插在树莓派的USB口系统会识别出一个串口设备通常是/dev/ttyUSB0。插上之后用ls /dev/tty*确认设备节点存在。这里有个很常见的权限问题默认情况下普通用户访问/dev/ttyUSB0会被拒绝提示Permission denied。需要把当前用户加入dialout组sudo usermod -a -G dialout $USER然后重新登录或者直接重启再运行代码就不会串口权限报错了。如果你用的是USB-TTL线直连飞控的TELEM口操作思路是一样的但要特别确认TXD、RXD、GND三根线的接线顺序不能错。数传模块一般自带电平转换直连时如果电平不匹配有烧坏飞控的风险这方面我建议优先使用数传模块别为了省几十块钱去冒险。3.2 飞控端参数设置通过数传连接后ArduPilot飞控默认的TELEM口参数通常就能直接通信但为了保险建议在地面站里逐项确认这几个参数参数名推荐值说明SERIAL0_BAUD57TELEM1口波特率对应57600SERIAL0_PROTOCOL2表示MAVLink2协议ARMING_CHECK1保持默认解锁检查FENCE_ENABLE1开启电子围栏强烈建议FENCE_ACTION1围栏触发后RTL返航FENCE_RADIUS80围栏半径单位米特别是FENCE_ENABLE和FENCE_ACTION这两个参数新手飞行的时候建议一定开起来。我之前见过有人在测试时飞机飞出去了因为遥控器切模式不及时眼看飞机冲出去几百米最后是切了RTL才飞回来。电子围栏等于多一道保险就算代码逻辑出问题飞机也会在边界自动返航。3.3 用wait_ready确认连接质量在一个Python脚本里连接飞控核心代码长这样from dronekit import connect connection_string /dev/ttyUSB0 vehicle connect(connection_string, wait_readyTrue, baud57600)wait_readyTrue会让程序阻塞直到从飞控收到至少一套遥测数据包经纬度、高度、姿态角等才继续往下走。这个参数一定要开否则你可能会在飞控还没完全握手成功时就发送指令导致指令丢失。连接之后先打印几个关键参数确认数据是活的print(版本: %s % vehicle.version) print(GPS: %s % vehicle.location.global_frame) print(电池: %s % vehicle.battery) print(模式: %s % vehicle.mode.name)如果一直卡在connect这步不往下走排查顺序是串口节点是否正常、波特率是否匹配、wait_ready是否能收到心跳包。后面问题排查那节我再展开讲。4. 正方形航线核心代码实现这一节进入正题。我用的是“先起飞到指定高度再依次飞往正方形四个角最后原地降落”的流程。为了让代码清晰易懂拆成三个部分来写坐标计算、基础函数、主流程。4.1 正方形四个顶点的坐标计算很多人一听到飞行坐标就觉得要处理GPS经纬度很麻烦。其实借助一个简单的经纬度偏移函数就能解决。它的原理是在经纬度平面上做近似平移纬度1度的距离大概是111320米经度1度的距离则取决于当前纬度约等于111320 * cos(纬度)。当距离只有几十米时这种近似完全够用。import math def move_meters(lat, lon, d_north, d_east): 从(lat, lon)出发向北移动d_north米、向东移动d_east米返回新的经纬度 earth_radius 6371000.0 d_lat d_north / earth_radius d_lon d_east / (earth_radius * math.cos(math.radians(lat))) new_lat lat math.degrees(d_lat) new_lon lon math.degrees(d_lon) return new_lat, new_lon以起飞点(home_lat, home_lon)为基准正方形边长设为10米四个顶点坐标这样算side_length 10.0 # 起飞点 home_lat, home_lon vehicle.location.global_frame.lat, vehicle.location.global_frame.lon # 第一个角: 起飞点向北5米、向东5米 corner1 move_meters(home_lat, home_lon, side_length / 2, side_length / 2) # 第二个角: 向东10米 corner2 move_meters(home_lat, home_lon, side_length / 2, side_length / 2 side_length) # 第三个角: 向南10米 corner3 move_meters(home_lat, home_lon, side_length / 2 - side_length, side_length / 2 side_length) # 第四个角: 向西10米 corner4 move_meters(home_lat, home_lon, side_length / 2 - side_length, side_length / 2)这样得到的就是一个以起飞点为中心的正方形四个顶点分别对应“右上、右下、左下、左上”。实际飞行时我会把边长调到20米以上因为GPS定位本身有误差10米的边长在飞行轨迹上看起来可能歪歪扭扭。4.2 起飞、到达判断、降落函数起飞用vehicle.simple_takeoff它会自动把飞控切换到GUIDED模式并完成爬升。以下是带目标高度验证的起飞函数def arm_and_takeoff(target_altitude): print(基本参数检查...) while not vehicle.is_armable: print( 等待飞控初始化...) time.sleep(1) print(切换到GUIDED模式) vehicle.mode VehicleMode(GUIDED) print(解锁电机) vehicle.armed True while not vehicle.armed: print( 等待解锁...) time.sleep(1) print(起飞到 %s 米 % target_altitude) vehicle.simple_takeoff(target_altitude) while True: print( 当前高度: %.2f米 % vehicle.location.global_relative_frame.alt) if vehicle.location.global_relative_frame.alt target_altitude * 0.95: print( 到达目标高度) break time.sleep(1)global_relative_frame表示相对于起飞点的高度这个值是判断爬升是否完成的关键依据。从A点飞到B点用simple_goto是不会自己判断“是否已经到达”的它只是把指令发给飞控。所以必须写一个等待循环持续计算当前位置和目标点的距离距离小于阈值就认为到达。这里我封装成goto_position函数def goto_position(target_lat, target_lon, target_alt, timeout60): target_location LocationGlobalRelative(target_lat, target_lon, target_alt) print(飞往: %.6f, %.6f 高度: %.1f % (target_lat, target_lon, target_alt)) vehicle.simple_goto(target_location) start_time time.time() while True: if time.time() - start_time timeout: print(超时未到达指定点) break current vehicle.location.global_frame distance get_distance_meters(current, LocationGlobal(target_lat, target_lon, target_alt)) if distance 1.0: print(到达目标点附近) break time.sleep(0.5)注意这个判断的尺度室内GPS环境经常抖动距离阈值设为1米比较合适如果设成0.2米飞机可能一直在原地转圈。这个函数里用到的get_distance_meters直接用DroneKit自带的工具就行from pymavlink.dialects.v20 import ardupilotmega def get_distance_meters(aLocation1, aLocation2): dlat aLocation2.lat - aLocation1.lat dlong aLocation2.lon - aLocation1.lon return math.sqrt((dlat * 111320.0) ** 2 (dlong * 111320.0 * math.cos(math.radians(aLocation1.lat))) ** 2) * 1.04.3 完整飞行主流程把所有串起来主流程就是先连接再起飞再按顺序飞四个角最后降落。注意我在飞第一个角之前先让飞机在起飞点原地升高避免起飞时的气流干扰影响正方形起点位置。from dronekit import connect, VehicleMode, LocationGlobal, LocationGlobalRelative import time, math def main(): vehicle connect(/dev/ttyUSB0, wait_readyTrue, baud57600) target_alt 5.0 side_length 20.0 print( 解锁并起飞 ) arm_and_takeoff(target_alt) print( 等待起飞点GPS稳定 ) home_lat vehicle.location.global_frame.lat home_lon vehicle.location.global_frame.lon time.sleep(2) c1 move_meters(home_lat, home_lon, side_length / 2, side_length / 2) c2 move_meters(home_lat, home_lon, side_length / 2, side_length / 2 side_length) c3 move_meters(home_lat, home_lon, side_length / 2 - side_length, side_length / 2 side_length) c4 move_meters(home_lat, home_lon, side_length / 2 - side_length, side_length / 2) print( 飞往第一个角 ) goto_position(c1[0], c1[1], target_alt) print( 飞往第二个角 ) goto_position(c2[0], c2[1], target_alt) print( 飞往第三个角 ) goto_position(c3[0], c3[1], target_alt) print( 飞往第四个角 ) goto_position(c4[0], c4[1], target_alt) print( 返回起点 ) goto_position(home_lat, home_lon, target_alt) print( 原地降落 ) vehicle.mode VehicleMode(LAND) while vehicle.armed: time.sleep(1) print(降落完成) vehicle.close()这段脚本整体逻辑不复杂但有几个细节值得展开说。第一为什么先在起飞点原地起飞再goto第一个角因为起飞时螺旋桨产生的离地效应会让飞机轻微偏移如果直接goto第一个角实际起点和理论起点会有偏差。先在原地爬升等高度稳定后再执行水平移动正方形的起点更准确。第二为什么四个角访问顺序是“右上-右下-左下-左上”这个顺序可以保证飞机按顺时针方向飞行减少转向角度实际轨迹不太会出现绕大弯的情况。第三每一个goto_position之间要有时间间隔吗不需要显式sleep因为goto_position内部会等到接近目标点才返回天然顺序执行。4.4 不同飞行环境的参数适配上面代码默认室外GPS环境。如果在室内飞行情况完全不同GPS信号弱甚至没有飞控必须依靠光流模块或视觉定位系统提供位置信息。这种情况下move_meters函数和simple_goto的定位能力会大打折扣需要配合光流模块才能实现类似航线。我的建议是新手阶段不要尝试室内航线先找一个空旷的操场或草坪确保GPS星数在10颗以上再飞。我第一次在小区楼下测试四面高楼遮挡GPS飘得厉害飞机明明在悬停位置数据却在两三米范围内来回跳航线形状自然也就对不上。换到开放场地之后同样的代码跑出来的正方形就肉眼可见地标准了。5. 常见问题与排查技巧实录这部分是这篇博文的精华部分全部来自我实际踩过的坑。每一个问题都附上现象、原因和解决方法建议收藏飞行前对照排查。5.1 DroneKit安装与导入问题现象pip install dronekit卡在pymavlink编译上或者安装完成后from dronekit import connect报ModuleNotFoundError。原因新版pip会尝试安装满足依赖条件的最高版本pymavlink而这个新版本带有C扩展缺少编译工具链时直接失败DroneKit代码本身也因为老API不兼容新版pymavlink导致导入崩溃。解决方案就是要严格指定依赖版本也就是前面说的pip install --no-deps dronekit pip install pymavlink2.4.41 pip install future monotonic pyserial netifaces另外一个隐蔽情况是树莓派系统里有多个Python版本比如系统自带Python 3.11你又装了Python 3.9。如果不用虚拟环境pip可能会装到其中一个Python里而python命令调用的却是另一个。解决方法统一用venv激活虚拟环境后再执行python命令就不会混乱了。5.2 串口连接故障现象connect()一直卡住报Timeout或者提示[Errno 13] Permission denied: /dev/ttyUSB0。串口权限问题最常见执行sudo usermod -a -G dialout $USER后重新登录即可。如果你确定设备节点存在且权限正常那就查波特率连接方式波特率原厂数传模块USB默认576003DR Radio V2/V357600USB-TTL直连TELEM2根据SERIAL1_BAUD确定常见57600或921600如果波特率对不上树莓派能检测到设备但收不到任何心跳包wait_ready自然一直等着。还有一个很不起眼的坑树莓派的USB口供电不足时数传模块可能会间歇性掉线。换一个带外部供电的USB Hub或者直接给树莓派用足额5V/3A电源可以解决。我最初用手机充电器供电电流不够飞控连上不到一分钟就掉线。5.3simple_goto后飞机一直绕圈或不动现象代码执行到simple_goto飞机要么原地悬停要么绕着一个点转圈就是不朝目标点飞。这个问题的根源通常是飞控没有在GUIDED模式下收到足够好的定位信息。在室外先确认GPS锁定的卫星数可以在地面站里看HUD的GPS状态至少10颗星以上再起飞。如果星数太少飞控在GUIDED模式下会拒绝执行精确的坐标导航。还有一个情况是simple_goto的参数传成了LocationGlobal而不是LocationGlobalRelative。如果高度参数用的是绝对高度而飞控的绝对高度参考的是海平面这时候飞控会认为目标点在很高或很低的位置飞行方向自然不对。用LocationGlobalRelative并把高度设为相对起飞点的高度就不会有这个问题。5.4 RTL设置与安全降落一旦出现失联情况飞控会自动触发RTL返回起飞点上空并降落前提是地面站和飞控连接的通信通道断开了。但如果你是在树莓派上跑脚本飞控触发RTL之后树莓派会收到位置变化信息脚本里的goto_position不会立刻报错而是会执着地继续调用simple_goto把飞机从RTL航线上拉回原来的目标点。这个逻辑冲突我遇到过好几次。解决办法是在每个goto_position循环里增加一个检测如果飞控当前模式变成了RTL或LAND就主动跳出循环停止导航。伪代码如下while True: if vehicle.mode.name in [RTL, LAND]: print(飞控进入%s模式取消导航 % vehicle.mode.name) break # 原有距离判断逻辑 ...当然最好还是提前设好电子围栏参数从源头避免飞出安全区域。5.5 降落后电机仍在低速转动现象飞机落地后vehicle.mode VehicleMode(LAND)执行完螺旋桨还在转脚本却已经结束退出。ArduPilot的LAND模式会让飞机自动降低油门并在地面停留一段时间确认机轮完全停稳后再关闭电机。这个阶段通常需要几秒脚本里最好加一个等待解锁状态变为False的循环while vehicle.armed: print( 等待电机停止...) time.sleep(1)如果一直无法停止考虑检查飞控的MOT_PWM_MIN和MOT_SPIN_ARM参数看看怠速值是否过高。实操总结这套从树莓派4B到DroneKit飞正方形的链路跑通之后就会发现真正复杂的不是代码本身而是各种环境细节和飞控设置。我个人的体会是把每一段流程都拆成独立的函数先用模拟器跑通逻辑再上真机会省掉大量挫败感。ArduPilot的SITL模拟器可以完全脱离硬件运行DroneKit脚本你可以在电脑上先把正方形航线跑一遍确认坐标计算和流程没有逻辑问题再烧到树莓派上做真机飞行。最后再分享一个细节实际执行时不要一上来就用20米的边长。第一次测试我建议用10米高度、20米边长电池充满确保至少留出60%的电量应对突发情况。飞行当天先检查一遍桨叶是否完整、电池电压是否正常、GPS星数是否足够再启动脚本。严格按照这个流程走你大概率会在第一次就看到你的无人机画出规整的轨迹。

相关推荐

MCP 2026 路线图深度解析:四大优先领域、SEP 评审优先级与社区参与指南
MCP 2026 路线图深度解析:四大优先领域、SEP 评审优先级与社区参与指南

人工智能AI Agent工具调用 【免费下载链接】specification Specification and documentation for the Model Context Protocol 项目地址: https://gitcode.com/gh_mirrors/specification2/specification 点击查看 免费下载 2026 年 3 月,Model Context … · 2026/9/25 1:26:40

VS Code插件这样配 TaoToken,settings.json 骨架一次到位
VS Code插件这样配 TaoToken,settings.json 骨架一次到位

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:26:40

洗碗机水泵EMC高集成整改方案:四维协同降噪
洗碗机水泵EMC高集成整改方案:四维协同降噪

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:26:40

CiLocks的keyevent速查表:8个Android按键码如何操控锁屏界面
CiLocks的keyevent速查表:8个Android按键码如何操控锁屏界面

CiLocks的keyevent速查表:8个Android按键码如何操控锁屏界面 【免费下载链接】CiLocks Crack Interface lockscreen, Metasploit and More Android/IOS Hacking 项目地址: https://gitcode.com/GitHub_Trending/ci/CiLocks CiLocks 是一款开源的 Android 锁屏… · 2026/9/25 2:36:01

BilibiliCacheVideoMerge路线图与社区指南:B站缓存视频合并为何转向Flutter重构?Issues与贡献完整清单
BilibiliCacheVideoMerge路线图与社区指南:B站缓存视频合并为何转向Flutter重构?Issues与贡献完整清单

BilibiliCacheVideoMerge路线图与社区指南:B站缓存视频合并为何转向Flutter重构?Issues与贡献完整清单 【免费下载链接】BilibiliCacheVideoMerge 🔥🔥Android上将bilibili缓存视频合并导出为mp4,支持安卓5.0 ~ 13&… · 2026/9/25 2:36:01

PaddleSpeech 标点恢复实战:基于 ERNIE 的 IWSLT2012-中文标点预测全流程指南
PaddleSpeech 标点恢复实战:基于 ERNIE 的 IWSLT2012-中文标点预测全流程指南

人工智能语音音频NLP媒体生成 【免费下载链接】PaddleSpeech Easy-to-use Speech Toolkit including Self-Supervised Learning model, SOTA/Streaming ASR with punctuation, Streaming TTS with text frontend, Speaker Verification System, End-to-End Speech Translation … · 2026/9/25 2:36:01

wheel-picker-cj 源码拆解:双 Scroll 同步实现滚轮吸附的底层原理
wheel-picker-cj 源码拆解:双 Scroll 同步实现滚轮吸附的底层原理

wheel-picker-cj 源码拆解:双 Scroll 同步实现滚轮吸附的底层原理 【免费下载链接】wheel-picker-cj 滚轮选择UI组件 项目地址: https://gitcode.com/Cangjie-TPC/wheel-picker-cj wheel-picker-cj 是一款基于仓颉(Cangjie)语言开发的… · 2026/9/25 2:36:01

阿里云部署OpenClaw:79元/年搭24小时AI代理,TaoToken统一Key接入配置指南
阿里云部署OpenClaw:79元/年搭24小时AI代理,TaoToken统一Key接入配置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 2:36:01

Comp AI CRM 渲染性能实践:用 useTransition 取代手动加载状态,告别多余重渲染
Comp AI CRM 渲染性能实践:用 useTransition 取代手动加载状态,告别多余重渲染

后端前端CRM人工智能AI Agent 【免费下载链接】crm Comp AI CRM is an open source, CRM designed for AI agents. Agentic-first CRM. 项目地址: https://gitcode.com/gh_mirrors/crm48/crm 点击查看 免费下载 本指南基于 Comp AI CRM 仓库内置的 Vercel React 最… · 2026/9/25 2:35:55

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码