尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
ROS自主移动机器人导航系统实战:SLAM建图、IMU融合与代价地图调参
简介这是一套面向ROS机器人开发初学者与进阶者的自主移动机器人导航系统实践资源围绕室内外场景的路径规划与避障需求整合了Gazebo仿真与实体小车控制两条验证路径。包内共21个文件以yaml参数配置、launch启动脚本、rviz可视化配置为主辅以地图pgm、说明文档与md笔记压缩包约66KB结构紧凑便于快速部署。系统集成激光雷达SLAM建图、IMU姿态融合与摄像头视觉感知并采用全局与局部代价结合的规划策略兼顾路径最优与环境动态响应。读者可借助仿真环境在无硬件条件下完成导航算法调试再迁移至实体小车验证速度与转向控制同时参考地图与rviz配置理解建图定位流程。目前已有197人学习下载适合希望系统掌握ROS导航栈、SLAM与多传感器融合的开发者对照实践。1. 从一堆散装模块到一台会自己走路的机器人室内走廊里放一台差速小车让它自己从工位跑到茶水间再绕回来这件事听起来简单真正动手才会发现坑比想象中多。激光雷达给的点云要配准成地图IMU 的角速度积分几分钟就漂到姥姥家摄像头识别到的障碍物得换算到全局坐标系才有意义而全局规划器算出来的路径如果没经过局部代价地图的二次修正小车大概率会贴着桌角蹭过去。这套基于 ROS 的自主移动机器人导航系统本质上就是把 SLAM 建图、IMU 姿态融合、视觉感知、全局与局部代价地图这几块拼成一个闭环先在 Gazebo 仿真环境里跑通再部署到实体小车上验证。它适合已经写过几个 ROS 节点、但还没把整条导航链路串起来的开发者也适合想把仿真和实车对齐的团队。下面按我实际搭这套系统的顺序把每一步的选择理由、参数含义和翻车点讲清楚。2. 仿真环境搭建Gazebo 里先把代价地图跑通2.1 为什么先在 Gazebo 里做而不是直接上实车实车调试最怕的是「不知道是算法错了还是硬件坏了」。Gazebo 的价值在于它把激光雷达、IMU、摄像头、轮式里程计全部虚拟化每个传感器的噪声模型、更新频率、坐标系变换都可以精确控制。我一般会先在仿真里把move_base的全局和局部代价地图调到能稳定绕障再把这套参数原样搬到实车上只改传感器话题名和 TF 外参。这样实车出问题时至少能确定算法链路本身是通的。仿真环境的核心是 URDF/Xacro 描述文件它定义了小车的连杆、关节、碰撞体以及每个传感器相对于base_link的安装位置。激光雷达装在车顶中心IMU 装在底盘几何中心摄像头朝前略微下倾。这些外参在仿真里是精确值到了实车就得靠卷尺和标定板重新量。2.2 用 Xacro 描述小车并挂载三类传感器下面是一个简化版的差速小车 Xacro 片段包含底盘、两个驱动轮、一个万向轮以及激光雷达和 IMU 的挂载。实际项目里摄像头会用gazebo_ros_camera插件单独配置。?xml version1.0? robot namediff_bot xmlns:xacrohttp://www.ros.org/wiki/xacro !-- 底盘主体圆柱形半径0.2m高0.15m -- link namebase_link visual geometrycylinder radius0.2 length0.15//geometry material namegraycolor rgba0.5 0.5 0.5 1//material /visual collision geometrycylinder radius0.2 length0.15//geometry /collision inertial mass value8.0/ inertia ixx0.1 ixy0 ixz0 iyy0.1 iyz0 izz0.15/ /inertial /link !-- 左驱动轮连续关节绕Y轴旋转 -- joint nameleft_wheel_joint typecontinuous parent linkbase_link/ child linkleft_wheel/ origin xyz0 0.22 -0.05 rpy0 0 0/ axis xyz0 1 0/ /joint link nameleft_wheel visual geometrycylinder radius0.05 length0.03//geometry /visual collision geometrycylinder radius0.05 length0.03//geometry /collision inertialmass value0.5/inertia ixx0.001 iyy0.001 izz0.001//inertial /link !-- 激光雷达固定在车顶中心扫描平面略高于底盘 -- joint namelidar_joint typefixed parent linkbase_link/ child linklaser_frame/ origin xyz0 0 0.12 rpy0 0 0/ /joint link namelaser_frame visualgeometrycylinder radius0.03 length0.04//geometry/visual inertialmass value0.1/inertia ixx0.0001 iyy0.0001 izz0.0001//inertial /link !-- IMU装在底盘几何中心方向与base_link一致 -- joint nameimu_joint typefixed parent linkbase_link/ child linkimu_frame/ origin xyz0 0 0.02 rpy0 0 0/ /joint link nameimu_frame/ /robot这段描述里最关键的是origin的xyz和rpy。激光雷达的z0.12决定了它扫描平面离地高度如果设得太低地面反射会引入大量噪点IMU 的z0.02尽量贴近底盘中心减少旋转时的离心加速度干扰。轮子的y±0.22是轮距的一半这个值直接参与差速运动学解算量错了里程计会系统性偏航。2.3 启动仿真并验证话题与 TF 树写完 Xacro 后用gazebo_ros的spawn_model把机器人加载进空世界同时启动robot_state_publisher发布 TF。下面这条 launch 文件把仿真、状态发布、传感器插件一次性拉起来。launch !-- 加载Gazebo空世界关闭默认地面反射噪声 -- include file$(find gazebo_ros)/launch/empty_world.launch arg nameworld_name value$(find diff_bot)/worlds/indoor.world/ arg namepaused valuefalse/ arg nameuse_sim_time valuetrue/ /include !-- 把Xacro解析成URDF并推送到参数服务器 -- param namerobot_description command$(find xacro)/xacro $(find diff_bot)/urdf/diff_bot.xacro/ !-- 在Gazebo中生成机器人初始位姿在原点 -- node namespawn_urdf pkggazebo_ros typespawn_model args-param robot_description -urdf -model diff_bot -x 0 -y 0 -z 0.1/ !-- 发布关节状态和TF变换 -- node namerobot_state_publisher pkgrobot_state_publisher typerobot_state_publisher/ node namejoint_state_publisher pkgjoint_state_publisher typejoint_state_publisher/ /launch启动后先别急着跑导航用rostopic list确认/scan、/imu/data、/camera/image_raw三个话题都在再用rosrun tf view_frames生成 TF 树 PDF检查base_link到laser_frame、imu_frame的变换是否存在。我见过最常见的翻车是激光雷达的 TF 没发出来move_base直接报「Timed out waiting for transform」这时候回头查 Xacro 里laser_frame的 joint 是不是写成了floating而不是fixed。3. 激光雷达 SLAM 建图从点云到可导航栅格地图3.1 选 gmapping 还是 cartographer室内小场景用gmapping就够了它基于粒子滤波计算量小在差速小车上跑起来很稳。cartographer更适合大场景和回环多的环境但它对 IMU 和里程计的融合要求更高调参也更玄学。我一般先在gmapping上把地图建出来确认激光雷达安装角度和扫描范围没问题再考虑要不要换cartographer做优化。gmapping的核心参数是粒子数和地图分辨率。粒子数太少机器人快速转向时地图会糊粒子数太多CPU 直接跑满。分辨率决定了栅格的精细程度0.05m 是室内导航的常用值再细对路径规划帮助不大反而让代价地图膨胀变慢。3.2 gmapping 关键参数配置与建图流程下面是一份gmapping的 launch 配置重点看delta、particles、linearUpdate和angularUpdate四个参数。launch node pkggmapping typeslam_gmapping nameslam_gmapping outputscreen !-- 激光雷达话题名与仿真/实车保持一致 -- remap fromscan to/scan/ !-- 地图分辨率0.05m/栅格室内导航够用 -- param namedelta value0.05/ !-- 粒子数30个小场景足够大场景可加到50 -- param nameparticles value30/ !-- 里程计噪声模型差速小车常用值 -- param namesrr value0.1/ param namesrt value0.2/ param namestr value0.1/ param namestt value0.2/ !-- 更新阈值移动0.3m或转0.3rad才做一次地图更新 -- param namelinearUpdate value0.3/ param nameangularUpdate value0.3/ !-- 激光雷达有效距离和角度范围 -- param namemaxRange value8.0/ param nameminRange value0.12/ param namemaxUrange value7.5/ /node /launchlinearUpdate和angularUpdate设得太小机器人原地抖动也会触发地图更新地图边缘会出现重影设得太大快速转弯时地图来不及更新墙角会缺一块。0.3 是我在轮距 0.44m 的小车上试出来的平衡点。maxUrange比maxRange略小是为了避开激光雷达最远端的低置信度数据。建图时用键盘遥控小车绕场景走一圈速度控制在 0.2m/s 以内转弯时慢一点。走完后用rosrun map_server map_saver -f my_map保存地图会得到my_map.pgm和my_map.yaml两个文件。打开 pgm 检查一下如果墙壁边缘呈锯齿状说明里程计噪声参数偏大把srr和str调小再重建。3.3 地图保存后必须检查的三个地方第一看my_map.yaml里的resolution是否和delta一致不一致会导致导航时坐标缩放错误。第二看origin的yaw是否为 0如果建图起点不是正方向后续全局路径会整体旋转。第三用图像工具打开 pgm确认没有大面积灰色未知区域灰色区域太多说明激光雷达扫描覆盖不够需要补走几圈。4. IMU 姿态融合与视觉感知让小车知道自己歪没歪、前面有没有东西4.1 为什么单靠轮式里程计不够差速小车的轮式里程计在直行时还算准一旦频繁转向轮子打滑和地面摩擦差异会让航向角快速漂移。IMU 的陀螺仪能提供短时间高精度的角速度但积分几分钟后零偏会累积成几十度的误差。常见做法是用robot_localization包里的扩展卡尔曼滤波把轮式里程计和 IMU 融合成一条平滑的odom到base_link的变换。融合的关键是配置ekf_localization_node的输入话题和协方差矩阵。轮式里程计提供x、y、yaw和对应速度IMU 提供yaw角速度和linear_acceleration。如果 IMU 没有磁力计就不要让它提供绝对yaw只取角速度做积分修正。4.2 robot_localization 融合配置与参数含义下面是一份 EKF 配置文件只融合轮式里程计和 IMU 的角速度不启用 IMU 的绝对朝向。# ekf.yaml ekf_filter_node: ros__parameters: frequency: 30.0 # 滤波输出频率与传感器更新率匹配 sensor_timeout: 0.1 # 传感器超时超过则不再等待 two_d_mode: true # 二维模式忽略z轴和俯仰横滚 # 里程计输入x, y, yaw 及对应速度 odom0: /wheel_odom odom0_config: [true, true, false, false, false, true, true, true, false, false, false, true, false, false, false] odom0_differential: false odom0_relative: false # IMU输入只取yaw角速度不取绝对朝向 imu0: /imu/data imu0_config: [false, false, false, false, false, false, false, false, false, false, false, true, false, false, false] imu0_differential: false imu0_relative: true # 输出到odom到base_link的变换 publish_tf: true map_frame: map odom_frame: odom base_link_frame: base_link world_frame: odomodom0_config里前三个true表示使用里程计的x、y、yaw中间三个true表示使用对应的线速度和角速度。imu0_config里只有角速度的true绝对朝向全部false这是为了避免没有磁力计时 IMU 的yaw缓慢漂移污染融合结果。two_d_mode在室内平地场景必须开否则 IMU 的俯仰和横滚噪声会耦合进平面运动。4.3 摄像头视觉感知的最小可用方案视觉感知不需要一上来就做深度学习先用颜色阈值和轮廓检测把红色锥桶或绿色地标找出来换算成base_link坐标系下的障碍物点插入局部代价地图。下面这段 Python 代码用 OpenCV 做红色区域检测并发布障碍物点。#!/usr/bin/env python3 import rospy import cv2 import numpy as np from sensor_msgs.msg import Image from geometry_msgs.msg import PointStamped from cv_bridge import CvBridge class RedObstacleDetector: def __init__(self): self.bridge CvBridge() # 订阅摄像头图像队列长度1避免延迟累积 self.sub rospy.Subscriber(/camera/image_raw, Image, self.callback) # 发布障碍物在base_link下的坐标 self.pub rospy.Publisher(/visual_obstacle, PointStamped, queue_size10) # 摄像头内参焦距和光心实车需标定后替换 self.fx, self.fy 320.0, 320.0 self.cx, self.cy 320.0, 240.0 def callback(self, msg): frame self.bridge.imgmsg_to_cv2(msg, bgr8) hsv cv2.cvtColor(frame, cv2.COLOR_BGR2HSV) # 红色在HSV中跨越0和180分两段提取 mask1 cv2.inRange(hsv, (0, 100, 100), (10, 255, 255)) mask2 cv2.inRange(hsv, (170, 100, 100), (180, 255, 255)) mask mask1 | mask2 contours, _ cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) if not contours: return # 取最大轮廓过滤噪点 c max(contours, keycv2.contourArea) if cv2.contourArea(c) 500: return M cv2.moments(c) u M[m10] / M[m00] v M[m01] / M[m00] # 假设障碍物贴地用相似三角形估算距离 # 实际项目中需要结合相机安装高度和俯仰角做完整投影 depth 1.0 # 占位实车用测距或已知尺寸反推 x (u - self.cx) * depth / self.fx y (v - self.cy) * depth / self.fy pt PointStamped() pt.header.frame_id base_link pt.header.stamp rospy.Time.now() pt.point.x depth pt.point.y -x pt.point.z 0.0 self.pub.publish(pt) if __name__ __main__: rospy.init_node(red_obstacle_detector) RedObstacleDetector() rospy.spin()这段代码里depth是占位值实际项目中要么用双目或深度相机直接拿深度要么假设障碍物高度已知用像素高度反推距离。pt.point.y -x是因为图像坐标系u向右而base_link的y向左需要取反。发布出来的点会被局部代价地图的obstacle_layer订阅作为动态障碍物插入。5. 全局与局部代价地图路径规划的参数怎么调才不撞墙5.1 全局代价地图和局部代价地图的分工全局代价地图基于map坐标系用静态地图层和膨胀层生成负责给全局规划器提供从起点到终点的粗略路径。局部代价地图基于odom坐标系除了静态层和膨胀层还叠加了激光雷达实时障碍物层和视觉障碍物层负责给局部规划器提供避障所需的实时信息。两者共用一套膨胀参数但局部地图的更新频率更高。全局规划器常用global_planner或navfn局部规划器常用teb_local_planner或dwa_local_planner。teb在窄通道里表现更好但参数多、调参玄学dwa参数少、稳定适合先跑通。我一般先用dwa把整条链路跑顺再换teb优化窄道通过性。5.2 costmap_common 参数与膨胀半径的取舍下面是一份costmap_common_params.yaml定义了障碍物层、膨胀层和机器人 footprint。# costmap_common_params.yaml obstacle_range: 3.0 # 激光雷达障碍物插入的最大距离 raytrace_range: 3.5 # 清除空闲空间的最大距离 footprint: [[-0.25, -0.22], [-0.25, 0.22], [0.25, 0.22], [0.25, -0.22]] # footprint是矩形比圆形更贴合差速小车减少不必要的膨胀 obstacle_layer: enabled: true combination_method: 1 # 取最大值避免障碍物被覆盖 observation_sources: scan visual scan: topic: /scan data_type: LaserScan marking: true # 允许标记障碍物 clearing: true # 允许清除空闲区域 max_obstacle_height: 2.0 min_obstacle_height: 0.0 visual: topic: /visual_obstacle data_type: PointCloud2 marking: true clearing: false # 视觉障碍物只标记不清除避免误删 inflation_layer: enabled: true cost_scaling_factor: 5.0 # 代价衰减系数越大衰减越快 inflation_radius: 0.55 # 膨胀半径约为机器人半宽0.1m安全余量inflation_radius是最容易翻车的参数。设得太小小车会贴着墙走稍微有点定位误差就撞上设得太大窄通道直接变成不可通行。0.55m 是轮距 0.44m 小车的常用值实际要按footprint的最大外接圆半径加 0.1m 安全余量来算。cost_scaling_factor控制代价从障碍物向外衰减的速度5.0 表示衰减较快路径倾向于远离障碍物但不会过度绕行。5.3 局部规划器 dwa 的关键参数与速度限制下面是一份dwa_local_planner_params.yaml重点看max_vel_x、min_vel_x、acc_lim_x和xy_goal_tolerance。# dwa_local_planner_params.yaml DWAPlannerROS: max_vel_x: 0.4 # 最大前进速度室内建议不超过0.5 min_vel_x: -0.1 # 允许小幅后退用于脱困 max_vel_y: 0.0 # 差速小车无横向速度 max_vel_theta: 1.0 # 最大角速度 min_vel_theta: 0.2 acc_lim_x: 0.5 # 线加速度限制防止急冲 acc_lim_theta: 1.0 # 角加速度限制防止原地猛转 xy_goal_tolerance: 0.15 # 到达目标点的位置容差 yaw_goal_tolerance: 0.1 # 到达目标点的朝向容差 latch_xy_goal_tolerance: true # 到达后锁定容差避免反复调整 sim_time: 1.5 # 前向仿真时间太短避障不及太长反应迟钝 sim_granularity: 0.05 # 仿真步长 vx_samples: 10 # 线速度采样数 vtheta_samples: 20 # 角速度采样数 path_distance_bias: 32.0 # 路径跟随权重 goal_distance_bias: 24.0 # 目标接近权重 occdist_scale: 0.02 # 障碍物代价权重太大会不敢走sim_time设 1.5 秒意味着规划器会预测未来 1.5 秒的运动轨迹如果小车速度是 0.4m/s相当于看前方 0.6m。在狭窄走廊里这个值够用但在开阔区域可以加到 2.0 秒让路径更平滑。occdist_scale是避障激进程度的开关0.02 表示障碍物代价权重较低小车会贴着障碍物走但不会撞如果发现小车在障碍物前犹豫不决把这个值调到 0.05 以上。5.4 全局规划器与局部规划器的衔接验证启动move_base后在 RViz 里先给一个 2D Nav Goal观察全局路径是否从起点连到终点再观察局部路径是否贴合全局路径且避开实时障碍物。如果全局路径正常但小车不动检查局部规划器是否报「No valid trajectories」这通常是inflation_radius太大导致所有采样轨迹都撞上膨胀层。如果小车走一半停下检查xy_goal_tolerance是否设得太小定位误差导致永远到不了目标点。6. 避坑与排查仿真到实车最容易翻车的五个地方6.1 现象仿真里跑得好好的实车一启动就原地转圈原因通常是 IMU 的安装方向与base_link不一致。仿真里 IMU 的rpy是精确的 0实车装上去可能有几度偏差导致融合后的航向角持续偏转。解决方法是先用rostopic echo /imu/data看静止时的角速度输出如果z轴不为零在 EKF 配置里加一个静态变换节点或者直接在 IMU 驱动里做零偏校准。6.2 现象激光雷达建图时墙壁出现双层重影原因是轮式里程计的srr和str噪声参数与实际打滑程度不匹配。仿真里轮子不打滑这两个值可以设很小实车在地毯上转向时打滑严重需要把srr调到 0.2 以上。另一个可能是激光雷达的 TF 外参z值不准扫描平面倾斜导致同一面墙在不同角度下测距不一致。用水平仪确认雷达安装面水平再重新量z值。6.3 现象局部代价地图里视觉障碍物一闪一闪原因是视觉检测的发布频率和局部代价地图的更新频率不匹配。摄像头 30fps 发布代价地图 5Hz 更新中间会丢帧。解决方法是加一个costmap_converter或者简单的缓存节点把视觉障碍物保持 0.5 秒再发布避免瞬时漏检导致障碍物消失。另外visual层的clearing要设为false否则代价地图会在没有新视觉数据时把障碍物清掉。6.4 现象小车在窄通道口反复前进后退进不去这是dwa的经典问题sim_time太短导致规划器看不到通道内部的可行路径或者inflation_radius把通道两侧的膨胀层连成一片通道直接变成高代价区域。先把inflation_radius降到刚好不撞墙的值再把sim_time加到 2.0 秒同时把path_distance_bias调高到 40 以上让小车更倾向于跟随全局路径而不是自己找路。6.5 现象实车导航时突然报 TF 超时小车急停原因是某个传感器的 TF 发布频率掉下去了常见于 USB 摄像头带宽不足或激光雷达数据量过大导致 CPU 卡顿。用rostopic hz /scan和rostopic hz /imu/data检查实际频率如果低于配置值先排查 USB 线和供电。另一个可能是robot_state_publisher的publish_frequency设得太低默认 50Hz 一般够用但如果 CPU 负载高可以降到 30Hz 减少压力。7. 从仿真到实车的参数迁移技巧把仿真参数搬到实车最忌讳的是整套复制。我一般会按「传感器层 → 融合层 → 规划层」的顺序逐层迁移每层迁移后单独验证。传感器层先确认话题名、频率、量程一致融合层先关掉 IMU只用轮式里程计跑一圈确认里程计方向正确再打开 IMU 看航向角是否平滑规划层先把速度限制降到仿真值的一半跑通后再逐步提速。下面这张表是我在迁移时必查的参数对照左边是仿真值右边是实车初始值实车值通常更保守。参数仿真值实车初始值调整理由max_vel_x0.40.2实车定位误差大先慢跑inflation_radius0.550.65实车 footprint 有装配误差sim_time1.52.0实车传感器延迟更大xy_goal_tolerance0.150.25实车定位精度不如仿真particles3050实车里程计噪声更大迁移完成后用rosbag record把/scan、/imu/data、/odom、/cmd_vel全部录下来回放分析。我习惯在实车跑完后回放 bag看cmd_vel的角速度指令和 IMU 的实际角速度是否跟得上如果指令发了但实际转得慢说明acc_lim_theta设小了或者电机扭矩不够。这套流程走下来仿真到实车的差距基本能控制在可接受范围内。希望帮到你。本文还有配套的精品资源点击获取
RELATED

相关推荐

阿里云人物动漫化接口详解:从原理到批量头像生成实践

阿里云人物动漫化接口详解:从原理到批量头像生成实践

把一张普通的生活照变成日漫风格头像,是这两年社交平台上特别流行的玩法。以前大家只能在特定App里手动调,风格就那么几种,处理一张图还得等上好几分钟。如果想批量处理几十上百张照片,或者把这个能力集成到自己的网站、小程序里&…

📅 2026/10/22 19:20:02
基于YOLOV8的细胞分裂检测系统:从数据标注到Web部署全流程

基于YOLOV8的细胞分裂检测系统:从数据标注到Web部署全流程

做了这么久的视觉检测项目,老实说“细胞分裂检测”这几个字第一次出现时,我还以为就是把常规目标检测算法换了个数据集跑一跑。等真正拿到HE染色病理切片图之后,才发现事情没那么简单——细胞分裂象个头小、分布密、形态又千奇百怪&#xff0…

📅 2026/10/22 19:14:53
基于YOLO的牛行为检测识别系统:从数据到部署实战

基于YOLO的牛行为检测识别系统:从数据到部署实战

每年到了毕业设计定题的时候,总有人来问我到底选什么方向最稳妥。如果只让我推荐一个既好出成果、又有实际应用价值、还能在答辩时撑住场面的题目,我会毫不犹豫地说:基于YOLO的行为检测项目。今天我要拆解的这套“基于yolov8/yolov5/yolo11的…

📅 2026/10/22 19:14:53
MORE NEWS

更多资讯

📰

【Pytorch】Anaconda: 新建环境出现No module named ‘pip._internal.main‘

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

📰

【Tensorflow实战系列】Tensorflow:动态库的使用(头文件提取,Makefile链接动态库)

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

📰

PJ85718DM与PIC18F85J10协同的HVAC远程温度采集方案

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

📰

【CUDA】CUDA: (八) 使用 CUDA C/C++ 加速计算的基础 (NVIDIA 课程 Part one)

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

📰

【Pytorch】Pytorch: Automatic Differentitation (二)

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

📰

自学还是课程?四个关键变量决定你的最佳学习路径

前几天收到一条留言,只有五个字:自学vs C。没有背景,没有上下文,我先是一愣——C是什么?C语言?Class?Course?后来跟对方聊了几句才明白,他想问的是一个几乎所有学习者都绕…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬