[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-UM-ARM-Lab--pytorch_kinematics":3,"tool-UM-ARM-Lab--pytorch_kinematics":64},[4,17,27,35,43,56],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":16},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,3,"2026-04-05T11:01:52",[13,14,15],"开发框架","图像","Agent","ready",{"id":18,"name":19,"github_repo":20,"description_zh":21,"stars":22,"difficulty_score":23,"last_commit_at":24,"category_tags":25,"status":16},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",140436,2,"2026-04-05T23:32:43",[13,15,26],"语言模型",{"id":28,"name":29,"github_repo":30,"description_zh":31,"stars":32,"difficulty_score":23,"last_commit_at":33,"category_tags":34,"status":16},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107662,"2026-04-03T11:11:01",[13,14,15],{"id":36,"name":37,"github_repo":38,"description_zh":39,"stars":40,"difficulty_score":23,"last_commit_at":41,"category_tags":42,"status":16},3704,"NextChat","ChatGPTNextWeb\u002FNextChat","NextChat 是一款轻量且极速的 AI 助手，旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性，以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发，NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。\n\n这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言，它也提供了便捷的自托管方案，支持一键部署到 Vercel 或 Zeabur 等平台。\n\nNextChat 的核心亮点在于其广泛的模型兼容性，原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型，让用户在一个界面即可自由切换不同 AI 能力。此外，它还率先支持 MCP（Model Context Protocol）协议，增强了上下文处理能力。针对企业用户，NextChat 提供专业版解决方案，具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能，满足公司对数据隐私和个性化管理的高标准要求。",87618,"2026-04-05T07:20:52",[13,26],{"id":44,"name":45,"github_repo":46,"description_zh":47,"stars":48,"difficulty_score":23,"last_commit_at":49,"category_tags":50,"status":16},2268,"ML-For-Beginners","microsoft\u002FML-For-Beginners","ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程，旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周，包含 26 节精炼课程和 52 道配套测验，内容涵盖从基础概念到实际应用的完整流程，有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。\n\n无论是希望转型的开发者、需要补充算法背景的研究人员，还是对人工智能充满好奇的普通爱好者，都能从中受益。课程不仅提供了清晰的理论讲解，还强调动手实践，让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持，通过自动化机制提供了包括简体中文在内的 50 多种语言版本，极大地降低了全球不同背景用户的学习门槛。此外，项目采用开源协作模式，社区活跃且内容持续更新，确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路，ML-For-Beginners 将是理想的起点。",84991,"2026-04-05T10:45:23",[14,51,52,53,15,54,26,13,55],"数据工具","视频","插件","其他","音频",{"id":57,"name":58,"github_repo":59,"description_zh":60,"stars":61,"difficulty_score":10,"last_commit_at":62,"category_tags":63,"status":16},3128,"ragflow","infiniflow\u002Fragflow","RAGFlow 是一款领先的开源检索增强生成（RAG）引擎，旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体（Agent）能力相结合，不仅支持从各类文档中高效提取知识，还能让模型基于这些知识进行逻辑推理和任务执行。\n\n在大模型应用中，幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构（如表格、图表及混合排版），显著提升了信息检索的准确度，从而有效减少模型“胡编乱造”的现象，确保回答既有据可依又具备时效性。其内置的智能体机制更进一步，使系统不仅能回答问题，还能自主规划步骤解决复杂问题。\n\n这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统，还是致力于探索大模型在垂直领域落地的创新者，都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口，既降低了非算法背景用户的上手门槛，也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目，它正成为连接通用大模型与行业专有知识之间的重要桥梁。",77062,"2026-04-04T04:44:48",[15,14,13,26,54],{"id":65,"github_repo":66,"name":67,"description_en":68,"description_zh":69,"ai_summary_zh":69,"readme_en":70,"readme_zh":71,"quickstart_zh":72,"use_case_zh":73,"hero_image_url":74,"owner_login":75,"owner_name":76,"owner_avatar_url":77,"owner_bio":78,"owner_company":79,"owner_location":79,"owner_email":79,"owner_twitter":79,"owner_website":80,"owner_url":81,"languages":82,"stars":91,"forks":92,"last_commit_at":93,"license":94,"difficulty_score":95,"env_os":96,"env_gpu":97,"env_ram":96,"env_deps":98,"category_tags":103,"github_topics":104,"view_count":23,"oss_zip_url":79,"oss_zip_packed_at":79,"status":16,"created_at":110,"updated_at":111,"faqs":112,"releases":142},1435,"UM-ARM-Lab\u002Fpytorch_kinematics","pytorch_kinematics","Robot kinematics implemented in pytorch","pytorch_kinematics 是一款基于 PyTorch 构建的机器人运动学计算库，旨在将传统的机器人正逆运动学求解过程转化为可微分、可并行的高效运算。它主要解决了传统运动学算法难以直接融入深度学习训练流程的痛点，让开发者能够轻松在神经网络中通过梯度下降优化机器人姿态，同时支持大规模批量计算以显著提升效率。\n\n这款工具非常适合机器人领域的研究人员、算法工程师以及希望结合深度学习进行强化学习或轨迹优化的开发者使用。用户可以直接从 URDF、SDF 或 MJCF 等主流格式加载机器人描述文件，快速构建运动学链。\n\n其核心技术亮点在于提供了完全可微分的正向运动学、雅可比矩阵计算以及阻尼最小二乘法逆运动学求解器。这意味着它不仅能在 CPU 上运行，还能无缝利用 GPU 加速，支持对成千上万个不同构型或空间点进行并行查询。无论是用于模拟环境中的大规模数据采集，还是作为端到端学习模型的一部分，pytorch_kinematics 都能提供灵活且高性能的底层支持，帮助使用者更专注于上层算法的创新与验证。","# PyTorch Robot Kinematics\n- Parallel and differentiable forward kinematics (FK), Jacobian calculation, and damped least squares inverse kinematics (IK)\n- Load robot description from URDF, SDF, and MJCF formats \n- SDF queries batched across configurations and points via [pytorch-volumetric](https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_volumetric)\n\n# Installation\n```shell\npip install pytorch-kinematics\n```\n\nFor development, clone repository somewhere, then `pip3 install -e .` to install in editable mode.\n\n## Reference\n[![DOI](https:\u002F\u002Fzenodo.org\u002Fbadge\u002F331721571.svg)](https:\u002F\u002Fzenodo.org\u002Fbadge\u002Flatestdoi\u002F331721571)\n\nIf you use this package in your research, consider citing\n```\n@software{Zhong_PyTorch_Kinematics_2024,\nauthor = {Zhong, Sheng and Power, Thomas and Gupta, Ashwin and Mitrano, Peter},\ndoi = {10.5281\u002Fzenodo.7700587},\nmonth = feb,\ntitle = {{PyTorch Kinematics}},\nversion = {v0.7.1},\nyear = {2024}\n}\n```\n\n# Usage\n\nSee `tests` for code samples; some are also shown here.\n\n## Loading Robots\n```python\nimport pytorch_kinematics as pk\n\nurdf = \"widowx\u002Fwx250s.urdf\"\n# there are multiple natural end effector links so it's not a serial chain\nchain = pk.build_chain_from_urdf(open(urdf, mode=\"rb\").read())\n# visualize the frames (the string is also returned)\nchain.print_tree()\n\"\"\"\nbase_link\n└── shoulder_link\n    └── upper_arm_link\n        └── upper_forearm_link\n            └── lower_forearm_link\n                └── wrist_link\n                    └── gripper_link\n                        └── ee_arm_link\n                            ├── gripper_prop_link\n                            └── gripper_bar_link\n                                └── fingers_link\n                                    ├── left_finger_link\n                                    ├── right_finger_link\n                                    └── ee_gripper_link\n\"\"\"\n\n# extract a specific serial chain such as for inverse kinematics\nserial_chain = pk.SerialChain(chain, \"ee_gripper_link\", \"base_link\")\nserial_chain.print_tree()\n\"\"\"\nbase_link\n└── shoulder_link\n    └── upper_arm_link\n        └── upper_forearm_link\n            └── lower_forearm_link\n                └── wrist_link\n                    └── gripper_link\n                        └── ee_arm_link\n                            └── gripper_bar_link\n                                └── fingers_link\n                                    └── ee_gripper_link\n\"\"\"\n\n# you can also extract a serial chain with a different root than the original chain\nserial_chain = pk.SerialChain(chain, \"ee_gripper_link\", \"gripper_link\")\nserial_chain.print_tree()\n\"\"\"\n gripper_link\n└── ee_arm_link\n    └── gripper_bar_link\n        └── fingers_link\n            └── ee_gripper_link\n\"\"\"\n```\n\n## Forward Kinematics (FK)\n```python\nimport math\nimport pytorch_kinematics as pk\n\n# load robot description from URDF and specify end effector link\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n# prints out the (nested) tree of links\nprint(chain)\n# prints out list of joint names\nprint(chain.get_joint_parameter_names())\n\n# specify joint values (can do so in many forms)\nth = [0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0]\n# do forward kinematics and get transform objects; end_only=False gives a dictionary of transforms for all links\nret = chain.forward_kinematics(th, end_only=False)\n# look up the transform for a specific link\ntg = ret['lbr_iiwa_link_7']\n# get transform matrix (1,4,4), then convert to separate position and unit quaternion\nm = tg.get_matrix()\npos = m[:, :3, 3]\nrot = pk.matrix_to_quaternion(m[:, :3, :3])\n```\n\nWe can parallelize FK by passing in 2D joint values, and also use CUDA if available\n```python\nimport torch\nimport pytorch_kinematics as pk\n\nd = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndtype = torch.float64\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\nchain = chain.to(dtype=dtype, device=d)\n\nN = 1000\nth_batch = torch.rand(N, len(chain.get_joint_parameter_names()), dtype=dtype, device=d)\n\n# order of magnitudes faster when doing FK in parallel\n# elapsed 0.008678913116455078s for N=1000 when parallel\n# (N,4,4) transform matrix; only the one for the end effector is returned since end_only=True by default\ntg_batch = chain.forward_kinematics(th_batch)\n\n# elapsed 8.44686508178711s for N=1000 when serial\nfor i in range(N):\n    tg = chain.forward_kinematics(th_batch[i])\n```\n\nWe can compute gradients through the FK\n```python\nimport torch\nimport math\nimport pytorch_kinematics as pk\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# require gradient through the input joint values\nth = torch.tensor([0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0], requires_grad=True)\ntg = chain.forward_kinematics(th)\nm = tg.get_matrix()\npos = m[:, :3, 3]\npos.norm().backward()\n# now th.grad is populated\n```\n\nWe can load SDF and MJCF descriptions too, and pass in joint values via a dictionary (unspecified joints get th=0) for non-serial chains\n```python\nimport math\nimport torch\nimport pytorch_kinematics as pk\n\nchain = pk.build_chain_from_sdf(open(\"simple_arm.sdf\").read())\nret = chain.forward_kinematics({'arm_elbow_pan_joint': math.pi \u002F 2.0, 'arm_wrist_lift_joint': -0.5})\n# recall that we specify joint values and get link transforms\ntg = ret['arm_wrist_roll']\n\n# can also do this in parallel\nN = 100\nret = chain.forward_kinematics({'arm_elbow_pan_joint': torch.rand(N, 1), 'arm_wrist_lift_joint': torch.rand(N, 1)})\n# (N, 4, 4) transform object\ntg = ret['arm_wrist_roll']\n\n# building the robot from a MJCF file\nchain = pk.build_chain_from_mjcf(open(\"ant.xml\").read())\nprint(chain)\nprint(chain.get_joint_parameter_names())\nth = {'hip_1': 1.0, 'ankle_1': 1}\nret = chain.forward_kinematics(th)\n\nchain = pk.build_chain_from_mjcf(open(\"humanoid.xml\").read())\nprint(chain)\nprint(chain.get_joint_parameter_names())\nth = {'left_knee': 0.0, 'right_knee': 0.0}\nret = chain.forward_kinematics(th)\n```\n\n## torch.compile Support\n\nThe FK computation can be compiled with `torch.compile(fullgraph=True)` for significant speedups,\nespecially for applications that call FK thousands of times (e.g. inverse kinematics, trajectory optimization).\n\nUse `forward_kinematics_tensor`, a compile-friendly variant that accepts and returns raw tensors\ninstead of dicts and `Transform3d` objects:\n\n```python\nimport torch\nimport pytorch_kinematics as pk\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# compile the FK kernel (one-time cost)\ncompiled_fk = torch.compile(chain.forward_kinematics_tensor, fullgraph=True, dynamic=True)\n\n# input: (B, n_joints) tensor\nth = torch.randn(1000, 7)\n\n# output: (num_frames, B, 4, 4) tensor of homogeneous transforms for all frames\nall_transforms = compiled_fk(th)\n\n# index by frame: use chain.frame_to_idx to look up the index for a frame name\nee_idx = chain.frame_to_idx['lbr_iiwa_link_7']\nee_transform = all_transforms[ee_idx]  # (B, 4, 4)\n```\n\nTypical speedups on CPU (Kuka IIWA 7-DOF):\n\n| Batch size | `forward_kinematics` | Compiled `forward_kinematics_tensor` | Speedup |\n|---:|---:|---:|---:|\n| 1 | 0.21 ms | 0.04 ms | **4.7x** |\n| 64 | 0.26 ms | 0.08 ms | **3.5x** |\n| 1024 | 1.13 ms | 0.51 ms | **2.2x** |\n\nSpeedups are larger for complex robots with more frames (e.g. 6x+ for 49-frame robots at batch=1).\nGPU speedups from CUDA graph capture provide additional gains at large batch sizes.\n\nThe standard `forward_kinematics` method (returning `Dict[str, Transform3d]`) also benefits from the\nrefactored internals without any code changes. It is 2-6x faster at small batch sizes compared to v0.7.\n\nThe rotation conversion functions (`matrix_to_quaternion`, `quaternion_to_axis_angle`,\n`axis_angle_to_quaternion`, etc.) are also compatible with `torch.compile(fullgraph=True)` and can\nbe compiled standalone or as part of a larger compiled graph:\n\n```python\nimport torch\nimport pytorch_kinematics as pk\n\n# compile a rotation conversion function\ncompiled_m2q = torch.compile(pk.matrix_to_quaternion, fullgraph=True)\nR = torch.randn(100, 3, 3)\nq = compiled_m2q(R)\n```\n\n## Jacobian calculation\nThe Jacobian (in the kinematics context) is a matrix describing how the end effector changes with respect to joint value changes\n(where ![dx](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FUM-ARM-Lab_pytorch_kinematics_readme_e32ebb39315e.png) is the twist, or stacked velocity and angular velocity):\n![jacobian](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FUM-ARM-Lab_pytorch_kinematics_readme_e32ebb39315e.png%3DJ%5Cdot%7Bq%7D)\n\nFor `SerialChain` we provide a differentiable and parallelizable method for computing the Jacobian with respect to the base frame.\n```python\nimport math\nimport torch\nimport pytorch_kinematics as pk\n\n# can convert Chain to SerialChain by choosing end effector frame\nchain = pk.build_chain_from_sdf(open(\"simple_arm.sdf\").read())\n# print(chain) to see the available links for use as end effector\n# note that any link can be chosen; it doesn't have to be a link with no children\nchain = pk.SerialChain(chain, \"arm_wrist_roll_frame\")\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\nth = torch.tensor([0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0])\n# (1,6,7) tensor, with 7 corresponding to the DOF of the robot\nJ = chain.jacobian(th)\n\n# get Jacobian in parallel and use CUDA if available\nN = 1000\nd = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndtype = torch.float64\n\nchain = chain.to(dtype=dtype, device=d)\n# Jacobian calculation is differentiable\nth = torch.rand(N, 7, dtype=dtype, device=d, requires_grad=True)\n# (N,6,7)\nJ = chain.jacobian(th)\n\n# can get Jacobian at a point offset from the end effector (location is specified in EE link frame)\n# by default location is at the origin of the EE frame\nloc = torch.rand(N, 3, dtype=dtype, device=d)\nJ = chain.jacobian(th, locations=loc)\n```\n\nLike FK, the Jacobian has a `torch.compile`-compatible variant `jacobian_tensor`:\n\n```python\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# compile the Jacobian kernel (one-time cost)\ncompiled_jac = torch.compile(chain.jacobian_tensor, fullgraph=True)\n\n# input: (B, n_joints) tensor; output: (B, 6, n_joints) Jacobian\nth = torch.randn(100, 7)\nJ = compiled_jac(th)\n```\n\nFor maximum performance in tight loops (e.g. IK), pass `mode='max-autotune'` to `torch.compile`\nfor additional kernel tuning at the cost of longer compilation.\n\nTypical speedups on CPU (Kuka IIWA 7-DOF, vs the old v0.7 `calc_jacobian`):\n\n| Batch size | Old `calc_jacobian` | New `jacobian` (eager) | Compiled `jacobian_tensor` | Speedup (compiled vs old) |\n|---:|---:|---:|---:|---:|\n| 1 | 0.63 ms | 0.12 ms | 0.03 ms | **21x** |\n| 10 | 0.79 ms | 0.15 ms | 0.05 ms | **15x** |\n| 100 | 0.75 ms | 0.30 ms | 0.09 ms | **8x** |\n| 1,000 | 1.67 ms | 1.23 ms | 0.53 ms | **3x** |\n| 10,000 | 7.93 ms | 7.01 ms | 4.91 ms | **1.6x** |\n| 100,000 | 59.42 ms | 64.58 ms | 46.46 ms | **1.3x** |\n\nAt small-to-medium batch sizes (the typical IK regime), the new eager implementation is 2-5x faster\ndue to vectorized computation replacing the per-frame Python loop.\n`torch.compile` provides an additional 2-4x on top of that, and is faster than the old implementation\nat every batch size.\n\nThe Jacobian can be used to do inverse kinematics. See [IK survey](https:\u002F\u002Fwww.math.ucsd.edu\u002F~sbuss\u002FResearchWeb\u002Fikmethods\u002Fiksurvey.pdf)\nfor a survey of ways to do so. Note that IK may be better performed through other means (but doing it through the Jacobian can give an end-to-end differentiable method).\n\n## Inverse Kinematics (IK)\nInverse kinematics is available via damped least squares (iterative steps with Jacobian pseudo-inverse damped to avoid oscillation near singularlities). \nCompared to other IK libraries, these are the typical advantages over them:\n- not ROS dependent (many IK libraries need the robot description on the ROS parameter server)\n- batched in both goal specification and retries from different starting configurations\n- goal orientation in addition to goal position\n\n![IK](https:\u002F\u002Fi.imgur.com\u002FQgaUME9.gif)\n\nSee `tests\u002Ftest_inverse_kinematics.py` for usage, but generally what you need is below:\n```python\nfull_urdf = os.path.join(search_path, urdf)\nchain = pk.build_serial_chain_from_urdf(open(full_urdf).read(), \"lbr_iiwa_link_7\")\n\n# goals are specified as Transform3d poses in the **robot frame**\n# so if you have the goals specified in the world frame, you also need the robot frame in the world frame\npos = torch.tensor([0.0, 0.0, 0.0], device=device)\nrot = torch.tensor([0.0, 0.0, 0.0], device=device)\nrob_tf = pk.Transform3d(pos=pos, rot=rot, device=device)\n\n# specify goals as Transform3d poses in world frame\ngoal_in_world_frame_tf = ...\n# convert to robot frame (skip if you have it specified in robot frame already, or if world = robot frame)\ngoal_in_rob_frame_tf = rob_tf.inverse().compose(goal_tf)\n\n# get robot joint limits\nlim = torch.tensor(chain.get_joint_limits(), device=device)\n\n# create the IK object\n# see the constructor for more options and their explanations, such as convergence tolerances\nik = pk.PseudoInverseIK(chain, max_iterations=30, num_retries=10,\n                        joint_limits=lim.T,\n                        early_stopping_any_converged=True,\n                        early_stopping_no_improvement=\"all\",\n                        debug=False,\n                        lr=0.2)\n# solve IK\nsol = ik.solve(goal_in_rob_frame_tf)\n# num goals x num retries x DOF tensor of joint angles; if not converged, best solution found so far\nprint(sol.solutions)\n# num goals x num retries can check for the convergence of each run\nprint(sol.converged)\n# num goals x num retries can look at errors directly\nprint(sol.err_pos)\nprint(sol.err_rot)\n```\n\n### Compiled IK\n\nFor workloads that solve IK repeatedly (e.g. in a planning loop), pass `use_compile=True` to compile the\nFK, Jacobian, and damped least squares kernels inside the IK loop with `torch.compile`.\nThe outer IK loop with its data-dependent convergence checks remains in eager mode.\n\n```python\nik = pk.PseudoInverseIK(chain, max_iterations=30, num_retries=10,\n                         joint_limits=lim.T,\n                         early_stopping_any_converged=True,\n                         early_stopping_no_improvement=\"all\",\n                         lr=0.2,\n                         use_compile=True)  # compile inner kernels\n\n# first solve() incurs a one-time compilation cost; subsequent calls are faster\nsol = ik.solve(goal_in_rob_frame_tf)\n```\n\nTypical speedups on CPU (Kuka IIWA 7-DOF, 30 iterations):\n\n| Retries | Eager (v0.7) | Eager (new) | Compiled | Speedup (compiled vs v0.7) |\n|---:|---:|---:|---:|---:|\n| 10 | 25.6 ms | 23.3 ms | 11.8 ms | **2.2x** |\n| 50 | 31.5 ms | 29.0 ms | 15.8 ms | **2.0x** |\n\nNote: `use_compile=True` requires PyTorch 2.0+. You cannot wrap `ik.solve()` directly with\n`torch.compile` due to data-dependent control flow in the outer loop — use this flag instead.\n\n## SDF Queries\nSee [pytorch-volumetric](https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_volumetric) for the latest details, some instructions are pasted here:\n\nFor many applications such as collision checking, it is useful to have the\nSDF of a multi-link robot in certain configurations.\nFirst, we create the robot model (loaded from URDF, SDF, MJCF, ...) with\n[pytorch kinematics](https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics).\nFor example, we will be using the KUKA 7 DOF arm model from pybullet data\n\n```python\nimport os\nimport torch\nimport pybullet_data\nimport pytorch_kinematics as pk\nimport pytorch_volumetric as pv\n\nurdf = \"kuka_iiwa\u002Fmodel.urdf\"\nsearch_path = pybullet_data.getDataPath()\nfull_urdf = os.path.join(search_path, urdf)\nchain = pk.build_serial_chain_from_urdf(open(full_urdf).read(), \"lbr_iiwa_link_7\")\nd = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\nchain = chain.to(device=d)\n# paths to the link meshes are specified with their relative path inside the URDF\n# we need to give them the path prefix as we need their absolute path to load\ns = pv.RobotSDF(chain, path_prefix=os.path.join(search_path, \"kuka_iiwa\"))\n```\n\nBy default, each link will have a `MeshSDF`. To instead use `CachedSDF` for faster queries\n\n```python\ns = pv.RobotSDF(chain, path_prefix=os.path.join(search_path, \"kuka_iiwa\"),\n                link_sdf_cls=pv.cache_link_sdf_factory(resolution=0.02, padding=1.0, device=d))\n```\n\nWhich when the `y=0.02` SDF slice is visualized:\n\n![sdf slice](https:\u002F\u002Fi.imgur.com\u002FPutw72A.png)\n\nWith surface points corresponding to:\n\n![wireframe](https:\u002F\u002Fi.imgur.com\u002FL3atG9h.png)\n![solid](https:\u002F\u002Fi.imgur.com\u002FXiAks7a.png)\n\nQueries on this SDF is dependent on the joint configurations (by default all zero).\n**Queries are batched across configurations and query points**. For example, we have a batch of\njoint configurations to query\n\n```python\nth = torch.tensor([0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0], device=d)\nN = 200\nth_perturbation = torch.randn(N - 1, 7, device=d) * 0.1\n# N x 7 joint values\nth = torch.cat((th.view(1, -1), th_perturbation + th))\n```\n\nAnd also a batch of points to query (same points for each configuration):\n\n```python\ny = 0.02\nquery_range = np.array([\n    [-1, 0.5],\n    [y, y],\n    [-0.2, 0.8],\n])\n# M x 3 points\ncoords, pts = pv.get_coordinates_and_points_in_grid(0.01, query_range, device=s.device)\n```\n\nWe set the batch of joint configurations and query:\n\n```python\ns.set_joint_configuration(th)\n# N x M SDF value\n# N x M x 3 SDF gradient\nsdf_val, sdf_grad = s(pts)\n```\n\n\n# Credits\n- `pytorch_kinematics\u002Ftransforms` is extracted from [pytorch3d](https:\u002F\u002Fgithub.com\u002Ffacebookresearch\u002Fpytorch3d) with minor extensions.\nThis was done instead of including `pytorch3d` as a dependency because it is hard to install and most of its code is unrelated.\n  An important difference is that we use left hand multiplied transforms as is convention in robotics (T * pt) instead of their\n  right hand multiplied transforms.\n- `pytorch_kinematics\u002Furdf_parser_py`, and `pytorch_kinematics\u002Fmjcf_parser` is extracted from [kinpy](https:\u002F\u002Fgithub.com\u002Fneka-nat\u002Fkinpy), as well as the FK logic.\nThis repository ports the logic to pytorch, parallelizes it, and provides some extensions.\n","# PyTorch 机器人运动学\n- 并行且可微的正向运动学（FK）、雅可比矩阵计算，以及阻尼最小二乘逆向运动学（IK）\n- 从 URDF、SDF 和 MJCF 格式加载机器人描述\n- 通过 [pytorch-volumetric](https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_volumetric) 实现对不同配置和点的 SDF 查询批量处理\n\n# 安装\n```shell\npip install pytorch-kinematics\n```\n\n如需开发版本，请将仓库克隆至任意位置，然后运行 `pip3 install -e .` 以进入可编辑模式进行安装。\n\n## 参考\n[![DOI](https:\u002F\u002Fzenodo.org\u002Fbadge\u002F331721571.svg)](https:\u002F\u002Fzenodo.org\u002Fbadge\u002Flatestdoi\u002F331721571)\n\n如果您在研究中使用本包，请考虑引用以下文献：\n```\n@software{Zhong_PyTorch_Kinematics_2024,\nauthor = {Zhong, Sheng and Power, Thomas and Gupta, Ashwin and Mitrano, Peter},\ndoi = {10.5281\u002Fzenodo.7700587},\nmonth = feb,\ntitle = {{PyTorch 运动学}},\nversion = {v0.7.1},\nyear = {2024}\n}\n```\n\n# 使用方法\n\n请参阅 `tests` 中的代码示例；部分示例也在此处展示。\n\n## 加载机器人\n```python\nimport pytorch_kinematics as pk\n\nurdf = \"widowx\u002Fwx250s.urdf\"\n# 由于存在多个自然末端执行器链接，因此并非串联链\nchain = pk.build_chain_from_urdf(open(urdf, mode=\"rb\").read())\n# 可视化各帧结构（字符串同样会返回）\nchain.print_tree()\n\"\"\"\nbase_link\n└── shoulder_link\n    └── upper_arm_link\n        └── upper_forearm_link\n            └── lower_forearm_link\n                └── wrist_link\n                    └── gripper_link\n                        └── ee_arm_link\n                            ├── gripper_prop_link\n                            └── gripper_bar_link\n                                └── fingers_link\n                                    ├── left_finger_link\n                                    ├── right_finger_link\n                                    └── ee_gripper_link\n\"\"\"\n\n# 提取特定的串联链，例如用于逆向运动学\nserial_chain = pk.SerialChain(chain, \"ee_gripper_link\", \"base_link\")\nserial_chain.print_tree()\n\"\"\"\nbase_link\n└── shoulder_link\n    └── upper_arm_link\n        └── upper_forearm_link\n            └── lower_forearm_link\n                └── wrist_link\n                    └── gripper_link\n                        └── ee_arm_link\n                            └── gripper_bar_link\n                                └── fingers_link\n                                    └── ee_gripper_link\n\"\"\"\n\n# 您也可以提取与原始链根节点不同的串联链\nserial_chain = pk.SerialChain(chain, \"ee_gripper_link\", \"gripper_link\")\nserial_chain.print_tree()\n\"\"\"\ngripper_link\n└── ee_arm_link\n    └── gripper_bar_link\n        └── fingers_link\n            └── ee_gripper_link\n\"\"\"\n```\n\n## 正向运动学（FK）\n```python\nimport math\nimport pytorch_kinematics as pk\n\n# 从 URDF 加载机器人描述，并指定末端执行器链接\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n# 打印出链接的嵌套树结构\nprint(chain)\n# 打印出关节名称列表\nprint(chain.get_joint_parameter_names())\n\n# 指定关节值（可采用多种形式）\nth = [0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0]\n# 进行正向运动学计算并获取变换对象；若设置 end_only=False，则会返回所有链接的变换矩阵\nret = chain.forward_kinematics(th, end_only=False)\n# 查找特定链接的变换矩阵\ntg = ret['lbr_iiwa_link_7']\n# 获取变换矩阵（1,4,4），随后将其转换为独立的位置和单位四元数\nm = tg.get_matrix()\npos = m[:, :3, 3]\nrot = pk.matrix_to_quaternion(m[:, :3, :3])\n```\n\n我们可以通过传入 2D 关节值来实现 FK 的并行化，同时在可用时也可使用 CUDA。\n```python\nimport torch\nimport pytorch_kinematics as pk\n\nd = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndtype = torch.float64\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\nchain = chain.to(dtype=dtype, device=d)\n\nN = 1000\nth_batch = torch.rand(N, len(chain.get_joint_parameter_names()), dtype=dtype, device=d)\n\n# 在并行环境下，按数量级排序能显著提升运算速度\n# 对于 N=1000，使用并行方式运行时耗时 0.008678913116455078 秒\n# （N,4,4）变换矩阵；默认情况下，仅返回末端执行器的变换矩阵，因为 end_only=True\ntg_batch = chain.forward_kinematics(th_batch)\n\n# 对于 N=1000，串行方式运行时耗时 8.44686508178711 秒\nfor i in range(N):\n    tg = chain.forward_kinematics(th_batch[i])\n```\n\n我们还可以通过 FK 计算梯度。\n```python\nimport torch\nimport math\nimport pytorch_kinematics as pk\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# 需要对输入关节值进行梯度计算\nth = torch.tensor([0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0], requires_grad=True)\ntg = chain.forward_kinematics(th)\nm = tg.get_matrix()\npos = m[:, :3, 3]\npos.norm().backward()\n# 现在 th.grad 已被填充\n```\n\n我们同样可以加载 SDF 和 MJCF 描述，并通过字典形式传递关节值（未指定的关节默认为 th=0），适用于非串联链。\n```python\nimport math\nimport torch\nimport pytorch_kinematics as pk\n\nchain = pk.build_chain_from_sdf(open(\"simple_arm.sdf\").read())\nret = chain.forward_kinematics({'arm_elbow_pan_joint': math.pi \u002F 2.0, 'arm_wrist_lift_joint': -0.5})\n# 请记住，我们需指定关节值并获取链接变换\ntg = ret['arm_wrist_roll']\n\n# 也可以采用并行方式完成此操作\nN = 100\nret = chain.forward_kinematics({'arm_elbow_pan_joint': torch.rand(N, 1), 'arm_wrist_lift_joint': torch.rand(N, 1)})\n# （N, 4, 4）变换对象\ntg = ret['arm_wrist_roll']\n\n# 从 MJCF 文件构建机器人\nchain = pk.build_chain_from_mjcf(open(\"ant.xml\").read())\nprint(chain)\nprint(chain.get_joint_parameter_names())\nth = {'hip_1': 1.0, 'ankle_1': 1}\nret = chain.forward_kinematics(th)\n\nchain = pk.build_chain_from_mjcf(open(\"humanoid.xml\").read())\nprint(chain)\nprint(chain.get_joint_parameter_names())\nth = {'left_knee': 0.0, 'right_knee': 0.0}\nret = chain.forward_kinematics(th)\n```\n\n## torch.compile 支持\n\n通过 `torch.compile(fullgraph=True)` 可对 FK 计算进行编译，从而大幅提升性能，尤其适用于需要多次调用 FK 的应用（例如逆向运动学、轨迹优化等）。\n\n使用 `forward_kinematics_tensor`，这是一种针对编译友好的变体，可接受并返回原始张量，而非字典或 `Transform3d` 对象：\n\n```python\nimport torch\nimport pytorch_kinematics as pk\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# 编译 FK 内核（一次性成本）\ncompiled_fk = torch.compile(chain.forward_kinematics_tensor, fullgraph=True, dynamic=True)\n\n# 输入：(B, n_joints) 张量\nth = torch.randn(1000, 7)\n\n# 输出：(num_frames, B, 4, 4) 张量，包含所有帧的齐次变换矩阵\nall_transforms = compiled_fk(th)\n```\n\n简化后的中文内容：\n\n# 通过帧索引进行查找：使用 `chain.frame_to_idx` 来查询某个帧名称对应的索引\nee_idx = chain.frame_to_idx['lbr_iiwa_link_7']\nee_transform = all_transforms[ee_idx]  # (B, 4, 4)\n```\n\n在 CPU 上的典型加速比（Kuka IIWA 7 自由度机器人）：\n\n| 批次大小 | `forward_kinematics` | 编译后的 `forward_kinematics_tensor` | 加速比 |\n|---:|---:|---:|---:|\n| 1 | 0.21 ms | 0.04 ms | **4.7倍** |\n| 64 | 0.26 ms | 0.08 ms | **3.5倍** |\n| 1024 | 1.13 ms | 0.51 ms | **2.2倍** |\n\n对于具有更多帧数的复杂机器人，加速比会更高（例如，在批次为 1 时，49 帧机器人可实现 6 倍以上的加速）。\n借助 CUDA 图捕获的 GPU 加速，可在较大的批量规模下进一步提升性能。\n\n标准的 `forward_kinematics` 方法（返回 `Dict[str, Transform3d]`）同样受益于经过重构的内部逻辑，无需任何代码变更。与 v0.7 相比，该方法在小批量规模下速度提升了 2–6 倍。\n\n旋转转换函数（如 `matrix_to_quaternion`、`quaternion_to_axis_angle`、`axis_angle_to_quaternion` 等）也兼容 `torch.compile(fullgraph=True)`，可以单独编译，也可以作为更大编译图的一部分进行编译：\n\n```python\nimport torch\nimport pytorch_kinematics as pk\n\n# 编译一个旋转转换函数\ncompiled_m2q = torch.compile(pk.matrix_to_quaternion, fullgraph=True)\nR = torch.randn(100, 3, 3)\nq = compiled_m2q(R)\n```\n\n## 柱坐标计算\n在运动学上下文中，柱坐标矩阵描述了末端执行器随关节值变化而发生的变化情况（其中 ![dx](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FUM-ARM-Lab_pytorch_kinematics_readme_e32ebb39315e.png) 表示扭转量，或堆叠的线速度和角速度）：\n![jacobian](https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FUM-ARM-Lab_pytorch_kinematics_readme_e32ebb39315e.png%3DJ%5Cdot%7Bq%7D)\n\n对于 `SerialChain`，我们提供了一种可微且可并行化的方法，用于计算基于基座框架的柱坐标矩阵。\n```python\nimport math\nimport torch\nimport pytorch_kinematics as pk\n\n# 可以通过选择末端执行器框架，将 Chain 转换为 SerialChain\nchain = pk.build_chain_from_sdf(open(\"simple_arm.sdf\").read())\n# 打印链结构，查看可用的链接，用作末端执行器\n# 请注意，任意链接都可以被选中；不必一定是没有子级的链接\nchain = pk.SerialChain(chain, \"arm_wrist_roll_frame\")\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\nth = torch.tensor([0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0])\n# (1,6,7) 张量，其中 7 代表机器人的自由度\nJ = chain.jacobian(th)\n\n# 并行计算柱坐标矩阵，并在可用时利用 CUDA\nN = 1000\nd = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndtype = torch.float64\n\nchain = chain.to(dtype=dtype, device=d)\n# 柱坐标计算是可微的\nth = torch.rand(N, 7, dtype=dtype, device=d, requires_grad=True)\n# (N,6,7)\nJ = chain.jacobian(th)\n\n# 可以在距离末端执行器一定偏移的位置上获取柱坐标矩阵（位置指定在 EE 框架中）\n# 默认情况下，位置位于 EE 框架的原点\nloc = torch.rand(N, 3, dtype=dtype, device=d)\nJ = chain.jacobian(th, locations=loc)\n```\n\n与 FK 类似，柱坐标矩阵也有一个兼容 `torch.compile` 的变体——`jacobian_tensor`：\n\n```python\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# 编译柱坐标矩阵核函数（一次性成本）\ncompiled_jac = torch.compile(chain.jacobian_tensor, fullgraph=True)\n\n# 输入：(B, n_joints) 张量；输出：(B, 6, n_joints) 柱坐标矩阵\nth = torch.randn(100, 7)\nJ = compiled_jac(th)\n```\n\n为了在紧密循环中获得最佳性能（例如在 IK 中），可向 `torch.compile` 传递 `mode='max-autotune'`，以在编译成本较高的前提下，对核函数进行额外的优化调整。\n\n在 CPU 上的典型加速比（Kuka IIWA 7 自由度机器人，对比旧版 v0.7 的 `calc_jacobian`）：\n\n| 批次大小 | 旧版 `calc_jacobian` | 新版 `jacobian`（即时计算） | 编译后的 `jacobian_tensor` | 编译版与旧版的加速比 |\n|---:|---:|---:|---:|---:|\n| 1 | 0.63 ms | 0.12 ms | 0.03 ms | **21倍** |\n| 10 | 0.79 ms | 0.15 ms | 0.05 ms | **15倍** |\n| 100 | 0.75 ms | 0.30 ms | 0.09 ms | **8倍** |\n| 1,000 | 1.67 ms | 1.23 ms | 0.53 ms | **3倍** |\n| 10,000 | 7.93 ms | 7.01 ms | 4.91 ms | **1.6倍** |\n| 100,000 | 59.42 ms | 64.58 ms | 46.46 ms | **1.3倍** |\n\n在小到中等批量规模下（典型的 IK 应用场景），由于向量化计算取代了每帧的 Python 循环，新版的即时计算实现速度提升了 2–5 倍。\n`torch.compile` 在此基础上又带来了 2–4 倍的性能提升，且在各个批量规模下都优于旧版实现。\n\n柱坐标矩阵可用于逆运动学计算。有关如何进行逆运动学计算的详细信息，请参阅 [IK 综述](https:\u002F\u002Fwww.math.ucsd.edu\u002F~sbuss\u002FResearchWeb\u002Fikmethods\u002Fiksurvey.pdf)。需要注意的是，逆运动学可以通过其他方式更好地完成（不过，通过柱坐标矩阵进行逆运动学计算，可以实现端到端的可微化方法）。\n\n## 逆运动学（IK）\n逆运动学可通过阻尼最小二乘法实现（通过迭代步骤结合柱坐标伪逆，以避免在奇异点附近出现振荡）。与其他逆运动学库相比，其典型优势如下：\n- 不依赖 ROS（许多逆运动学库需要将机器人模型发布至 ROS 参数服务器）\n- 支持目标姿态的批量处理，以及从不同起始配置中进行重试\n- 除了目标位置外，还支持目标方向\n\n![IK](https:\u002F\u002Fi.imgur.com\u002FQgaUME9.gif)\n\n有关使用方法，请参阅 `tests\u002Ftest_inverse_kinematics.py`，但通常您需要以下内容：\n```python\nfull_urdf = os.path.join(search_path, urdf)\nchain = pk.build_serial_chain_from_urdf(open(full_urdf).read(), \"lbr_iiwa_link_7\")\n\n# 目标以 **机器人框架中的 Transform3d 姿态** 进行指定\n# 因此，如果您已将目标以世界坐标系中的姿态进行指定，则还需要将机器人坐标系中的姿态纳入世界坐标系中\npos = torch.tensor([0.0, 0.0, 0.0], device=device)\nrot = torch.tensor([0.0, 0.0, 0.0], device=device)\nrob_tf = pk.Transform3d(pos=pos, rot=rot, device=device)\n\n# 将目标以世界坐标系中的 Transform3d 姿态进行指定\ngoal_in_world_frame_tf = ...\n# 转换为机器人坐标系（如果目标已以机器人坐标系中指定，或若世界坐标系与机器人坐标系一致，则跳过此步骤）\ngoal_in_rob_frame_tf = rob_tf.inverse().compose(goal_tf)\n\n# 获取机器人关节限位\nlim = torch.tensor(chain.get_joint_limits(), device=device)\n\n# 创建 IK 对象\n# 请参阅构造函数，了解更多选项及其说明，例如收敛容差等\nik = pk.PseudoInverseIK(chain, max_iterations=30, num_retries=10,\n                        joint_limits=lim.T,\n                        early_stopping_any_converged=True,\n                        early_stopping_no_improvement=\"all\",\n                        debug=False,\n                        lr=0.2)\n# 解决 IK\nsol = ik.solve(goal_in_rob_frame_tf)\n# 目标数量 × 重试次数 × 关节角度张量；若未收敛，仅显示迄今为止找到的最佳解\nprint(sol.solutions)\n# 目标数量 × 重试次数，可检查每次运行的收敛情况\nprint(sol.converged)\n# 目标数量 × 重试次数，可直接查看误差\nprint(sol.err_pos)\nprint(sol.err_rot)\n```\n\n### 编译 IK\n\n对于那些会反复求解 IK 的工作负载（例如在规划循环中），请在 IK 循环内部，通过 `use_compile=True` 来编译 FK、雅可比矩阵以及阻尼最小二乘核函数。这样可以利用 PyTorch 的编译功能实现高效运行。而外层的 IK 循环及其基于数据的收敛性检查则仍保持在 eager 模式下。\n\n```python\nik = pk.PseudoInverseIK(chain, max_iterations=30, num_retries=10,\n                         joint_limits=lim.T,\n                         early_stopping_any_converged=True,\n                         early_stopping_no_improvement=\"all\",\n                         lr=0.2,\n                         use_compile=True)  # 编译内部核函数\n\n# 第一次调用 solve() 会花费一次编译成本；后续调用则会更快\nsol = ik.solve(goal_in_rob_frame_tf)\n```\n\n在 CPU 上的典型加速效果（Kuka IIWA 7 自由度，30 次迭代）：\n\n| 重试次数 | Eager (v0.7) | Eager (新版本) | 编译后 | 编译与 v0.7 相比的加速比 |\n|---:|---:|---:|---:|---:|\n| 10 | 25.6 ms | 23.3 ms | 11.8 ms | **2.2x** |\n| 50 | 31.5 ms | 29.0 ms | 15.8 ms | **2.0x** |\n\n注意：`use_compile=True` 需要 PyTorch 2.0+。由于外层循环中存在依赖于数据的控制流，您无法直接使用 `torch.compile` 来包装 `ik.solve()`——请改用此标志。\n\n## SDF 查询\n最新详情请参见 [pytorch-volumetric](https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_volumetric)，部分说明已粘贴在此处：\n\n对于许多应用，例如碰撞检测，掌握多连杆机器人在特定配置下的 SDF 是非常有用的。\n首先，我们通过 [PyTorch 运动学](https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics) 创建机器人模型，并从 URDF、SDF、MJCF 等格式中加载模型。\n例如，我们将使用 pybullet 数据中的 KUKA 7 自由度机械臂模型。\n\n```python\nimport os\nimport torch\nimport pybullet_data\nimport pytorch_kinematics as pk\nimport pytorch_volumetric as pv\n\nurdf = \"kuka_iiwa\u002Fmodel.urdf\"\nsearch_path = pybullet_data.getDataPath()\nfull_urdf = os.path.join(search_path, urdf)\nchain = pk.build_serial_chain_from_urdf(open(full_urdf).read(), \"lbr_iiwa_link_7\")\nd = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n\nchain = chain.to(device=d)\n# 连杆网格文件的路径是根据其在 URDF 中的相对路径来指定的。为了正确加载这些文件，我们需要为它们提供路径前缀。\ns = pv.RobotSDF(chain, path_prefix=os.path.join(search_path, \"kuka_iiwa\"))\n```\n\n默认情况下，每个连杆都会拥有一个 `MeshSDF`。若希望使用 `CachedSDF` 以提升查询速度，则可以这样做：\n\n```python\ns = pv.RobotSDF(chain, path_prefix=os.path.join(search_path, \"kuka_iiwa\"),\n                link_sdf_cls=pv.cache_link_sdf_factory(resolution=0.02, padding=1.0, device=d))\n```\n\n当可视化 `y=0.02` 的 SDF 切片时：\n\n![sdf 切片](https:\u002F\u002Fi.imgur.com\u002FPutw72A.png)\n\n其中，表面点对应如下：\n\n![线框图](https:\u002F\u002Fi.imgur.com\u002FL3atG9h.png)\n![实体图](https:\u002F\u002Fi.imgur.com\u002FXiAks7a.png)\n\n对这一 SDF 的查询会根据关节配置进行调整（默认情况下，所有关节配置均为零）。\n**查询会针对不同配置和查询点进行批量处理**。例如，我们有一组需要查询的关节配置：\n\n```python\nth = torch.tensor([0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0], device=d)\nN = 200\nth_perturbation = torch.randn(N - 1, 7, device=d) * 0.1\n# N x 7 个关节值\nth = torch.cat((th.view(1, -1), th_perturbation + th))\n```\n\n此外，我们还有一组需要查询的点（每组配置对应的点相同）：\n\n```python\ny = 0.02\nquery_range = np.array([\n    [-1, 0.5],\n    [y, y],\n    [-0.2, 0.8],\n])\n# M x 3 个点\ncoords, pts = pv.get_coordinates_and_points_in_grid(0.01, query_range, device=s.device)\n```\n\n我们设置了关节配置和查询的批量参数：\n\n```python\ns.set_joint_configuration(th)\n# N x M 个 SDF 值\n# N x M x 3 个 SDF 偏导数\nsdf_val, sdf_grad = s(pts)\n```\n\n# 资助来源\n- `pytorch_kinematics\u002Ftransforms` 从 [pytorch3d](https:\u002F\u002Fgithub.com\u002Ffacebookresearch\u002Fpytorch3d) 中提取而来，并进行了少量扩展。\n之所以选择不将 `pytorch3d` 作为依赖项，是因为它安装起来较为困难，且大部分代码与我们的需求并无直接关联。\n一个重要的区别在于，我们在机器人学中沿用左乘变换的方式（T * pt），而非右乘变换。\n- `pytorch_kinematics\u002Furdf_parser_py` 和 `pytorch_kinematics\u002Fmjcf_parser` 分别源自 [kinpy](https:\u002F\u002Fgithub.com\u002Fneka-nat\u002Fkinpy)，并结合了 FK 逻辑。该仓库将这些逻辑移植到 PyTorch 中，实现了并行化，并提供了一些扩展功能。","# pytorch_kinematics 快速上手指南\n\n`pytorch_kinematics` 是一个基于 PyTorch 的机器人运动学库，支持并行化、可微分的前向运动学（FK）、雅可比矩阵计算以及阻尼最小二乘法逆运动学（IK）。它可以直接从 URDF、SDF 和 MJCF 文件加载机器人描述，并充分利用 GPU 加速。\n\n## 环境准备\n\n*   **操作系统**：Linux, macOS, Windows\n*   **Python 版本**：建议 Python 3.8+\n*   **核心依赖**：\n    *   `torch` (PyTorch)\n    *   `numpy`\n*   **可选依赖**：若需使用 `torch.compile` 加速功能，建议使用较新版本的 PyTorch (2.0+)。\n\n## 安装步骤\n\n### 1. 基础安装\n通过 pip 直接安装稳定版：\n\n```shell\npip install pytorch-kinematics\n```\n\n> **提示**：国内用户如遇下载缓慢，可使用清华或阿里镜像源加速：\n> ```shell\n> pip install pytorch-kinematics -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n> ```\n\n### 2. 开发模式安装\n如需修改源码或贡献代码，可克隆仓库后以可编辑模式安装：\n\n```shell\ngit clone https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics.git\ncd pytorch_kinematics\npip3 install -e .\n```\n\n## 基本使用\n\n以下示例展示如何加载 URDF 文件并执行前向运动学（FK）计算。\n\n### 1. 加载机器人与前向运动学 (FK)\n\n```python\nimport math\nimport torch\nimport pytorch_kinematics as pk\n\n# 1. 从 URDF 文件构建串联链 (SerialChain)\n# 指定末端执行器链接名称，例如 \"lbr_iiwa_link_7\"\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# 查看关节参数名称\nprint(chain.get_joint_parameter_names())\n\n# 2. 定义关节角度 (弧度制)\nth = [0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0]\n\n# 3. 执行前向运动学计算\n# end_only=False 会返回所有链接的变换字典，默认为 True 仅返回末端\nret = chain.forward_kinematics(th, end_only=False)\n\n# 4. 获取末端变换矩阵并解析位置和姿态\ntg = ret['lbr_iiwa_link_7']\nm = tg.get_matrix()  # 形状: (1, 4, 4)\n\n# 提取位置 (x, y, z)\npos = m[:, :3, 3]\n\n# 提取旋转矩阵并转换为四元数\nrot = pk.matrix_to_quaternion(m[:, :3, :3])\n\nprint(f\"Position: {pos}\")\nprint(f\"Quaternion: {rot}\")\n```\n\n### 2. 批量计算与 GPU 加速\n\n该库支持批量处理关节数据以利用并行计算，并可自动使用 CUDA。\n\n```python\nimport torch\nimport pytorch_kinematics as pk\n\n# 选择设备\ndevice = \"cuda\" if torch.cuda.is_available() else \"cpu\"\ndtype = torch.float64\n\n# 构建链并移至指定设备和精度\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\nchain = chain.to(dtype=dtype, device=device)\n\n# 生成批量关节数据 (Batch Size = 1000)\nN = 1000\nth_batch = torch.rand(N, len(chain.get_joint_parameter_names()), dtype=dtype, device=device)\n\n# 并行执行 FK (速度远快于循环调用)\ntg_batch = chain.forward_kinematics(th_batch)\n\nprint(f\"Batch result shape: {tg_batch.get_matrix().shape}\")\n```\n\n### 3. 可微分特性 (用于梯度下降\u002F优化)\n\n由于基于 PyTorch，所有运动学计算均可自动求导，适用于轨迹优化或学习型逆运动学。\n\n```python\nimport torch\nimport math\nimport pytorch_kinematics as pk\n\nchain = pk.build_serial_chain_from_urdf(open(\"kuka_iiwa.urdf\").read(), \"lbr_iiwa_link_7\")\n\n# 设置 requires_grad=True 以追踪梯度\nth = torch.tensor([0.0, -math.pi \u002F 4.0, 0.0, math.pi \u002F 2.0, 0.0, math.pi \u002F 4.0, 0.0], requires_grad=True)\n\ntg = chain.forward_kinematics(th)\nm = tg.get_matrix()\npos = m[:, :3, 3]\n\n# 计算位置范数的梯度\nloss = pos.norm()\nloss.backward()\n\n# th.grad 现在包含关节角度对位置损失的梯度\nprint(f\"Gradients: {th.grad}\")\n```","某机器人实验室团队正在开发基于深度强化学习的机械臂抓取策略，需要在一个仿真环境中每秒对数千种不同的关节配置进行正向运动学解算和雅可比矩阵计算，以训练神经网络预测最佳抓取姿态。\n\n### 没有 pytorch_kinematics 时\n- **计算效率低下**：传统库（如 KDL 或 Pinocchio）通常基于 CPU 串行计算，面对批量数据时速度极慢，无法满足深度学习训练的高吞吐需求。\n- **梯度断裂难题**：现有工具难以直接提供可微分的运动学接口，研究人员需手动推导复杂的反向传播公式或使用黑盒数值微分，导致策略网络无法通过端到端方式优化。\n- **开发流程割裂**：需要在 Python 逻辑与底层 C++ 运动学引擎之间频繁切换数据格式，且难以利用 GPU 加速，代码维护成本高且易出错。\n- **模型适配繁琐**：每次更换机器人模型（如从 URDF 切换到 MJCF），都需要重写大量解析代码，缺乏统一的标准化加载接口。\n\n### 使用 pytorch_kinematics 后\n- **并行加速显著**：直接利用 PyTorch 的批处理能力，在 GPU 上并行计算成千上万个构型的正向运动学和雅可比矩阵，推理速度提升数十倍。\n- **原生支持自动微分**：内置的可微分 IK 和 FK 模块让梯度能够自然流过运动学链条，实现了从传感器输入到关节控制指令的端到端训练。\n- **生态无缝集成**：作为纯 PyTorch 实现，它能直接与现有的深度学习管道融合，无需数据拷贝即可在 CUDA 设备上运行，大幅简化了代码架构。\n- **多格式灵活加载**：支持一键加载 URDF、SDF 和 MJCF 等多种主流机器人描述文件，快速提取串联链，极大缩短了不同机型的适配周期。\n\npytorch_kinematics 通过将机器人运动学转化为高效的张量运算，彻底打通了传统控制理论与现代深度学习之间的性能与梯度壁垒。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002FUM-ARM-Lab_pytorch_kinematics_9b9ce31a.png","UM-ARM-Lab","The Autonomous Robotic Manipulation Lab","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002FUM-ARM-Lab_03cebfda.png","The Autonomous Robotic Manipulation Lab studies motion planning, manipulation, and human-robot collaboration.",null,"arm.eecs.umich.edu","https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab",[83,87],{"name":84,"color":85,"percentage":86},"Python","#3572A5",78.5,{"name":88,"color":89,"percentage":90},"Jupyter Notebook","#DA5B0B",21.5,789,69,"2026-04-03T11:20:25","MIT",1,"未说明","非必需。支持 CUDA 加速（若可用），具体显卡型号、显存大小及 CUDA 版本未在文档中指定。",{"notes":99,"python":96,"dependencies":100},"该工具是一个纯 PyTorch 实现的机器人运动学库，支持通过 pip 直接安装。它利用 PyTorch 的自动微分功能进行可微分的正向运动学、雅可比矩阵计算和阻尼最小二乘逆运动学。支持 URDF、SDF 和 MJCF 格式的机器人描述文件加载。可通过 torch.compile 进一步加速计算。文档未明确列出最低 Python 版本或操作系统限制，通常意味着兼容主流支持 PyTorch 的环境（Linux, macOS, Windows）。",[101,102],"torch","pytorch-volumetric (可选，用于 SDF 查询)",[13,54],[105,106,107,108,109],"differentiable-programming","jacobian","kinematics","pytorch","robotics","2026-03-27T02:49:30.150509","2026-04-06T11:31:13.945969",[113,118,123,128,133,138],{"id":114,"question_zh":115,"answer_zh":116,"source_url":117},6566,"如何让代码支持 torch.compile 编译或导出为 ONNX 格式？","最新版本已修复 `.item()` 等导致图断裂的操作，支持 `torch.compile` 和 ONNX 导出。对于逆运动学（IK），可以通过设置 `use_compile=True` 来启用编译加速：\n```python\nik = pk.PseudoInverseIK(chain, max_iterations=30, num_retries=10,\n                         joint_limits=lim.T,\n                         early_stopping_any_converged=True,\n                         early_stopping_no_improvement=\"all\",\n                         lr=0.2,\n                         use_compile=True)  # 编译内部内核\nsol = ik.solve(goal_in_rob_frame_tf)\n```\n注意：第一次调用 `solve()` 会产生一次性编译开销，后续调用速度将提升约 2 倍。雅可比矩阵计算也已支持编译，在小到中等批量大小下速度提升显著。","https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics\u002Fissues\u002F66",{"id":119,"question_zh":120,"answer_zh":121,"source_url":122},6567,"在使用 Franka Panda 机器人进行逆运动学求解时，为什么无法收敛（converged 为 False）？","这通常是因为从包含非线性分支（如夹爪）的 URDF 构建串行链（serial chain）时，末端执行器帧仍然关联了后续的非线性部分关节。如果 URDF 中包含 9 个驱动关节（7 个自由度 + 2 个夹爪关节），容易导致此问题。\n解决方案：\n1. 升级到 v0.7.3 或更高版本，该版本已修复此逻辑错误。\n2. 或者，使用仅包含 7 个驱动关节的简化版 URDF 文件进行测试。\n参考示例脚本和 URDF：https:\u002F\u002Fgist.github.com\u002Fwilliamshen-nz\u002Fabb8bd1aaf91499741aaacb3a87f22dd","https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics\u002Fissues\u002F36",{"id":124,"question_zh":125,"answer_zh":126,"source_url":127},6568,"如何处理具有复杂运动学树（非线性的多分支结构）的机器人，特别是当某些活动关节不影响目标连杆时？","对于包含“虚拟”连杆或多分支结构的复杂运动学树，`PseudoInverseIK` 需要忽略那些不是目标连杆祖先的活动关节。维护者已在后续更新中改进了对这类结构的支持（例如添加了 wx250s 作为测试用例）。\n如果您遇到收敛问题，请确保：\n1. 使用最新版本，其中包含了对非线形运动学树的更好处理。\n2. 检查是否正确地构建了串行链，确保只包含影响目标末端执行器的相关关节路径。\n3. 如有必要，可以参考社区提供的测试用例（如 `test_serial_chain_creation.py`）来验证您的 URDF 配置。","https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics\u002Fissues\u002F42",{"id":129,"question_zh":130,"answer_zh":131,"source_url":132},6569,"如何解除对 numpy 版本的限制以支持 numpy 2.0 及以上版本？","该限制已在版本 0.7.6 中解除。请升级 `pytorch_kinematics` 到 0.7.6 或更高版本即可支持 numpy 2.0+。\n命令：\n```bash\npip install --upgrade pytorch_kinematics\n```\n如果 PyPI 上的版本未更新，请检查 `setup.py` 或直接安装 GitHub 上的最新代码。","https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics\u002Fissues\u002F54",{"id":134,"question_zh":135,"answer_zh":136,"source_url":137},6570,"使用 `build_chain_from_mjcf` 读取 MuJoCo 模型时报错 `KeyError: 'slide'` 怎么办？","这是因为当前的 `JOINT_TYPE_MAP` 映射字典中只定义了 `'hinge': 'revolute'`，不支持 MuJoCo 中的 `'slide'`（滑动关节）类型。\n解决方法：\n您需要手动修改 `pytorch_kinematics\u002Fmjcf.py` 文件，在 `JOINT_TYPE_MAP` 字典中添加对 `'slide'` 类型的支持，将其映射为 `'prismatic'`（移动关节）：\n```python\nJOINT_TYPE_MAP = {\n    'hinge': 'revolute',\n    'slide': 'prismatic',  # 添加此行\n    # 其他类型...\n}\n```\n修改后重新运行即可解析包含滑动关节的 MJCF 文件。","https:\u002F\u002Fgithub.com\u002FUM-ARM-Lab\u002Fpytorch_kinematics\u002Fissues\u002F9",{"id":139,"question_zh":140,"answer_zh":141,"source_url":117},6571,"编译后的雅可比矩阵计算性能提升有多少？","在新的实现中，雅可比矩阵计算经过向量化优化，即使不使用编译，在小到中等批量大小下也比旧版本快 2-5 倍。结合 `torch.compile` 后，性能提升更加显著：\n- 批量大小为 1 时：加速约 21 倍（从 0.63ms 降至 0.03ms）\n- 批量大小为 10 时：加速约 15 倍\n- 批量大小为 100 时：加速约 8 倍\n- 批量大小为 1,000 时：加速约 3 倍\n随着批量增大，加速比逐渐降低，但在大规模批处理下仍有 1.3-1.6 倍的提升。",[143,148,153,158,163,168,173,178,183],{"id":144,"version":145,"summary_zh":146,"released_at":147},115832,"v0.9.1","## Bug fix\n\n- **Require `torch>=2.1`** — v0.9.0 introduced `torch.compiler.is_compiling()` and `torch.compile` usage without specifying a minimum torch version, causing `AttributeError` for users on older torch installations.","2026-03-15T09:13:36",{"id":149,"version":150,"summary_zh":151,"released_at":152},115833,"v0.9.0","## Highlights\n\n- **`torch.compile` support**: New `forward_kinematics_tensor` and `jacobian_tensor` APIs are fully compatible with `torch.compile(fullgraph=True)`\n- **Improved IK convergence**: Adaptive Levenberg-Marquardt damping boosts single-retry convergence by ~20 percentage points\n- **IK refactoring**: Bug fixes, dead code removal, eliminated redundant FK calls\n\n## New APIs\n\n- `Chain.forward_kinematics_tensor(th)` — returns `(num_frames, B, 4, 4)` tensor, compile-compatible\n- `SerialChain.jacobian_tensor(th)` — returns `(B, 6, DOF)` Jacobian, compile-compatible\n- `PseudoInverseIK` new parameters: `lm_damping`, `position_weight`, `orientation_weight`, `clamp_to_limits`\n\n## torch.compile support\n\nForward kinematics, Jacobian, and rotation conversions (`matrix_to_quaternion`, `quaternion_to_axis_angle`, `axis_angle_to_quaternion`) are now compatible with `torch.compile(fullgraph=True)`. Boolean indexing patterns were replaced with `torch.where`, `torch.gather`, and `torch.clamp`.\n\n```python\nchain = pk.build_serial_chain_from_urdf(urdf, \"end_effector\")\nfk_compiled = torch.compile(chain.forward_kinematics_tensor, fullgraph=True)\njac_compiled = torch.compile(chain.jacobian_tensor, fullgraph=True)\n```\n\nThe IK solver also supports `use_compile=True` to compile the FK, Jacobian, and IK step kernels.\n\n## IK improvements\n\n- **Adaptive LM damping** (`lm_damping=0.1` default): Scales regularization by error magnitude — large errors get more damping (stable), small errors get less (fast convergence)\n- **Default learning rate** changed from 0.2 to 1.0\n- **Bug fixes**: hardcoded Adam optimizer, line search crash on non-converged problems, dtype mismatch with non-default dtypes\n- **Per-coordinate weighting**: `position_weight` and `orientation_weight` parameters for task-specific tuning\n- **Fused IK kernel**: `delta_pose` + DLS solve in a single function, compilable with `torch.compile`\n\n## Performance\n\nAll benchmarks: Kuka IIWA 7-DOF, 500 goals, 30 iterations. GPU is NVIDIA RTX 4070.\n\n### FK & Jacobian (B=500)\n\n| | v0.8.0 | v0.9.0 eager | v0.9.0 compiled |\n|---|---|---|---|\n| **CPU FK** | 2.07ms | 1.09ms (1.9x) | 0.52ms (4.0x) |\n| **CPU Jacobian** | 5.51ms | 1.36ms (4.1x) | 0.59ms (9.3x) |\n| **GPU FK** | 1.45ms | 0.64ms (2.3x) | 0.32ms (4.5x) |\n| **GPU Jacobian** | 2.76ms | 0.75ms (3.7x) | 0.36ms (7.7x) |\n\n### IK — 500 goals, 10 retries\n\n| | v0.8.0 | v0.9.0 eager | v0.9.0 compiled |\n|---|---|---|---|\n| **CPU** | 614ms, 99.6% | 140ms, 99.8% (4.4x) | 92ms, 99.8% (6.7x) |\n| **GPU** | 387ms, 98.8% | 76ms, 99.4% (5.1x) | 51ms, 99.4% (7.6x) |\n\n### IK — 500 goals, 1 retry (hardest case)\n\n| | v0.8.0 | v0.9.0 eager | v0.9.0 compiled |\n|---|---|---|---|\n| **CPU** | 239ms, 67.4% | 70ms, 89.4% (3.4x) | 32ms, 89.4% (7.5x) |\n| **GPU** | 263ms, 71.0% | 51ms, 75.2% (5.2x) | 24ms, 75.2% (11.0x) |\n\n## Bug fixes\n\n- Fixed SerialChain crash when all joints are fixed (0 DOF)\n- Fixed IKSolution dtype mismatch when chain uses non-default dtype\n- Fixed line search crash on non-converged problems\n- Eliminated redundant FK calls in IK loop and Jacobian wrapper","2026-03-11T22:05:29",{"id":154,"version":155,"summary_zh":156,"released_at":157},115834,"v0.8.0","## What's New\n\n### Bug fixes\n- **IK convergence bugs fixed**: stale error check, non-sticky convergence, early stopping init (#48)\n- **IK solutions now respect joint limits**: wrap revolute joints by 2*pi + clamped refinement (#48)\n- **SerialChain root_frame_name fix**: no longer includes parent joint when root is non-root (#62)\n- **Jacobian with link offsets**: supports link offsets in Jacobian calculation (#57, #14)\n- **Transform3d dtype mismatch**: fix matrix broadcast dtype issue (#47)\n- **Documentation**: fix composition order docs (#46)\n\n### Other changes\n- Drop Python 3.8 support; add 3.11 and 3.12 to CI\n- Pin mujoco\u003C=3.3.7 for Python 3.9 compatibility\n- Minimum Python version is now 3.9","2026-03-04T06:55:19",{"id":159,"version":160,"summary_zh":161,"released_at":162},115835,"v0.7.6","Relax numpy version requirement due to fixed incompatibility from 3rd party library","2025-10-16T21:43:24",{"id":164,"version":165,"summary_zh":166,"released_at":167},115836,"v0.7.4","Fix serial chain construction from chains not removing unused branches with wx250s IK test contributions from @StoneT2000 ","2024-08-29T23:44:16",{"id":169,"version":170,"summary_zh":171,"released_at":172},115837,"v0.7.3","Add capsule primitive type and other fixes by Stone Tao.","2024-08-22T21:20:05",{"id":174,"version":175,"summary_zh":176,"released_at":177},115838,"v0.7.1","Batch-to-Batch transforms (N transforms applied to N points with 1-to-1 correspondence rather than all-to-all)\r\nSE(3) conversions to 9D continuous representation suitable for training networks on and back\r\nQuaternion distances and slerp","2024-07-08T18:46:28",{"id":179,"version":180,"summary_zh":181,"released_at":182},115839,"v0.6.1","Implement damped least squares IK","2024-02-16T22:17:40",{"id":184,"version":185,"summary_zh":186,"released_at":187},115840,"v0.5.4","First citable release","2023-03-06T03:19:06"]