第十七讲、Isaaclab中使用操作空间控制器
0 前言
官方教程:https://isaac-sim.github.io/IsaacLab/main/source/tutorials/05_controllers/run_osc.html
Isaacsim+Isaaclab安装:https://blog.csdn.net/m0_47719040/article/details/146389391?spm=1001.2014.3001.5502
有时候,仅使用differential IK控制器来控制机器人末端执行器的姿态是不够的。比如,我们可能希望在任务空间中强制执行非常特定的姿态跟踪动态误差,使用关节力/扭矩指令来驱动机器人,或者在特定方向上施加接触力,同时控制其他方向的运动(例如,用布擦拭桌面)。在这类任务中,可以使用空间控制器(OSC)。
本教程中,我们将学习如何使用一个OSC控制机器人。我们将使用controllers.OperationalSpaceController类施加一个垂直于倾斜墙面的恒定力,同时在所有其他方向上跟踪所需的末端执行器姿态。
教程对应的脚本为run_osc.py在scripts/tutorials/05_controllers目录下。
运行该程序:
- 进入安装 isaac lab 时创建的conda虚拟环境
- 在该环境下进入 isaac sim文件夹中运行
source setup_conda_env.sh - 终端中输入
./isaaclab.sh -p scripts/tutorials/05_controllers/run_osc.py --num_envs 128运行你的代码。

1 创建操作空间控制器
OperationalSpaceController类计算机器人在任务空间中同时进行运动和力控制的联合努力/扭矩。
官方文档:https://isaac-sim.github.io/IsaacLab/main/source/tutorials/05_controllers/run_osc.html
任务坐标系定义:
控制器的任务空间参考坐标系可自由指定(默认机器人基座坐标系)。但是,在某些情况下,定义相对于不同坐标系的目标坐标可能更容易。在这种情况下,应在set_command方法的current_task_frame_pose_b参数中提供此任务参考系相对于机器人基座坐标系的姿态。
场景示例:在墙面接触任务中,定义与墙面平行的坐标系(如Z轴垂直墙面),此时:
- 力控制:只需在Z轴方向施加接触力。
- 运动控制:在x/y平面调整位置,绕z轴旋转调整姿态。
# 假设已定义墙面坐标系到基座的变换矩阵 T_wall_to_base
controller.set_command(target_pose=target_in_wall_frame, current_task_frame_pose_b=T_wall_to_base
)
控制类型与轴向选择:
1、目标类型(target_types)
- “pose_abs”:绝对位姿控制(基座坐标系)
- “pose_rel”:相对当前末端位姿的增量控制。
- “wrench_abs”:绝对力/力矩控制。
还可以组合选择
# 同时进行位姿和力控制
cfg.target_types = ["pose_abs", "wrench_abs"]
2、控制轴向(motion_control_axes_task 和 force_control_axes_task)
- 两个参数为6维二进制列表(0/1),分别对应位置(XYZ)和旋转(RxRyRz)。
- 同一轴向不能同时激活运动和力控制(互补)。
# 在墙面坐标系中:
# - 运动控制XY平面位置和绕Z轴旋转(索引0,1,5)
# - 力控制Z轴方向(索引2)
cfg.motion_control_axes_task = [1, 1, 0, 0, 0, 1] # X, Y, _, _, _, Rz
cfg.force_control_axes_task = [0, 0, 1, 0, 0, 0] # Z方向力控制
运动控制参数:
刚度与阻尼比(motion_control_stiffness 和 motion_damping_ratio_task)
- 标量(所有轴向相同值)或6维列表(各轴向独立)。
- 临界阻尼公式:kd = 2 * sqrt(kp)(当impedance_mode="variable_kp"时自动计算阻尼)。
cfg.impedance_mode = "variable_kp" # 允许通过命令实时调整刚度
cfg.motion_stiffness_limits_task = (min_kp, max_kp) # 刚度范围约束
力控制模式:
开环控制:直接设置目标力,无反馈
cfg.contact_wrench_stiffness_task = None
闭环控制:通过刚度参数调节力跟踪:
# 仅线性轴(XYZ)有效,旋转轴刚度被忽略
cfg.contact_wrench_stiffness_task = [100, 100, 100, 0, 0, 0] # Z轴刚度100 N/m
动力学解耦与重力补偿:
惯性解耦(inertial_dynamics_decoupling):利用机器人惯性矩阵解耦任务空间加速度,提升动态响应精度。
cfg.inertial_dynamics_decoupling = True # 启用完全惯性解耦
cfg.partial_inertial_dynamics_decoupling = False # 不忽略平移-旋转耦合
重力补偿(gravity_compensation):若机器人模型已包含重力项(如仿真中启用重力),需关闭此选项:
cfg.gravity_compensation = False # 假设仿真中机器人已处理重力
冗余机器人的零空间控制
冗余自由度机器人的关节运动不影响末端位姿(零空间)。
cfg.nullspace_control = "position" # 吸引关节至中立位置
cfg.nullspace_stiffness = 10.0 # 零空间刚度
cfg.nullspace_damping_ratio = 0.7 # 阻尼比
本教程中的参数配置如下:
# 创建操作空间控制器配置
osc_cfg = OperationalSpaceControllerCfg(target_types=["pose_abs", "wrench_abs"], # 绝对位姿 + 绝对力控制motion_control_axes_task=[1, 1, 0, 1, 1, 1], # 控制XY位置和绕Z旋转(假设墙面Z轴)force_control_axes_task=[0, 0, 1, 0, 0, 0], # Z轴力控制motion_control_stiffness=[200, 200, 0, 50, 50, 50], # XY高刚度,旋转适中motion_damping_ratio_task=1.0, # 临界阻尼(kd=2*sqrt(kp))impedance_mode="variable_kp", # 允许动态调整刚度inertial_dynamics_decoupling=True, # 启用惯性解耦partial_inertial_dynamics_decoupling=False,gravity_compensation=False, # 仿真中已禁用重力nullspace_control="position", # 零空间关节位置控制nullspace_stiffness=10.0, # 零空间刚度nullspace_damping_ratio=0.7
)
2 更新机器人的状态
与前一节任务空间(task-space)控制类似,OSC 实现是一个仅用于计算的类。因此,需要提供机器人的必要信息,包括机器人的雅可比矩阵、质量/惯性矩阵、末端执行器位姿、速度、接触力(均在根坐标系中),以及关节位置和速度。此外,如果需要,用户还应提供重力补偿矢量和零空间关节位置目标。
# 函数功能:更新机器人状态信息,为操作空间控制器(OSC)提供必要的输入数据
def update_states(sim: sim_utils.SimulationContext,scene: InteractiveScene,robot: Articulation,ee_frame_idx: int,arm_joint_ids: list[int],contact_forces,
):"""Update the robot states.Args:sim: (SimulationContext) 仿真上下文对象,包含时间步长等物理参数scene: (InteractiveScene) 交互场景对象,管理多环境robot: (Articulation) 机器人刚体关节树对象ee_frame_idx: (int) 末端执行器在body_state_w中的索引arm_joint_ids: (list[int]) 机械臂关节的物理引擎索引列表contact_forces: (ContactSensor) 接触力传感器对象Returns:返回OSC控制器所需的11个关键参数,所有张量均为batch格式(shape: [num_envs, ...])"""# ====================== 动力学参数获取 ======================# 获取雅可比矩阵(世界坐标系)# 注意:对于固定基座机器人,物理引擎返回的雅可比矩阵索引需要-1(排除根身体)ee_jacobi_idx = ee_frame_idx - 1 # 计算物理引擎中的雅可比索引# 形状:[num_envs, 6, num_arm_joints] (6=3平移+3旋转)jacobian_w = robot.root_physx_view.get_jacobians()[:, ee_jacobi_idx, :, arm_joint_ids]# 获取质量矩阵(仅机械臂关节部分)# 形状:[num_envs, num_arm_joints, num_arm_joints]mass_matrix = robot.root_physx_view.get_generalized_mass_matrices()[:, arm_joint_ids, :][:, :, arm_joint_ids]# 获取重力补偿力矩(已考虑机器人质量分布)# 形状:[num_envs, num_arm_joints]gravity = robot.root_physx_view.get_gravity_compensation_forces()[:, arm_joint_ids]# ================= 雅可比矩阵坐标系转换(世界→基座) =================jacobian_b = jacobian_w.clone() # 创建副本避免修改原始数据# 计算基座旋转矩阵的逆(将世界坐标系转换到基座坐标系)root_rot_matrix = matrix_from_quat(quat_inv(robot.data.root_quat_w)) # shape: [num_envs, 3, 3]# 转换平移部分雅可比:J_lin_base = R_base^T * J_lin_worldjacobian_b[:, :3, :] = torch.bmm(root_rot_matrix, jacobian_b[:, :3, :])# 转换旋转部分雅可比:J_rot_base = R_base^T * J_rot_worldjacobian_b[:, 3:, :] = torch.bmm(root_rot_matrix, jacobian_b[:, 3:, :])# ===================== 末端执行器位姿计算 =====================# 世界坐标系下的基座位姿root_pos_w = robot.data.root_pos_w # 位置 [num_envs, 3]root_quat_w = robot.data.root_quat_w # 四元数 [num_envs, 4]# 世界坐标系下的末端位姿ee_pos_w = robot.data.body_pos_w[:, ee_frame_idx] # 末端位置ee_quat_w = robot.data.body_quat_w[:, ee_frame_idx] # 末端姿态# 将末端位姿转换到基座坐标系ee_pos_b, ee_quat_b = subtract_frame_transforms(root_pos_w, root_quat_w, ee_pos_w, ee_quat_w)# 拼接完整位姿张量root_pose_w = torch.cat([root_pos_w, root_quat_w], dim=-1) # [num_envs, 7]ee_pose_w = torch.cat([ee_pos_w, ee_quat_w], dim=-1) # [num_envs, 7]ee_pose_b = torch.cat([ee_pos_b, ee_quat_b], dim=-1) # [num_envs, 7]# ===================== 末端执行器速度计算 =====================# 世界坐标系下的末端线速度+角速度 [num_envs, 6]ee_vel_w = robot.data.body_vel_w[:, ee_frame_idx, :] # 基座速度(线速度 + 角速度)[num_envs, 6]root_vel_w = robot.data.root_vel_w # 计算末端相对于基座的速度(世界坐标系)relative_vel_w = ee_vel_w - root_vel_w # 转换到基座坐标系:线速度ee_lin_vel_b = quat_rotate_inverse(robot.data.root_quat_w, relative_vel_w[:, 0:3]) # [num_envs, 3]# 转换到基座坐标系:角速度ee_ang_vel_b = quat_rotate_inverse(robot.data.root_quat_w, relative_vel_w[:, 3:6]) # [num_envs, 3]# 拼接完整速度张量 [num_envs, 6]ee_vel_b = torch.cat([ee_lin_vel_b, ee_ang_vel_b], dim=-1)# ====================== 接触力处理 ======================ee_force_w = torch.zeros(scene.num_envs, 3, device=sim.device) # 初始化接触力sim_dt = sim.get_physics_dt() # 获取物理时间步长contact_forces.update(sim_dt) # 更新接触传感器数据# 数据平滑处理:取最近4步的平均值,再取三个接触面中的最大值(假设仅有一个有效接触)# net_forces_w_history形状:[num_envs, history_len=4, num_surfaces=3, 3]ee_force_w, _ = torch.max(torch.mean(contact_forces.data.net_forces_w_history, dim=1), dim=1)# 简化假设:直接使用世界坐标系的力(实际应根据任务坐标系转换)ee_force_b = ee_force_w # 此处应优化为基座坐标系转换# ===================== 关节状态获取 =====================# 仅提取机械臂关节(排除夹爪等)joint_pos = robot.data.joint_pos[:, arm_joint_ids] # [num_envs, num_arm_joints]joint_vel = robot.data.joint_vel[:, arm_joint_ids] # [num_envs, num_arm_joints]# 返回所有必要参数(用于OSC控制器计算)return (jacobian_b, # 基座坐标系雅可比矩阵 [num_envs, 6, num_arm_joints]mass_matrix, # 质量矩阵 [num_envs, num_arm_joints, num_arm_joints]gravity, # 重力补偿力矩 [num_envs, num_arm_joints]ee_pose_b, # 基座坐标系末端位姿 [num_envs, 7]ee_vel_b, # 基座坐标系末端速度 [num_envs, 6]root_pose_w, # 世界坐标系基座位姿 [num_envs, 7]ee_pose_w, # 世界坐标系末端位姿 [num_envs, 7]ee_force_b, # 基座坐标系接触力(当前简化处理)[num_envs, 3]joint_pos, # 关节角度 [num_envs, num_arm_joints]joint_vel, # 关节速度 [num_envs, num_arm_joints])
3 计算机器人指令
- 命令坐标系转换
- 位姿控制 (“pose_abs”):通过 subtract_frame_transforms 将基座坐标系下的目标位姿转换到任务帧坐标系。例如,若任务帧是墙面坐标系,则目标位置将表示为相对于墙面的坐标。
- 力控制 (“wrench_abs”):假设力命令已在任务帧中定义(如Z轴垂直墙面),无需转换。
- OSC命令设置
- 任务帧位姿传递:current_task_frame_pose_b 告知OSC任务帧相对于基座的位置,用于内部计算误差。
- 当前末端位姿:提供实时反馈,用于计算位姿误差和速度误差。
- 力矩计算参数
- 质量矩阵与惯性解耦:启用 inertial_dynamics_decoupling 时,质量矩阵用于解耦任务空间加速度,提升动态响应。
- 零空间控制:
nullspace_joint_pos_target吸引关节至中立位置(如 joint_centers),避免极限位置。
- 力控制实现
- 开环 vs 闭环:若
contact_wrench_stiffness_task未设置,为开环力控;若设置刚度值,则闭环调整力误差。 - 接触力测量:
ee_force_b来自接触传感器,需平滑处理(如示例中的四步平均)。
- 开环 vs 闭环:若
# 将目标命令从基座坐标系转换到任务帧(如墙面坐标系)
def convert_to_task_frame(osc: OperationalSpaceController, command: torch.tensor, ee_target_pose_b: torch.tensor
):"""将基座坐标系下的命令转换为任务帧坐标系下的命令Args:osc: 操作空间控制器实例,包含配置信息(如目标类型)command: 原始命令张量,形状为 [num_envs, command_dim]ee_target_pose_b: 末端在基座坐标系下的目标位姿(用于定义任务帧)Returns:command_task: 转换到任务帧后的命令张量task_frame_pose_b: 任务帧在基座坐标系下的位姿(用于后续计算)"""command_task = command.clone() # 避免修改原始命令task_frame_pose_b = ee_target_pose_b.clone() # 任务帧位姿(例如墙面坐标系)cmd_idx = 0 # 命令张量的当前处理位置索引# 遍历所有目标类型(如 ["pose_abs", "wrench_abs"])for target_type in osc.cfg.target_types:if target_type == "pose_abs":# 提取当前位姿命令部分(位置+四元数姿态)target_pos_b = command_task[:, cmd_idx : cmd_idx+3] # [num_envs, 3]target_quat_b = command_task[:, cmd_idx+3 : cmd_idx+7] # [num_envs, 4]# 将位姿从基座坐标系转换到任务帧坐标系# 数学等效:T_task^base * T_target^task = T_target^base → 求T_target^tasktarget_pos_task, target_quat_task = subtract_frame_transforms(task_frame_pose_b[:, :3], # 任务帧位置(基座坐标系)task_frame_pose_b[:, 3:7], # 任务帧姿态(基座坐标系)target_pos_b, target_quat_b)# 更新命令张量中的位姿部分command_task[:, cmd_idx : cmd_idx+3] = target_pos_taskcommand_task[:, cmd_idx+3 : cmd_idx+7] = target_quat_taskcmd_idx += 7 # 移动索引到下个命令部分elif target_type == "wrench_abs":# 力/力矩命令已在任务帧中定义,无需转换cmd_idx += 6 # 力控制为6维(3力 + 3力矩)else:raise ValueError(f"未定义的目标类型:{target_type}")return command_task, task_frame_pose_b# ====================== OSC命令设置与力矩计算 ======================
# 重置控制器内部状态(如积分项、历史误差)
osc.reset()# 将目标命令转换到任务帧坐标系
command_task, task_frame_pose_b = convert_to_task_frame(osc, command=command_raw, # 原始命令(基座坐标系)ee_target_pose_b=ee_target_pose_b # 任务帧在基座下的位姿(如墙面坐标系)
)# 设置OSC命令(任务帧坐标系下的命令 + 当前末端位姿 + 任务帧位姿)
osc.set_command(command=command_task, # 转换后的命令(任务帧)current_ee_pose_b=ee_pose_b, # 当前末端在基座下的位姿(来自update_states)current_task_frame_pose_b=task_frame_pose_b # 任务帧在基座下的位姿
)# 计算关节力矩(核心运算)
joint_efforts = osc.compute(jacobian_b=jacobian_b, # 基座坐标系下的雅可比矩阵current_ee_pose_b=ee_pose_b, # 当前末端基座位姿current_ee_vel_b=ee_vel_b, # 当前末端基座速度current_ee_force_b=ee_force_b, # 当前末端基座接触力(简化处理)mass_matrix=mass_matrix, # 质量矩阵(仅机械臂关节)gravity=gravity, # 重力补偿力矩current_joint_pos=joint_pos, # 当前关节角度current_joint_vel=joint_vel, # 当前关节速度nullspace_joint_pos_target=joint_centers # 零空间目标关节位置(如限位中点)
)# 将计算的关节力矩应用到机器人
robot.set_joint_effort_target(joint_efforts, # 计算得到的力矩 [num_envs, num_arm_joints]joint_ids=arm_joint_ids # 仅控制机械臂关节(排除夹爪)
)
# 将数据写入仿真环境,准备下一步物理计算
robot.write_data_to_sim()
相关文章:
第十七讲、Isaaclab中使用操作空间控制器
0 前言 官方教程:https://isaac-sim.github.io/IsaacLab/main/source/tutorials/05_controllers/run_osc.html IsaacsimIsaaclab安装:https://blog.csdn.net/m0_47719040/article/details/146389391?spm1001.2014.3001.5502 有时候,仅使用…...
基于SpringBoot的校园二手商品在线交易系统+含项目运行说明文档
基于SpringBoot的校园二手商品在线交易系统含项目运行说明文档 专注校园二手交易平台是一个基于Java的在线市场,专为学生设计,便于买卖二手商品。平台提供全面的用户管理功能,包括学生、管理员和二手商品卖家账户管理。商品管理功能允许用户…...
电商行业下的Java核心、Spring生态与AI技术问答
电商行业下的Java核心、Spring生态与AI技术问答 在互联网大厂求职的Java程序员马架构,今天参加了一场关于电商行业的技术面试。以下是面试官和马架构之间的5轮提问和回答。 第一轮提问 问题1:请简要描述一下电商系统中的高并发处理方案。问题2&#x…...
面向电力变压器的声纹智能诊断系统简析
面向电力变压器的声纹智能诊断系统是一种利用声纹识别技术对电力变压器运行状态进行实时监测和故障诊断的系统。以下是其简要分析: 系统组成 感知层:主要由声纹传感器和振动传感器组成。声纹传感器一般采用高灵敏度麦克风,用于采集变压器向…...
《浔川AI翻译v6.1.0问题已修复公告》
《浔川AI翻译v6.1.0问题已修复公告》 尊敬的浔川AI翻译用户: 感谢您对浔川AI翻译的支持与反馈!我们已针对 **v6.1.0** 版本中用户反馈的多个问题进行了全面修复,并优化了系统稳定性。以下是本次修复的主要内容: 已修复问题 ✅…...
详解springcloud gateway工作原理、断言、filter、uri、id、全局跨域、globalfilter等以及关键源码实现
1.gateway概念 网关就是当前微服务项目的"统一入口"程序中的网关就是当前微服务项目对外界开放的统一入口所有外界的请求都需要先经过网关才能访问到我们的程序提供了统一入口之后,方便对所有请求进行统一的检查和管理 2. 网关的主要功能 将所有请求统一经过网关网…...
C++面向对象特性之继承篇
C语音是面向过程的语言,而C在其之上多了面向对象的特性,面向对象三大特性:封装性、继承性、多态性。今天主包来讲讲自己学到的关于C继承特性的知识。 一、继承是什么 继承是提高代码复用的一种重要手段。正如C的模版、泛型编程等等都是为了实现代码复用…...
【Java设计模式及实践学习-第4章节-结构型模式】
第4章节-结构型模式 笔记记录 1. 适配器模式2. 代理模式3. 装饰器模式4. 桥接模式5. 组合模式6. 外观模式7. 享元模式8. 总结 1. 适配器模式 2. 代理模式 3. 装饰器模式 4. 桥接模式 5. 组合模式 6. 外观模式 7. 享元模式 Java语言中的String字符串就使用了享元模式&…...
【AI News | 20250423】每日AI进展
AI Repos 1、suna Suna是一款完全开源的AI助手,旨在通过自然对话帮助用户轻松完成现实世界的任务。它作为您的数字伙伴,提供研究、数据分析和日常问题解决等功能,并结合强大的能力与直观的界面,理解您的需求并交付成果。Suna的工…...
大数据利器Kafka
大数据利器Kafka:从入门到实战的全面指南 在大数据的世界里,Kafka就像是一个高效的“数据快递员”,负责在不同的系统之间快速、可靠地传递数据。今天,咱们就一起来深入了解一下这个强大的工具。Kafka是由LinkedIn开发的分布式发布…...
.NET、java、python语言连接SAP系统的方法
💡 本文会带给你 可用哪些技术与Sap系统连接怎样用Rfc技术连接SAP一. SAP系统与外部系统集成技术 SAP系统提供了多种方式供Java、.NET、Python等外部编程语言进行连接和集成。 1. RFC (Remote Function Call) 连接 适用语言:Java, .NET, Python, 其他支持RFC的编程语言 …...
【学习准备】算法和开发知识大纲
1 缘起 今年(2025年)的职业升级结果:不通过。没办法升职加薪了。 需要开始完善学习,以应对不同的发展趋势,为了督促自己学习,梳理出相关学习大纲。 分为算法和开发两部分。 算法,包括基础算法和…...
【Nova UI】七、SASS 全局变量体系:组件库样式开发的坚固基石
序言 咱们已经实现了 SASS 中一系列实用的函数和混入,可它们究竟如何在实际的组件库样式开发里大展身手,尤其是在构建全局变量体系这一关键环节呢🧐?这篇文章将为你揭晓答案,带你深入了解怎样利用这些工具实现 SASS 全…...
第七篇:linux之基本权限、进程管理、系统服务
第七篇:linux之基本权限、进程管理、系统服务 文章目录 第七篇:linux之基本权限、进程管理、系统服务一、基本权限1、什么是权限?2、为什么要有权限?3、权限与用户之间的关系?4、权限对应的数字含义5、使用chmod设定权…...
Windows 同步技术-一次性初始化
组件通常设计为在首次调用时执行初始化任务,而不是加载它们时。 一次性初始化函数可确保此初始化仅发生一次,即使多个线程可能尝试初始化也是如此。 Windows Server 2003 和 Windows XP: 应用程序必须使用 互锁函数 或其他同步机制提供自己的…...
爬虫案例-爬取某企数据
文章目录 1、准备要爬取企业名称数据表2、爬取代码3、查看效果 1、准备要爬取企业名称数据表 企业名称绍兴市袍江王新国家庭农场绍兴市郑杜粮油专业合作社绍兴市越城区兴华家庭农场绍兴市越城区锐意家庭农场绍兴市越城区青甸畈家庭农场绍兴市袍江王新国家庭农场绍兴市袍江月明…...
VAE-LSTM异常检测模型复刻报告
VAE-LSTM异常检测模型复刻报告 复刻背景 本报告记录了我复刻VAE-LSTM异常检测模型的完整过程。原论文提出了一种结合变分自编码器(VAE)和长短期记忆网络(LSTM)的异常检测方法,用于时间序列数据。 环境配置 复刻过程中使用的环境配置如下: Python 3.…...
学习笔记—C++—string(一)
目录 string 为什么学习string的类 string类的常用接口 string类对象的常见构造 string类对象的访问及遍历操作 operator[] 迭代器 范围for auto 迭代器(二) string类对象的容量操作 size,length,max_size,capacity,clear基本用法 reserve 提…...
OpenCV 图形API(55)颜色空间转换-----将图像从 RGB 色彩空间转换为 I420 格式函数RGB2I420()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将图像从 RGB 色彩空间转换为 I420 色彩空间。 该函数将输入图像从 RGB 色彩空间转换为 I420。R、G 和 B 通道值的常规范围是 0 到 255。 输出图…...
GPLT-2025年第十届团体程序设计天梯赛总决赛题解(共计266分)
今天偶然发现天梯赛的代码还保存着,于是决定写下这篇题解,也算是复盘一下了 L1本来是打算写的稳妥点,最后在L1-6又想省时间,又忘记了insert,replace这些方法怎么用,也不想花时间写一个文件测试,…...
MySQL数据库精研之旅第十期:打造高效联合查询的实战宝典(一)
专栏:MySQL数据库成长记 个人主页:手握风云 目录 一、简介 1.1. 为什么要使用联合查询 1.2. 多表联合查询时的计算 1.3. 示例 二、内连接 2.1. 语法 2.2. 示例 三、外连接 4.1. 语法 4.2. 示例 一、简介 1.1. 为什么要使用联合查询 一次查询需…...
zkPass案例实战之合约篇
目录 一、contracts/contracts/ProofVerifier.sol 1. License 和 Solidity 版本 2. 导入依赖 3. 合约声明和默认分配器地址 4. 验证证明 5. 验证分配器签名 6. 验证验证者签名 7. 签名前缀处理 8. 签名恢复 总结 二、contracts/contracts/SampleAttestation.sol 1. …...
15.FineReport动态展示需要的列
1.首先连接自带的sqlite数据库,具体方法参考下面的链接 点击查看连接sqlite数据库 2.文件 – 新建普通报表 3.新建数据库查询 4.查询自带的销售明细表 5.把数据添加到格子中,并设置边框颜色等格式 6.查询新的数据集:column 7.点笔 8.全部添…...
Windows云主机远程连接提示“出现了内部错误”
今天有人反馈说有个服务器突然连不上了,让我看下什么问题,我根据他给的账号密码试了下发现提示“出现了内部错误”,然后就是一通排查 先是查看安全组,没发现特别的问题,因为也没有调过这块的配置 然后通过控制台登录进…...
最新扣子(Coze)案例教程:Excel数据生成统计图表,自动清洗数据+转换可视化图表+零代码,完全免费教程
大家好,我是斜杠君。 知识星球群有同学和我说每天的工作涉及很多数据表的重复操作,想学习Excel数据表通过大模型自动转数据图片的功能。 今天斜杠君就带大家一起搭建一个智能体,以一个销售行业数据为例,可以快速实现自动清洗Exc…...
如何安装Visio(win10)
首先下载下面这些文件 HomeStudent2021Retail.img officedeploymenttool_17531-20046.exe office中文语言包.exe 确保这些文件都在一个文件夹内(我已经上传这些资源,这些资源都是官网下载的) 官网资源下载教程 1.下载Office镜像࿰…...
建筑安全员 A 证与 C 证:差异决定职业方向
在建筑行业的职业发展道路上,安全员 A 证和 C 证就像两条不同的岔路,它们之间的差异,在很大程度上决定了从业者的职业方向。 从证书性质和用途来看,A 证是从业资格证书,更像是一把开启安全管理高层岗位的 “金钥匙”。…...
Java Arrays工具类解析(Java 8-17)
一、Arrays工具类概述 java.util.Arrays是Java集合框架中提供的数组操作工具类,包含各种静态方法用于操作数组(排序、搜索、比较、填充、复制等)。自Java 8到17版本,Arrays类不断增强了功能,特别是引入了并行操作和St…...
(19)VTK C++开发示例 --- 分隔文本读取器
文章目录 1. 概述2. CMake链接VTK3. main.cpp文件4. 演示效果 更多精彩内容👉内容导航 👈👉VTK开发 👈 1. 概述 本例采用坐标和法线(x y z nx ny nz)的纯文本文件,并将它们读入vtkPolyData并显示…...
Redis从入门到实战先导篇
前言:本节内容包括虚拟机VMware的安装,Linux系统的配置,FinalShell的下载与配置,Redis与其桌面客户端的安装指导,便于后续黑马Redis从入门到实战的课程学习 目录 主要内容 0.相关资源 1.VMware安装 2.Linux与CentOS安装 3.Fi…...
