* 新增 J519 实发采样器,按 8ms 周期生成 timing/jerk 诊断行并完成 rad->deg 转换 * 兼容层产物导出补充 speedRatio,规划编排补齐 smoothStartStopTiming 与日志透传 * 配置与机型加载切换到运行目录 JSON 模型,并补齐 7L 展开模型与相关单元测试
173 lines
5.0 KiB
C#
173 lines
5.0 KiB
C#
using System.Text.Json.Serialization;
|
||
|
||
namespace Flyshot.Core.Domain;
|
||
|
||
/// <summary>
|
||
/// 描述机器人运动学链所需的完整关节几何信息,从现场固化的机器人 JSON 中提取。
|
||
///
|
||
/// 为什么与 RobotProfile 分开?
|
||
/// ---
|
||
/// RobotProfile 只存规划侧需要的限速和 couple 元数据,是"规划约束视图"。
|
||
/// RobotKinematicsModel 存的是几何链(origin、axis、变换顺序),是"运动学视图"。
|
||
/// 两者生命周期和用途不同,分开可以避免规划层被迫依赖完整几何数据。
|
||
/// </summary>
|
||
public sealed class RobotKinematicsModel
|
||
{
|
||
/// <summary>
|
||
/// 初始化一份已验证的运动学模型。
|
||
/// </summary>
|
||
public RobotKinematicsModel(string name, IEnumerable<RobotJointGeometry> joints)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(name))
|
||
{
|
||
throw new ArgumentException("机器人名称不能为空。", nameof(name));
|
||
}
|
||
|
||
ArgumentNullException.ThrowIfNull(joints);
|
||
|
||
var copiedJoints = joints.ToArray();
|
||
if (copiedJoints.Length == 0)
|
||
{
|
||
throw new ArgumentException("关节列表不能为空。", nameof(joints));
|
||
}
|
||
|
||
Name = name;
|
||
Joints = copiedJoints;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取机器人名称。
|
||
/// </summary>
|
||
[JsonPropertyName("name")]
|
||
public string Name { get; }
|
||
|
||
/// <summary>
|
||
/// 获取按运动学链顺序排列的关节几何列表。
|
||
/// </summary>
|
||
[JsonPropertyName("joints")]
|
||
public IReadOnlyList<RobotJointGeometry> Joints { get; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 描述单个关节的几何属性,用于正运动学计算。
|
||
/// </summary>
|
||
public sealed class RobotJointGeometry
|
||
{
|
||
/// <summary>
|
||
/// 初始化一份已验证的关节几何描述。
|
||
/// </summary>
|
||
public RobotJointGeometry(
|
||
string name,
|
||
string parent,
|
||
string child,
|
||
int jointType,
|
||
double[] axis,
|
||
double[] originXyz,
|
||
double[] originQuatXyzw,
|
||
string? coupleMaster = null,
|
||
double coupleMultiplier = 0.0,
|
||
double coupleOffset = 0.0)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(name))
|
||
{
|
||
throw new ArgumentException("关节名称不能为空。", nameof(name));
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(parent))
|
||
{
|
||
throw new ArgumentException("父节点名称不能为空。", nameof(parent));
|
||
}
|
||
|
||
if (string.IsNullOrWhiteSpace(child))
|
||
{
|
||
throw new ArgumentException("子节点名称不能为空。", nameof(child));
|
||
}
|
||
|
||
if (axis is null || axis.Length != 3)
|
||
{
|
||
throw new ArgumentException("关节轴必须是长度为 3 的数组。", nameof(axis));
|
||
}
|
||
|
||
if (originXyz is null || originXyz.Length != 3)
|
||
{
|
||
throw new ArgumentException("原点平移必须是长度为 3 的数组。", nameof(originXyz));
|
||
}
|
||
|
||
if (originQuatXyzw is null || originQuatXyzw.Length != 4)
|
||
{
|
||
throw new ArgumentException("原点旋转四元数必须是长度为 4 的数组(xyzw)。", nameof(originQuatXyzw));
|
||
}
|
||
|
||
Name = name;
|
||
Parent = parent;
|
||
Child = child;
|
||
JointType = jointType;
|
||
Axis = (double[])axis.Clone();
|
||
OriginXyz = (double[])originXyz.Clone();
|
||
OriginQuatXyzw = (double[])originQuatXyzw.Clone();
|
||
CoupleMaster = coupleMaster;
|
||
CoupleMultiplier = coupleMultiplier;
|
||
CoupleOffset = coupleOffset;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取关节名称。
|
||
/// </summary>
|
||
[JsonPropertyName("name")]
|
||
public string Name { get; }
|
||
|
||
/// <summary>
|
||
/// 获取父连杆名称。
|
||
/// </summary>
|
||
[JsonPropertyName("parent")]
|
||
public string Parent { get; }
|
||
|
||
/// <summary>
|
||
/// 获取子连杆名称。
|
||
/// </summary>
|
||
[JsonPropertyName("child")]
|
||
public string Child { get; }
|
||
|
||
/// <summary>
|
||
/// 获取关节类型:0=fixed, 1=prismatic, 2=revolute。
|
||
/// </summary>
|
||
[JsonPropertyName("jointType")]
|
||
public int JointType { get; }
|
||
|
||
/// <summary>
|
||
/// 获取关节旋转轴(单位向量)。
|
||
/// </summary>
|
||
[JsonPropertyName("axis")]
|
||
public double[] Axis { get; }
|
||
|
||
/// <summary>
|
||
/// 获取关节原点平移 [x, y, z]。
|
||
/// </summary>
|
||
[JsonPropertyName("originXyz")]
|
||
public double[] OriginXyz { get; }
|
||
|
||
/// <summary>
|
||
/// 获取关节原点旋转四元数 [x, y, z, w]。
|
||
/// </summary>
|
||
[JsonPropertyName("originQuatXyzw")]
|
||
public double[] OriginQuatXyzw { get; }
|
||
|
||
/// <summary>
|
||
/// 获取耦合主关节名称(如无则为 null)。
|
||
/// </summary>
|
||
[JsonPropertyName("coupleMaster")]
|
||
public string? CoupleMaster { get; }
|
||
|
||
/// <summary>
|
||
/// 获取耦合乘数。
|
||
/// </summary>
|
||
[JsonPropertyName("coupleMultiplier")]
|
||
public double CoupleMultiplier { get; }
|
||
|
||
/// <summary>
|
||
/// 获取耦合偏移。
|
||
/// </summary>
|
||
[JsonPropertyName("coupleOffset")]
|
||
public double CoupleOffset { get; }
|
||
}
|