UR协作机器人+Robotiq夹爪:ur_rtde的C++与Python控制及数据记录实战
1. 项目缘起与整体设计思路1.1 这个项目到底在做什么这个项目的核心目标很明确用一台UR系列协作机器人搭配Robotiq末端执行器通过ur_rtde这个工具包分别用C和Python两套语言实现控制与数据记录。说白了就是让机械臂动起来、让夹爪抓起来、把整个过程的数据存下来方便后续分析或复现。ur_rtde是一个开源的实时数据交换接口库专门为UR机器人设计。它封装了UR的RTDE协议把底层那些繁琐的寄存器读写、数据包解析都藏起来了留给上层的就是几个干净的类RTDEControlInterface负责控制指令RTDEReceiveInterface负责状态接收还有RTDEIOInterface管IO。这套东西的好处是实时性够用接口稳定社区维护也活跃。Robotiq末端执行器这边常见的是2F-85、2F-140这类两指自适应夹爪也有Hand-E这种。它们通常通过Modbus RTU或者Modbus TCP跟UR的控制柜通信。UR本身支持Modbus所以最省事的做法就是把Robotiq的Modbus寄存器映射到UR的IO或者直接用ur_rtde的IO接口去写。这个项目适合谁呢如果你正在做机器人抓取、装配、上下料这类任务需要把机械臂和夹爪联动起来同时还要记录关节角度、TCP位姿、夹爪开合状态这些数据那这套方案基本可以直接抄。如果你只是想让UR动一下那可能用不上这么完整的框架但数据记录这部分迟早会需要。1.2 为什么选ur_rtde而不是其他方案UR机器人控制方式有好几种URScript通过socket发、Dashboard Server发指令、RTDE直接读写、还有URCap插件。我选ur_rtde主要看中三点。第一实时性。RTDE本身就是为实时数据交换设计的默认125Hz的周期对于大部分抓取任务够用了。你要是用URScript发movej那个延迟和抖动在精细操作里很难受。第二跨语言。ur_rtde同时提供C和Python绑定Python版底层就是C的封装所以两套代码的行为一致不用维护两套逻辑。Python适合快速验证和数据分析C适合部署到工控机或者对周期要求更严的场景。第三数据记录方便。RTDEReceiveInterface可以订阅一堆输出量actual_q、actual_TCP_pose、actual_digital_input_bits、runtime_state等等。你只要在回调或者循环里读就行不用自己去解析RTDE数据包。Robotiq这边为什么不直接用URCapURCap是图形化配置简单场景确实快但你要做复杂逻辑、要记录夹爪的实时位置和电流URCap就不够灵活了。直接走Modbus寄存器读写虽然麻烦一点但控制粒度细数据也能拿到。1.3 整体架构拆解整个系统分三层通信层ur_rtde负责跟UR控制柜通信Modbus客户端负责跟Robotiq通信。如果Robotiq是接在UR的Tool端或者控制柜的Modbus端口上那其实可以统一走UR的Modbus但为了清晰我习惯把夹爪控制单独拎出来。控制层C或Python写的主控程序负责发运动指令、发夹爪指令、处理异常。记录层一个独立的线程或者进程以固定频率采集RTDE数据和夹爪状态写到CSV或者二进制文件里。这个分层的好处是控制逻辑和数据记录解耦。你调运动参数的时候不会影响记录频率记录那边卡了也不会让机械臂停下来。注意ur_rtde的RTDEControlInterface和RTDEReceiveInterface最好在同一个进程里但不同线程。控制线程发指令接收线程读数据别在一个线程里既发又读容易阻塞。2. 环境搭建与核心细节解析2.1 硬件连接与网络配置UR机器人控制柜后面有个网口通常默认IP是192.168.0.1或者你设的静态IP。工控机或者开发机用网线直连配同网段IP比如192.168.0.100子网掩码255.255.255.0。Robotiq的接线分两种情况通过UR控制柜的ModbusRobotiq的RS485接到UR控制柜的Modbus端口然后在UR的IO设置里配Modbus RTU。这种方式下夹爪的寄存器地址会映射到UR的Modbus地址空间ur_rtde可以通过RTDEIOInterface或者直接发URScript的modbus_set_output_register来写。通过USB转RS485Robotiq直接接工控机的USB口工控机上跑一个Modbus RTU主站。这种方式更灵活但多了一个串口要管。我一般推荐第一种少一个串口设备而且UR控制柜本身就对Modbus有支持稳定性好。网络配置这块UR的RTDE默认端口是30004Dashboard是29999。ur_rtde连接的时候指定IP就行端口默认。2.2 ur_rtde的安装与编译Python版安装最简单pip install ur_rtde但注意pip安装的是预编译的wheel可能跟你系统的Python版本、架构不匹配。如果装不上就得从源码编译。C版编译步骤git clone https://github.com/UniversalRobots/Universal_Robots_RTDE_Client.git cd Universal_Robots_RTDE_Client mkdir build cd build cmake .. -DCMAKE_BUILD_TYPERelease make -j4 sudo make install编译依赖CMake 3.5、C17编译器、Boost主要是thread和system。Ubuntu下装libboost-all-dev就行。实操心得C编译的时候如果遇到Boost版本问题别急着升级系统Boost可以在CMake里指定Boost路径。另外ur_rtde的C库默认装到/usr/local/lib记得把/usr/local/lib加到ld.so.conf或者设LD_LIBRARY_PATH。Python版如果pip装不上也可以从源码编译git clone https://github.com/UniversalRobots/Universal_Robots_RTDE_Client.git cd Universal_Robots_RTDE_Client mkdir build cd build cmake .. -DPYTHON_BINDINGSON -DCMAKE_BUILD_TYPERelease make -j4编译出来的.so文件在build目录下把它加到PYTHONPATH或者拷到site-packages里。2.3 Robotiq Modbus寄存器映射Robotiq 2F-85的Modbus寄存器地址以UR的Modbus地址空间为例实际地址可能偏移寄存器地址功能说明0x03E8 (1000)动作请求写1激活写0复位0x03E9 (1001)位置请求0-255对应开合度0x03EA (1002)速度请求0-2550x03EB (1003)力请求0-2550x07D0 (2000)夹爪状态读gACT、gGTO、gSTA等0x07D1 (2001)位置反馈读当前开合度0x07D2 (2002)电流反馈读当前电流这些地址是Robotiq手册里的标准地址但通过UR的Modbus映射后实际读写的地址可能不一样。你得在UR的IO设置里看Modbus RTU的映射表。注意Robotiq上电后需要先写动作请求寄存器为1来激活等状态寄存器的gSTA变成3激活完成才能发位置指令。这个激活过程大概需要几百毫秒别一上电就发位置会没反应。2.4 数据记录的内容设计记录什么数据取决于你后续要分析什么。我一般至少记这几类关节数据actual_q6个关节角度、actual_qd关节速度、actual_current关节电流TCP数据actual_TCP_pose6维位姿、actual_TCP_speed夹爪数据位置反馈、电流反馈、状态字时间戳RTDE的timestamp或者系统时间IO状态actual_digital_input_bits、actual_digital_output_bits记录频率一般跟RTDE的周期一致125Hz或者500Hz。500Hz对硬盘写入压力大除非你上SSD或者用二进制格式否则125Hz够用了。存储格式我推荐CSV方便用Excel或者Python的pandas直接读。但如果记录时间长CSV文件会很大这时候可以用二进制或者HDF5。我一般先用CSV后期要压缩再转。3. 实操过程与核心环节实现3.1 Python版控制与记录完整流程先上代码骨架再解释关键点。import rtde_control import rtde_receive import rtde_io import time import csv import threading ROBOT_IP 192.168.0.1 # 初始化接口 rtde_c rtde_control.RTDEControlInterface(ROBOT_IP) rtde_r rtde_receive.RTDEReceiveInterface(ROBOT_IP) rtde_io rtde_io.RTDEIOInterface(ROBOT_IP) # 夹爪激活 def activate_gripper(): # 通过UR的Modbus写寄存器这里用RTDEIOInterface的setToolDigitalOut或直接发URScript # 实际项目中通常用rtde_c.sendCustomScript或modbus客户端 pass # 数据记录线程 class DataRecorder(threading.Thread): def __init__(self, rtde_r, filename, freq125): super().__init__() self.rtde_r rtde_r self.filename filename self.freq freq self.running True self.data [] def run(self): dt 1.0 / self.freq while self.running: t time.time() q self.rtde_r.getActualQ() tcp self.rtde_r.getActualTCPPose() qd self.rtde_r.getActualQd() current self.rtde_r.getActualCurrent() row [t] q tcp qd current self.data.append(row) elapsed time.time() - t if elapsed dt: time.sleep(dt - elapsed) def stop(self): self.running False self.join() with open(self.filename, w, newline) as f: writer csv.writer(f) writer.writerow([timestamp] [fq{i} for i in range(6)] [ftcp{i} for i in range(6)] [fqd{i} for i in range(6)] [fcurrent{i} for i in range(6)]) writer.writerows(self.data) # 主流程 if __name__ __main__: recorder DataRecorder(rtde_r, robot_data.csv, freq125) recorder.start() # 运动到初始位置 rtde_c.moveJ([0, -1.57, 1.57, -1.57, -1.57, 0], 0.5, 0.3) time.sleep(1) # 直线运动 rtde_c.moveL([0.3, 0, 0.3, 0, 0, 0], 0.1, 0.1) time.sleep(1) # 夹爪动作 # 这里调用夹爪控制函数 recorder.stop() rtde_c.stopScript()关键点解释RTDEControlInterface的moveJ和moveLmoveJ是关节空间运动参数是目标关节角、速度、加速度。moveL是笛卡尔空间直线运动参数是目标位姿、速度、加速度。速度单位是rad/s和m/s加速度是rad/s²和m/s²。RTDEReceiveInterface的getActualQ等这些方法返回的是当前时刻的值不是缓存。所以你在循环里读读到的就是最新的。记录线程的sleep用time.sleep来控频但sleep的精度受系统调度影响实际频率可能略低于设定值。如果要精确控频可以用time.perf_counter和忙等待但会占CPU。数据存储先存内存最后一次性写文件。如果记录时间长内存不够可以边记边写但要注意文件IO的阻塞。实操心得Python的GIL对多线程有影响但记录线程主要是IO等待和sleepCPU占用不高所以问题不大。如果记录频率要500Hz以上建议用C或者把记录放到独立进程。3.2 C版控制与记录实现C版的结构跟Python类似但性能更好适合部署。#include ur_rtde/rtde_control_interface.h #include ur_rtde/rtde_receive_interface.h #include ur_rtde/rtde_io_interface.h #include thread #include chrono #include fstream #include vector #include atomic using namespace ur_rtde; std::atomicbool recording{true}; std::vectorstd::vectordouble data_buffer; void recordThread(RTDEReceiveInterface rtde_r, double freq) { double dt 1.0 / freq; while (recording) { auto t_start std::chrono::high_resolution_clock::now(); std::vectordouble row; auto q rtde_r.getActualQ(); auto tcp rtde_r.getActualTCPPose(); auto qd rtde_r.getActualQd(); auto current rtde_r.getActualCurrent(); row.push_back(std::chrono::durationdouble( std::chrono::system_clock::now().time_since_epoch()).count()); row.insert(row.end(), q.begin(), q.end()); row.insert(row.end(), tcp.begin(), tcp.end()); row.insert(row.end(), qd.begin(), qd.end()); row.insert(row.end(), current.begin(), current.end()); data_buffer.push_back(row); auto t_end std::chrono::high_resolution_clock::now(); double elapsed std::chrono::durationdouble(t_end - t_start).count(); if (elapsed dt) { std::this_thread::sleep_for(std::chrono::durationdouble(dt - elapsed)); } } } int main() { std::string robot_ip 192.168.0.1; RTDEControlInterface rtde_c(robot_ip); RTDEReceiveInterface rtde_r(robot_ip); RTDEIOInterface rtde_io(robot_ip); std::thread recorder(recordThread, std::ref(rtde_r), 125.0); // 运动 std::vectordouble joint_target {0, -1.57, 1.57, -1.57, -1.57, 0}; rtde_c.moveJ(joint_target, 0.5, 0.3); std::this_thread::sleep_for(std::chrono::seconds(1)); std::vectordouble tcp_target {0.3, 0, 0.3, 0, 0, 0}; rtde_c.moveL(tcp_target, 0.1, 0.1); std::this_thread::sleep_for(std::chrono::seconds(1)); recording false; recorder.join(); // 写CSV std::ofstream file(robot_data.csv); for (const auto row : data_buffer) { for (size_t i 0; i row.size(); i) { file row[i]; if (i row.size() - 1) file ,; } file \n; } file.close(); rtde_c.stopScript(); return 0; }C版的关键差异线程用std::thread原子变量控制停止。数据缓冲用vectorvector 最后一次性写文件。时间戳用chrono精度比Python的time.time()高。编译时链接ur_rtde库在CMakeLists.txt里加find_package(ur_rtde REQUIRED)和target_link_libraries(your_target ur_rtde::ur_rtde)。注意C版里RTDEControlInterface和RTDEReceiveInterface的构造函数会阻塞直到连接成功如果机器人没开机或者IP不对程序会卡在那里。建议加超时或者先ping一下。3.3 夹爪控制的具体实现夹爪控制这块如果走UR的Modbus可以用RTDEIOInterface的setToolDigitalOut或者直接发URScript。但更通用的做法是用一个Modbus客户端。Python下用pymodbusfrom pymodbus.client import ModbusTcpClient def gripper_activate(client): client.write_register(1000, 1) time.sleep(0.5) # 读状态确认激活 status client.read_holding_registers(2000, 1) return status.registers[0] def gripper_move(client, position, speed255, force255): client.write_register(1001, position) client.write_register(1002, speed) client.write_register(1003, force) client.write_register(1000, 1) # 触发动作如果Robotiq接在UR控制柜的Modbus上那Modbus TCP的IP就是UR的IP端口502。但UR的Modbus映射可能不是直接的寄存器地址需要在UR的IO设置里看。C下用libmodbus#include modbus/modbus.h modbus_t* ctx modbus_new_tcp(192.168.0.1, 502); modbus_connect(ctx); uint16_t reg[1]; reg[0] 1; modbus_write_register(ctx, 1000, reg[0]);实操心得Robotiq的激活流程一定要等写1之后至少等300ms再读状态。如果gSTA不是3再等。有时候第一次激活会失败重试一次就好。另外位置请求0-255对应的是开合度0是全开还是全闭取决于夹爪型号2F-85是0全开、255全闭但实际用的时候最好试一下。3.4 数据记录的后处理记录完的CSV用Python的pandas读进来分析import pandas as pd import matplotlib.pyplot as plt df pd.read_csv(robot_data.csv) df[time_rel] df[timestamp] - df[timestamp].iloc[0] fig, axes plt.subplots(3, 1, figsize(12, 8)) axes[0].plot(df[time_rel], df[[fq{i} for i in range(6)]]) axes[0].set_ylabel(Joint Angle (rad)) axes[1].plot(df[time_rel], df[[ftcp{i} for i in range(3)]]) axes[1].set_ylabel(TCP Position (m)) axes[2].plot(df[time_rel], df[[fcurrent{i} for i in range(6)]]) axes[2].set_ylabel(Joint Current (A)) axes[2].set_xlabel(Time (s)) plt.tight_layout() plt.show()这样能直观看到运动过程中关节角度、TCP位置、电流的变化。如果发现某个关节电流突然增大可能是碰撞或者负载过大。4. 常见问题与排查技巧实录4.1 连接与通信类问题问题1RTDE连接不上报Timeout。排查顺序先ping机器人IP通不通。不通就是网络问题检查网线、IP配置、防火墙。通了但RTDE连不上检查UR的RTDE服务是否开启。在UR的示教器上设置-RTDE确认RTDE端口是30004并且没有其他客户端占用。UR的RTDE同时只允许一个控制客户端和一个接收客户端如果你开了两个Python脚本第二个会连不上。问题2Modbus读写失败返回异常码。先确认Modbus TCP端口502是否开放。UR的Modbus TCP默认是开的但如果你在UR的IO设置里禁用了就得打开。然后确认寄存器地址对不对UR的Modbus地址映射可能跟Robotiq手册不一样。用modbus poll工具先手动读一下确认能读到数据再写代码。问题3夹爪不动作状态字一直是0。大概率是没激活。写动作请求寄存器为1之后等500ms再读状态。如果gSTA还是0检查夹爪的电源和通信线。Robotiq的RS485线序是A对A、B对B别接反了。4.2 运动控制类问题问题4moveL报错说目标位姿不可达。moveL是直线运动如果起点和终点之间经过奇异点或者超出工作空间就会报错。解决办法先用moveJ运动到一个中间点再用moveL。或者用moveL的异步版本自己插补。问题5运动过程中机械臂抖动。可能是速度或加速度设太大了。UR的默认加速度是1.4 rad/s²你设0.3是合理的。但如果负载重心偏了也会抖。检查TCP的负载设置在UR示教器上配好负载质量和重心。问题6stopScript之后机械臂没停。stopScript是停止URScript程序但如果你用的是RTDEControlInterface的moveJ它底层是发URScript的。stopScript之后当前运动会被打断但机械臂会因为惯性继续动一点。要急停的话用rtde_c.stopScript()之后再加rtde_c.servoStop()。4.3 数据记录类问题问题7记录的数据时间戳不均匀。Python的time.sleep精度不够导致记录频率波动。解决办法用time.perf_counter()做忙等待或者用C的std::this_thread::sleep_until。另外RTDE本身的数据更新是125Hz你记录频率高于125Hz也没用读到的还是旧值。问题8CSV文件太大打开慢。125Hz记录10分钟6个关节6个TCP6个速度6个电流1个时间戳25列125601075000行大概几MB不算大。但如果记录几小时就上百MB了。解决办法用二进制格式或者只记录你需要的列或者降低频率。问题9记录线程和控制线程冲突。如果记录线程在读RTDEReceiveInterface控制线程在发moveJ两个线程同时操作同一个RTDE连接可能会出问题。解决办法RTDEReceiveInterface和RTDEControlInterface是两个独立的连接互不干扰。但如果你在记录线程里也调用了控制接口的方法那就得加锁。4.4 常见问题速查表问题现象可能原因排查方法解决措施RTDE连接超时网络不通/RTDE服务未开ping机器人IP检查示教器RTDE设置修复网络开启RTDE服务Modbus读写失败端口未开/地址错误用Modbus Poll手动测试开启Modbus TCP核对寄存器地址夹爪不动作未激活/通信线接反读状态寄存器检查RS485线序重新激活调整线序moveL报错奇异点/超出工作空间检查目标位姿是否可达用moveJ过渡或调整目标点机械臂抖动速度过大/负载配置错误降低速度检查负载设置调整速度加速度重新配负载数据时间戳不均匀sleep精度不够检查记录频率波动用perf_counter或C sleep_untilCSV文件过大记录时间长/列太多查看文件大小用二进制格式减少列降频独家避坑技巧UR的RTDE在机器人重启后IP可能会变回默认的192.168.0.1。如果你设了静态IP重启后可能失效。建议在UR的示教器里把网络设置成静态IP并且记下来。另外Robotiq夹爪的Modbus地址在不同固件版本可能略有差异遇到读不到的情况先查Robotiq的官方手册确认地址。5. 性能优化与扩展思路5.1 提高记录频率的几种手段125Hz对大部分应用够了但如果你要做力控或者视觉伺服可能需要500Hz甚至1kHz。这时候Python的GIL和sleep精度就是瓶颈。方案一用C写记录程序Python只做上层逻辑。C的std::this_thread::sleep_until可以做到微秒级精度而且没有GIL。方案二用RTDE的底层接口直接订阅数据包。ur_rtde的RTDEReceiveInterface已经封装了但你可以用它的getDataPackage()方法一次性拿所有数据减少函数调用开销。方案三用实时内核。Linux下打PREEMPT_RT补丁把记录线程设成实时优先级。这个对系统配置要求高但效果最好。5.2 数据记录的扩展加入夹爪和IO上面的例子只记了关节和TCP数据。实际项目中夹爪的位置和电流也很重要。如果夹爪走Modbus可以在记录线程里加一个Modbus读操作把夹爪的位置反馈和电流反馈也记下来。但Modbus读有延迟可能几毫秒会影响记录频率。解决办法把夹爪数据单独记一个文件或者降低夹爪数据的记录频率比如每10个RTDE周期读一次夹爪。IO状态可以用rtde_r.getActualDigitalInputBits()和getActualDigitalOutputBits()返回的是32位整数每一位对应一个IO。5.3 从记录到回放数据的使用记录的数据可以用来做很多事运动复现把记录的关节轨迹导出来用moveJ或者servoJ回放。碰撞检测分析电流突变判断是否发生碰撞。参数调优对比不同速度加速度下的电流和振动找到最优参数。机器学习把关节角度、TCP位姿、夹爪状态作为输入训练抓取策略。回放的时候注意记录的关节角度是实际值有噪声。直接回放可能会抖。可以先做低通滤波或者用样条插值平滑。5.4 多机器人协同的考虑如果你有多台UR每台都要记录那可以每台跑一个记录进程用一个中央服务收集数据。或者用ROS把UR和Robotiq都接进ROS用rosbag记录。但ROS的实时性不如ur_rtde直接而且多了一层网络通信。我个人经验是单台UR用ur_rtde直接记最省事。多台的话每台一个工控机各自记录最后汇总。别想着用一个进程控制多台RTDE连接是点对点的多台就是多个连接管理起来麻烦。最后分享一个小技巧记录的时候在文件名里加上时间戳和任务名比如grasp_20250101_120000.csv。不然跑几次之后你根本分不清哪个文件对应哪个任务。另外记录开始前先写一行注释把当时的运动参数、夹爪参数记下来后面分析的时候省事。这个项目后续还可以这样扩展把记录的数据实时可视化用matplotlib的animation或者pyqtgraph边记边看曲线。或者加一个Web界面远程监控机械臂状态。再或者把数据传到数据库做长期趋势分析。这些就看你具体需求了。

相关新闻

Codex 桌面版接入国内大模型系列一:EchoBird 与 GLM 的 TaoToken 配置实践

Codex 桌面版接入国内大模型系列一:EchoBird 与 GLM 的 TaoToken 配置实践

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

2026/10/17 23:22:22 阅读更多 →
MLA、稀疏注意力、MoE top-6路由如何省显存:DeepSeek-V4-Flash 2.4bit 架构原理完全剖析

MLA、稀疏注意力、MoE top-6路由如何省显存:DeepSeek-V4-Flash 2.4bit 架构原理完全剖析

【免费下载链接】DeepSeek-V4-Flash-0731-2.4bit-mixed 项目地址: https://ai.gitcode.com/hf_mirrors/mlx-community/DeepSeek-V4-Flash-0731-2.4bit-mixed 点击查看 免费下载 DeepSeek-V4-Flash-0731-2.4bit-mixed 是一个面向 Apple Silicon 的 MLX 混合精度量化…

2026/10/17 23:22:22 阅读更多 →
如何微调InternVL3-2B-AWQ:SWIFT与XTuner定制视觉数据完整实战

如何微调InternVL3-2B-AWQ:SWIFT与XTuner定制视觉数据完整实战

【免费下载链接】InternVL3-2B-AWQ 项目地址: https://ai.gitcode.com/OpenGVLab/InternVL3-2B-AWQ 点击查看 免费下载 InternVL3-2B-AWQ 微调,是把通用视觉语言模型"改造"成行业专属模型的关键一步。InternVL3-2B-AWQ 是 OpenGVLab 出品的 I…

2026/10/17 23:22:22 阅读更多 →

最新新闻

AI指数报告:工程师的技术决策校准器

AI指数报告:工程师的技术决策校准器

简介:本资源为斯坦福大学HAI研究所发布的《2025年人工智能指数报告》官方英文原版PDF,是全球最具权威性的AI发展年度评估报告第八版,面向政策制定者、AI研究人员、企业技术高管、科技记者及关注AI社会影响的公众读者。报告以数据驱动方式系统…

2026/10/18 0:07:01 阅读更多 →
MySQL 8.0报错Unknown system variable ‘query_cache_size‘的排查与配置迁移指南

MySQL 8.0报错Unknown system variable ‘query_cache_size‘的排查与配置迁移指南

我遇到过很多次这种报错,每次帮别人排查的时候,第一反应基本都是:这哥们儿又升级MySQL版本了,而且没清理老配置文件。Unknown system variable query_cache_size这个问题,说白了就是MySQL 8.0版本把查询缓存&#xff0…

2026/10/18 0:06:00 阅读更多 →
Oracle 12c在线redo日志误删后的故障诊断与恢复实战指南

Oracle 12c在线redo日志误删后的故障诊断与恢复实战指南

redo在线日志被误删,这大概是在Oracle 12c数据库运维里最能让人瞬间清醒的事故之一。我这些年处理过的类似case不算少,最常见的原因是DBA在清理/u01这类目录下的历史日志文件时,把redo01.log、redo02.log当成了普通日志顺手删掉。接下来剧情几…

2026/10/18 0:06:00 阅读更多 →
Windows下JDK与Maven安装配置实战:环境变量与版本管理全攻略

Windows下JDK与Maven安装配置实战:环境变量与版本管理全攻略

JDK 和 Maven 在 Windows 下的安装和配置,算是 Java 开发里最基础但也最容易出幺蛾子的一环。不少新手甚至工作一两年的同事,都可能在环境变量、版本兼容这些地方卡过壳。这篇文章就把我多年来在 Windows 上折腾 JDK 和 Maven 的经验完整梳理一遍&#x…

2026/10/18 0:06:00 阅读更多 →
Win10+VS2015下OpenCV3.3.0扩展contrib编译完整指南

Win10+VS2015下OpenCV3.3.0扩展contrib编译完整指南

如果你最近在一个老项目里接手了OpenCV 3.3.0,大概率也绕不开这个标题本身:Win10 VS2015 OpenCV3.3.0下扩展OpenCV_contrib3.3.0。OpenCV 3.3.0官方只提供标准模块的预编译包,SIFT、SURF、face、aruco这些扩展模块都放在contrib仓库里&…

2026/10/18 0:06:00 阅读更多 →
前端安全实战指南:XSS、CSRF、点击劫持与供应链攻击防御

前端安全实战指南:XSS、CSRF、点击劫持与供应链攻击防御

1. 前端安全到底在防什么前端安全这个词,刚入行的同学听起来容易觉得虚。页面能跑、按钮能点、接口能通,不就完了吗?但真正做过线上项目的人都知道,前端是离用户最近的一层,也是最容易被当成突破口的一层。用户输入的数…

2026/10/18 0:06:00 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式: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/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/16 14:23:36 阅读更多 →