动画
7 动画接口与数据模型
动画数据描述实体及其运动部位随仿真时间的变化,包括载具行驶与旋转、提升机升降、堆垛机行走与货叉动作,以及货物承载。先读取快照建立状态,再按游标应用增量。REAL_TIME 和 EVENT_DRIVEN 产生动画;FULL_SPEED 不产生新的动画增量。
每条动作包含实体名称、实体类型、动作类型和发生时刻,并只携带该动作需要的字段。例如,Carrier 行驶使用有序路线,Lift 升降使用起终高度,Stacker 伸叉使用货叉局部起终位置。调用方将实体名称及资源引用绑定到对应的三维模型。
7.1 获取动画快照
GET /simulations/{simulationId}/animation/snapshot
请求无请求体。响应提供当前实体状态、路径几何、资源引用、未结束的运动及对应游标。取得快照后,应整体替换本地动画状态,再从该游标读取增量。
| 响应字段 | 类型 | 说明 |
|---|---|---|
simulationId | 字符串 | 所属仿真实例 |
coordinates | 对象 | 右手坐标系、Y 向上、米、以度表示的 XYZ 欧拉角;详见第 7.3 节 |
clock | 对象 | 仿真时刻、运行模式、倍速、暂停及流控状态 |
cursor | 对象 | generation 为代次,sequence 为非负整数序号 |
assets | 数组 | assetId 与 sourceObjectName,用于绑定预先准备的模型资源;不包含模型文件 |
entities | 数组 | 实体名称、类型、资源绑定、当前位姿、设备状态及 supportedActions;详见第 7.8 节 |
points | 数组 | 路线中可引用的点,每项含 name、position |
paths | 数组 | 路径名称、起终点、长度及几何;详见第 7.4 节 |
motions | 数组 | 各运动部位当前未结束的动作,使用与增量相同的动作结构 |
entities 中的位姿是快照时刻的状态,motions 中的起点是该动作最初开始时的状态。中途接入应按快照时钟计算已过时间,不能从动作起点重新播放。快照示例中 Carrier1 已运行 4 秒,当前位于 x=4 米,尚未结束的行驶仍保留 0 秒开始、持续 10 秒的完整定义。
7.2 查询动画增量
POST /simulations/{simulationId}/animation/updates/query
| 请求字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
cursor | 对象 | 是 | 上次快照的 cursor 或增量的 nextCursor;generation、sequence 均必填 |
limit | 整数 | 否 | 批次数量,1~500,默认 100;同时受响应字节上限约束 |
| 响应字段 | 类型 | 说明 |
|---|---|---|
simulationId、clock | 字符串、对象 | 所属实例及读取时的时钟 |
nextCursor | 对象 | 成功应用全部返回批次后保存的游标;无批次时不推进序号 |
oldestAvailableSequence | 整数 | 保留窗口内最早的批次序号 |
latestSequence | 整数 | 当前已发布的最新序号 |
hasMore | 布尔值 | true 时继续使用 nextCursor 查询 |
batches | 数组 | 每项含 sequence、assets、events;批次不可拆分 |
先登记批次 assets,再按 events 的数组顺序应用全部动作,完成后保存游标。已应用过的批次忽略,不同读取者独立保存游标。同一仿真时刻可能有先停止后恢复、收叉与承载等多个动作,不能仅按时间排序而改变数组顺序。
没有新数据时 batches=[],仍可读取 clock。遇到 VISUALIZATION_GENERATION_CHANGED 或 VISUALIZATION_CURSOR_EXPIRED,应重新取得快照。读取失败时保留原游标;错误不等于没有动作。
下例延续快照游标:Carrier1 在仿真 5.6 秒停止于 PathA 中途。虽然先前行驶的目标为 x=10 米,应用 STOP 后应保持 x=5.6 米。
7.3 公共字段 坐标与时钟
| 动作字段 | 类型 | 说明 |
|---|---|---|
entityName | 字符串 | 动作所属实体的名称,与快照关联;不可通过名称格式推断父子关系 |
entityType | 字符串 | 实体类型,例如 CARRIER、LIFT、STACKER |
animationType | 字符串 | 动作类别,决定其适用字段和运动部位 |
simulationTimeMicros | 整数 | 动作开始或即时状态生效的仿真微秒 |
durationSeconds | 数值 | 持续运动的仿真秒数,必须为正;停止、即时承载和位姿观测不使用此字段 |
position/rotation 表示世界位置和朝向。localPosition/localRotation 表示相对父实体或指定运动部位的位置和朝向,参考对象在对应动作中明确。长度单位为米,角度单位为度,静态位姿采用内禀 XYZ 欧拉角顺序。Carrier 的平面朝向为绕 Y 轴旋转。方向由有符号角度或局部坐标表达,不使用无观察方向定义的“顺时针”字段。
位置和角度均为含 x、y、z 三个有限数值的对象。动作表格及示例中列出的字段均为该动作必填字段,明确标为可选或条件提供的字段除外。不同动作不适用的字段省略,不使用 null 或空对象占位。
durationSeconds 始终使用仿真时间,不预先除以倍速。maxSpeed、initialSpeed 的单位为米/仿真秒;acceleration、deceleration 为米/仿真秒²。运行倍速改变时间推进,不改变已经收到的动作时长和速度参数。
| clock 字段 | 说明 |
|---|---|
simulationTimeMicros | 本次采样的仿真时刻 |
sampledAt | 采样的 UTC 时间 |
status、runMode | 实例状态与运行模式 |
speedMultiplier | REAL_TIME、EVENT_DRIVEN 的运行倍速 |
advancing | false 时停止外推动画时间,并保持当前进度 |
flowControl | NONE 或 ANIMATION_BACKPRESSURE |
以返回的仿真时钟为准推进动画,结合 sampledAt 和倍速作显示校准;事件推进可能受事件密度与背压影响,不能无限依赖本地墙钟外推。暂停和背压停止推进时保留已播放进度,恢复后继续。采样观测中的 sampleIntervalSeconds 是采样间隔,不是未来运动的耗时。
7.4 Carrier 行驶 旋转与停止
沿路径行驶 MOVE_ALONG_PATH
| 字段 | 说明 |
|---|---|
position、rotation | 本段开始时的世界位姿 |
route | POINT/PATH 混合有序数组;数组顺序就是实际经过顺序 |
initialSpeed、maxSpeed | 本段初始速度及设定最高速度 |
acceleration、deceleration | 本段使用的加减速度参数;0 按相应匀速分支解释 |
route 每项含 type 和 name。POINT 表示经过的场景点,PATH 表示行驶路段;首项 POINT 是起始位置。重复经过的同名点或路径须保留,不按类型分组,也不按名称去重。
路线允许从 Path 中途开始、在 Path 中途结束,或只有一个 PATH 项。部分路段必须同时给出 startOffsetMeters 和 endOffsetMeters,均从该 Path 定义的起点沿路径累计,单位米;反向行驶时起始偏移大于结束偏移。完整 Path 的方向由相邻两个 POINT 明确时,可省略这两个偏移。偏移相等不构成新的行驶。
以下示例从 PathA 的 5.6 米处出发,到达 PointB 后沿 PathB 行驶至 4 米处。假设两条 10 米直路沿 +X 连接,PointB 位于 x=10 米,则本段行驶 8.4 米,终点为 x=14 米。
{
"entityName": "Carrier1",
"entityType": "CARRIER",
"animationType": "MOVE_ALONG_PATH",
"simulationTimeMicros": 20000000,
"durationSeconds": 8.4,
"position": {"x": 5.6, "y": 0.0, "z": 0.0},
"rotation": {"x": 0.0, "y": 0.0, "z": 0.0},
"route": [
{
"type": "PATH",
"name": "PathA",
"startOffsetMeters": 5.6,
"endOffsetMeters": 10.0
},
{
"type": "POINT",
"name": "PointB"
},
{
"type": "PATH",
"name": "PathB",
"startOffsetMeters": 0.0,
"endOffsetMeters": 4.0
}
],
"initialSpeed": 0.0,
"maxSpeed": 1.0,
"acceleration": 0.0,
"deceleration": 0.0
}
快照的 Path 含 name、startPointName、endPointName、lengthMeters、geometry。lengthMeters 是用于该路段行程定位的长度,不能用起终坐标的直线距离替代曲线路程。
| geometry 类型 | 字段与含义 |
|---|---|
| LINE | type=LINE;startPosition、endPosition 为世界坐标中的两端点 |
| CATMULL_ROM | type=CATMULL_ROM;controlPoints 为有序世界坐标数组;parameterization=CENTRIPETAL,closed=false;arcLengthDivisions 为弧长映射分段数,minimumHeightMeters 为求值位置的 Y 下限 |
曲线控制点不是等时间采样点。沿曲线使用弧长比例定位,并采用响应给出的 arcLengthDivisions 和 minimumHeightMeters,不自行固定分段数或忽略高度下限。运动段带 poses 时,仍以该段 poses 为准。
已有位姿序列 poses
某些行驶段直接给出 poses,保存该段有序的世界位置与朝向,首末项为实际区间边界。此时不再重复顶层 position/rotation 和另一组速度参数;route 仍用于识别物理路段和经过顺序。运动以 poses 为准,不能同时使用另一套 Path 几何重算。
该类段沿累计水平路程按仿真时间推进,线段内位置沿原位姿序列连接,朝向按相邻有向角差推进。数组下标不代表等时间间隔。纯原地旋转使用 ROTATE,不用零长度路径代替。
{
"entityName": "Carrier1",
"entityType": "CARRIER",
"animationType": "MOVE_ALONG_PATH",
"simulationTimeMicros": 10000000,
"durationSeconds": 2.4,
"route": [
{
"type": "PATH",
"name": "PathA",
"startOffsetMeters": 3.2,
"endOffsetMeters": 5.6
}
],
"poses": [
{
"position": {"x": 3.2, "y": 0.0, "z": 0.0},
"rotation": {"x": 0.0, "y": 0.0, "z": 0.0}
},
{
"position": {"x": 5.6, "y": 0.0, "z": 0.0},
"rotation": {"x": 0.0, "y": 0.0, "z": 0.0}
}
]
}
原地旋转 ROTATE
position 保持不变,rotation 为开始朝向,targetRotation 为目标朝向,durationSeconds 为转向的仿真耗时。无需携带 route 或行驶加减速度。
{
"entityName": "Carrier1",
"entityType": "CARRIER",
"animationType": "ROTATE",
"simulationTimeMicros": 30000000,
"durationSeconds": 1.5,
"position": {"x": 14.0, "y": 0.0, "z": 0.0},
"rotation": {"x": 0.0, "y": 0.0, "z": 0.0},
"targetRotation": {"x": 0.0, "y": 90.0, "z": 0.0}
}
targetRotation.y 采用保持实际转向方向的连续角度,允许超出 0~360°。例如 350° 正向转 20°,目标为 370°;10° 负向转 20°,目标为 -10°。接入方按两者差值理解转角,不先分别归一化再猜方向;恰好 180° 时也以返回的有向角度为准。
停止 STOP 与恢复
STOP 在指定时刻结束该 Carrier 尚未结束的行驶和转向,并保持给定世界位姿。STOP 没有预计等待时长。恢复时返回从实际停靠位置开始的新 MOVE_ALONG_PATH 或 ROTATE,不单独发送一个需要猜测剩余路线的 RESUME 动作。
{
"entityName": "Carrier1",
"entityType": "CARRIER",
"animationType": "STOP",
"simulationTimeMicros": 30500000,
"position": {"x": 14.0, "y": 0.0, "z": 0.0},
"rotation": {"x": 0.0, "y": 30.0, "z": 0.0}
}
因安全距离停在 Path 中途时,恢复段从实际偏移继续,不能跳回 Path 起点。旋转中途停止后,也应从停止角度继续,不能回到上一次旋转起始角。
位姿观测 POSE_UPDATE
position/rotation 是指定仿真时刻已发生的状态,不能据此猜测未来运动或判断停止。Track 上的 Carrier 可另外携带 track.name、track.headOffsetMeters 和 sampleIntervalSeconds。
{
"entityName": "Carrier1",
"entityType": "CARRIER",
"animationType": "POSE_UPDATE",
"simulationTimeMicros": 12000000,
"position": {"x": 4.0, "y": 0.0, "z": 0.0},
"rotation": {"x": 0.0, "y": 0.0, "z": 0.0},
"track": {
"name": "Track1",
"headOffsetMeters": 4.5
},
"sampleIntervalSeconds": 0.1
}
headOffsetMeters 为车头沿 Track 的偏移,position 为载具中心。上例载具长度为 1 米,车头偏移 4.5 米、中心位于 x=4 米。不能把车头距离当作中心距离,也不能用截断到 0~1 的显示进度反推边界外位置。观测不承诺固定发送频率。
7.5 Lift 升降平台
MOVE_VERTICAL 表示平台上升或下降,设备底座保持不变。startHeightMeters 和 targetHeightMeters 以该 Lift 底座为零点,向上为正;目标高度小于起始高度表示下降。平台承载的货物随平台运动。
{
"entityName": "Lift1",
"entityType": "LIFT",
"animationType": "MOVE_VERTICAL",
"simulationTimeMicros": 20000000,
"durationSeconds": 3.0,
"startHeightMeters": 1.0,
"targetHeightMeters": 4.0,
"initialSpeed": 0.0,
"maxSpeed": 1.0,
"acceleration": 0.0,
"deceleration": 0.0
}
上例平台以每仿真秒 1 米从 1 米升至 4 米,耗时 3 秒。initialSpeed、maxSpeed、acceleration、deceleration 与第 7.3 节使用相同单位。平台观测以 POSE_UPDATE 加 platformHeightMeters 表达,不把平台位置当作底座位置。
7.6 Stacker 行走 升降与货叉
| 动作 | animationType | 专用数据及参考系 |
|---|---|---|
| 整机沿轨道行走 | TRAVEL | startOffsetMeters、targetOffsetMeters;从固定轨道起点沿终点方向计量 |
| 升降台升降 | MOVE_VERTICAL | startHeightMeters、targetHeightMeters;从快照给出的升降零点计量 |
| 货叉伸出 | EXTEND_FORK | localPosition、targetLocalPosition;相对本机升降台 |
| 货叉收回 | RETRACT_FORK | 与伸出使用相同坐标结构,保留实际收回起点 |
TRAVEL 和 MOVE_VERTICAL 另含初速、最高速度和加减速度参数。货叉局部坐标中的正负方向区分向两侧伸出,不用非负距离代替。轨道起终位置、升降参考原点和机械部位的安装关系由快照提供。
行走、升降和货叉是同一设备的不同运动部分。TRAVEL 与 MOVE_VERTICAL 可以同时执行,各自保留时间和进度;收到升降动作不能覆盖同机行走。货叉随升降台移动,货叉局部动作再叠加到升降台当前姿态。
下面给出取货过程:0~5 秒行走,同时 0~2 秒升降;5~6 秒伸叉;6 秒开始收叉并建立货物承载,7 秒完成收叉。示例假设轨道沿 +X、升降零点为 0、货叉向局部 -Z 伸出,货物参考点位于叉面原点。
[
{
"entityName": "Stacker1",
"entityType": "STACKER",
"animationType": "TRAVEL",
"simulationTimeMicros": 0,
"durationSeconds": 5.0,
"startOffsetMeters": 0.0,
"targetOffsetMeters": 5.0,
"initialSpeed": 0.0,
"maxSpeed": 1.0,
"acceleration": 0.0,
"deceleration": 0.0
},
{
"entityName": "Stacker1",
"entityType": "STACKER",
"animationType": "MOVE_VERTICAL",
"simulationTimeMicros": 0,
"durationSeconds": 2.0,
"startHeightMeters": 1.0,
"targetHeightMeters": 3.0,
"initialSpeed": 0.0,
"maxSpeed": 1.0,
"acceleration": 0.0,
"deceleration": 0.0
},
{
"entityName": "Stacker1",
"entityType": "STACKER",
"animationType": "EXTEND_FORK",
"simulationTimeMicros": 5000000,
"durationSeconds": 1.0,
"localPosition": {"x": 0.0, "y": 0.0, "z": 0.0},
"targetLocalPosition": {"x": 0.0, "y": 0.0, "z": -1.0}
},
{
"entityName": "Stacker1",
"entityType": "STACKER",
"animationType": "RETRACT_FORK",
"simulationTimeMicros": 6000000,
"durationSeconds": 1.0,
"localPosition": {"x": 0.0, "y": 0.0, "z": -1.0},
"targetLocalPosition": {"x": 0.0, "y": 0.0, "z": 0.0}
},
{
"entityName": "Stacker1",
"entityType": "STACKER",
"animationType": "ATTACH_CARGO",
"simulationTimeMicros": 6000000,
"cargoName": "Item1",
"part": "FORK",
"localPosition": {"x": 0.0, "y": 0.0, "z": 0.0},
"localRotation": {"x": 0.0, "y": 0.0, "z": 0.0}
}
]
同刻收叉与承载按 events 原顺序处理,货物只随一次货叉位移。伸叉或收叉动作本身不代表取货成功;取货失败时不能据机械动作建立货物承载。业务结果从相应运行状态或结果接口读取。
7.7 货物承载与装卸
货物保留自己的 cargoName;entityName 表示承载设备或装卸目标设备。part 指定机械角色:ENTITY 为普通载具整体,LIFT_PLATFORM 为升降平台,FORK 为货叉,STORAGE 为存储部位。part 不是模型内部节点路径。
| 动作 | 数据字段 | 应用规则 |
|---|---|---|
| ATTACH_CARGO | cargoName、part、localPosition、localRotation | 从给定时刻起随该部位运动;局部位姿相对该部位 |
| DETACH_CARGO | cargoName、position、rotation | 解除原承载,保持给定世界位姿 |
| TRANSFER_CARGO | cargoName、part、局部起终位置和角度、durationSeconds | 以目标承载部位为坐标参考执行已有装卸过程 |
ATTACH_CARGO 和 DETACH_CARGO 是即时状态,不带 durationSeconds。储位编号、层、列、深均不是米制坐标;存储部位必须使用实际承载偏移,不能把货格编号作为 x/y/z。
TRANSFER_CARGO 的 localPosition/localRotation 为初始位姿,targetLocalPosition/targetLocalRotation 为目标位姿。开始时在保持初始世界位姿连续的前提下,改用目标部位作为显示父级,然后推进装卸动作;该部位运动时,货物随之运动。
{
"entityName": "Lift1",
"entityType": "LIFT",
"animationType": "TRANSFER_CARGO",
"simulationTimeMicros": 30000000,
"durationSeconds": 0.8,
"cargoName": "Item2",
"part": "LIFT_PLATFORM",
"localPosition": {"x": -0.8, "y": 0.0, "z": 0.0},
"targetLocalPosition": {"x": 0.0, "y": 0.0, "z": 0.0},
"localRotation": {"x": 0.0, "y": 0.0, "z": 0.0},
"targetLocalRotation": {"x": 0.0, "y": 0.0, "z": 0.0}
}
示例表示货物 Item2 从 Lift1 平台局部 x=-0.8 米移动到 x=0。不能对缺少装卸时间的数据自行添加默认时长。只有即时承载变更时使用 ATTACH_CARGO 或 DETACH_CARGO。
卸下货物后保持世界位姿的示例:
{
"entityName": "Stacker1",
"entityType": "STACKER",
"animationType": "DETACH_CARGO",
"simulationTimeMicros": 50000000,
"cargoName": "Item1",
"position": {"x": 10.0, "y": 3.0, "z": -1.0},
"rotation": {"x": 0.0, "y": 0.0, "z": 0.0}
}
从一台移动设备交给另一台设备时,按事件顺序解除旧承载并建立新承载,保持世界位姿连续,避免同时随两个设备运动。
7.8 设备状态与组合设备
实体名称用于关联动作与快照;名称匹配区分大小写,不根据点号、斜杠或名称前缀推断实体类型。supportedActions 给出该实体适用的动作,不表示服务列出的每种动作都适用于它。
| 实体状态 | 必要内容 |
|---|---|
| 普通实体 | entityName、entityType、assetId、当前 position/rotation、supportedActions |
| 真实子实体 | parentEntityName、localPosition/localRotation,替代世界位姿形式;父级必须存在且不能形成循环 |
| Lift | platformHeightMeters、platformLocalRotation;高度从底座原点向局部 +Y 计量,平台当前位置为 (0, platformHeightMeters, 0) |
| Stacker | trackStartPosition、trackEndPosition、travelOffsetMeters、platformOriginLocalPosition、platformHeightMeters、platformLocalRotation、forkLocalPosition、forkLocalRotation |
| 已承载货物 | parentEntityName 为承载设备,part 为承载部位,localPosition/localRotation 为相对该部位的位姿;entityName 与动作中的 cargoName 一致 |
高度和偏移字段为有限数值,单位米;位置、角度字段均为 x/y/z 对象。Stacker 的 trackStartPosition/trackEndPosition 是固定轨道的世界端点,travelOffsetMeters 从轨道起点计量。platformOriginLocalPosition 是相对整机的升降零点,平台位置为该零点加 (0, platformHeightMeters, 0);platformLocalRotation 相对整机。forkLocalPosition/forkLocalRotation 相对平台,同时作为 FORK 承载参考位姿。普通载具的 ENTITY 部位使用其实体坐标系。
真实子实体的父级为 parentEntityName 指定实体的整体,已承载货物的父级则由 parentEntityName 与 part 共同确定。无父级的实体使用世界 position/rotation,并省略 parentEntityName 和局部位姿。资源绑定及实体状态在创建时完整提供,后续动作只更新对应状态字段。
CTU 的上层 Lift 是独立子实体:父 Carrier 负责行驶和旋转,上层 Lift 负责平台高度变化,货物挂接到实际承载部位。父级位移只应用一次。以下上层 Lift 的动作无需重复父 Carrier 的路线:
{
"entityName": "CTU1.Lift1",
"entityType": "LIFT",
"animationType": "MOVE_VERTICAL",
"simulationTimeMicros": 40000000,
"durationSeconds": 2.0,
"startHeightMeters": 0.5,
"targetHeightMeters": 1.5,
"initialSpeed": 0.0,
"maxSpeed": 0.5,
"acceleration": 0.0,
"deceleration": 0.0
}
动态实体使用 ENTITY_CREATED、ENTITY_REMOVED、ENTITY_RENAMED 通知。创建携带完整 entity 及其依赖资源;移除使用 entityName,先处理承载与子实体;改名使用原 entityName 和 newEntityName,按该事件顺序更新名称引用及未结束动作的归属。删除后同名创建视为新实体,不复用原运动状态。
快照必须保留各部位当前活动动作、原开始时刻和承载关系。恢复连接后以新快照整体重建,再应用该快照游标之后的批次,避免重复装载或从头播放。
7.9 使用边界与错误
动画数据用于表现已有运动,不提供场景建模、模型文件导出或设备控制命令。PTrack 连续运动、独立双叉状态,以及缺少有效时间或路径的任意脚本坐标列表不属于支持的完整运动数据。通过 supportedActions 确认对象能力,不将未支持动作解释为空动画。
不能映射的动作、缺失目标或路径、无效坐标与时间返回 VISUALIZATION_UNSUPPORTED_ACTION;保留 requestId 便于定位。失败批次不部分生效,不推进游标。暂停与恢复整段仿真通过实例控制接口和 clock 表达,不推断每种设备都提供独立急停动作。
接口参考与调用示例
以下为结构示例,未代表当前环境实测。路径中的标识和请求变量使用本次响应或获授权的配置。
获取动画快照
GET /simulation/openapi/v1/simulations/{simulationId}/animation/snapshot
运行资源可用;REAL_TIME / EVENT_DRIVEN 生成动画。FULL_SPEED 不用于动画体验。
请求参数
认证头 X-Foresim-Api-Key 由调用方服务端添加;可选 X-Request-Id 用于关联请求。当前接口没有查询字符串参数。
| 位置 | 字段 | 类型 | 必填与说明 |
|---|---|---|---|
| path | simulationId | string | 必填。本次创建返回的实例编号 |
无请求体,不发送空 JSON 代替省略。
请求示例
双花括号是测试页变量,发送时替换;下列模板尚未发送。
GET /simulation/openapi/v1/simulations/{simulationId}/animation/snapshot
X-Foresim-Api-Key: <api-key>
Accept: application/json
成功响应结构
首次成功 HTTP 200;外层 code=OK。下方是结构示例,值与空数组不代表实测数据。
{
"code": "OK",
"message": "Success",
"requestId": "example_request",
"data": {
"simulationId": "example_simulationId",
"coordinates": {
"handedness": "example",
"upAxis": "example",
"lengthUnit": "example",
"rotationRepresentation": "example",
"transformSpace": "example"
},
"clock": {
"simulationTimeMicros": 0,
"sampledAt": "2026-01-01T00:00:00Z",
"status": "READY",
"runMode": "REAL_TIME",
"speedMultiplier": null,
"advancing": false,
"flowControl": "example"
},
"cursor": {
"generation": "example_generation",
"sequence": 0
},
"assets": [],
"nodes": [],
"motions": []
}
}
展开完整响应字段定义
| 字段 | 类型与约束 | 必填 | 说明 |
|---|---|---|---|
simulationId | string | 是 | 本次创建返回的实例编号 |
coordinates | object | 是 | 见字段结构 |
clock | object | 是 | 见字段结构 |
cursor | object | 是 | 使用对应协议的快照 cursor 或增量 nextCursor;错误时不推进 |
assets | array | 是 | 见字段结构 |
nodes | array | 是 | 见字段结构 |
motions | array | 是 | 见字段结构 |
典型失败与下一步
401 检查服务端凭证;403 检查来源和实例归属;400 检查 details 中的字段;409 检查状态、幂等键或名称歧义;410 表示资源已释放;429 按 Retry-After 停止并等待。保留实际 requestId。
{"code":"INVALID_REQUEST","message":"Invalid request","requestId":"example_error","details":[{"field":"request","reason":"检查必填字段和前置状态"}]}
查询动画增量
POST /simulation/openapi/v1/simulations/{simulationId}/animation/updates/query
先获取新动画快照;使用该实例、该协议最新成功响应的完整 cursor。
请求参数
认证头 X-Foresim-Api-Key 由调用方服务端添加;可选 X-Request-Id 用于关联请求。当前接口没有查询字符串参数。
| 位置 | 字段 | 类型 | 必填与说明 |
|---|---|---|---|
| path | simulationId | string | 必填。本次创建返回的实例编号 |
| 字段 | 类型与约束 | 必填 | 说明 |
|---|---|---|---|
cursor | object | 是 | 使用对应协议的快照 cursor 或增量 nextCursor;错误时不推进 |
limit | integer (int32) / null minimum=1,maximum=500 | 否 | 省略/null 默认 100;上限见 capabilities.limits.maximumUpdatesPerPoll |
请求示例
双花括号是测试页变量,发送时替换;下列模板尚未发送。
POST /simulation/openapi/v1/simulations/{simulationId}/animation/updates/query
X-Foresim-Api-Key: <api-key>
Accept: application/json
Content-Type: application/json
{
"cursor": {{animationCursor}},
"limit": 100
}
成功响应结构
首次成功 HTTP 200;外层 code=OK。下方是结构示例,值与空数组不代表实测数据。
{
"code": "OK",
"message": "Success",
"requestId": "example_request",
"data": {
"simulationId": "example_simulationId",
"clock": {
"simulationTimeMicros": 0,
"sampledAt": "2026-01-01T00:00:00Z",
"status": "READY",
"runMode": "REAL_TIME",
"speedMultiplier": null,
"advancing": false,
"flowControl": "example"
},
"nextCursor": {
"generation": "example_generation",
"sequence": 0
},
"oldestAvailableSequence": 0,
"latestSequence": 0,
"hasMore": false,
"batches": []
}
}
展开完整响应字段定义
| 字段 | 类型与约束 | 必填 | 说明 |
|---|---|---|---|
simulationId | string | 是 | 本次创建返回的实例编号 |
clock | object | 是 | 见字段结构 |
nextCursor | object | 是 | 见字段结构 |
oldestAvailableSequence | integer (int64) | 是 | 见字段结构 |
latestSequence | integer (int64) | 是 | 见字段结构 |
hasMore | boolean | 是 | 见字段结构 |
batches | array | 是 | 见字段结构 |
典型失败与下一步
401 检查服务端凭证;403 检查来源和实例归属;400 检查 details 中的字段;409 检查状态、幂等键或名称歧义;410 表示资源已释放;429 按 Retry-After 停止并等待。保留实际 requestId。
{"code":"INVALID_REQUEST","message":"Invalid request","requestId":"example_error","details":[{"field":"request","reason":"检查必填字段和前置状态"}]}