本翻译基于 [kRPC 官方文档](https://krpc.github.io/krpc)遵循 LGPL v3 许可。 部分内容可能受 GPLv3 或 MIT 许可约束详见原始仓库。 Copyright 2015-2023 kRPC Org.本教程和示例脚本合集详细说明了如何使用 kRPC 的功能特性。参考系介绍kRPC 中的所有位置、方向、速度和旋转都是相对于某个参考系而言的而*参考系*定义了这些某个参考系是什么。一个参考系规定了原点 (0,0,0) 的位置坐标轴 x、y、z 的方向原点的线速度如果参考系移动的话坐标轴的角速度轴旋转的速度和方向注意KSP 和 kRPC 使用左手坐标系原点位置和轴方向下面给出了一些不同参考系的原点位置和坐标轴方向的例子。天体参考系天体的参考系比如 Kerbin。赤道用蓝色表示本初子午线用红色表示。黑色箭头表示坐标轴原点位于行星中心。通过调用 Kerbin 的CelestialBody.reference_frame获得的参考系具有以下属性原点位于 Kerbin 的中心y 轴从 Kerbin 中心指向北极x 轴从 Kerbin 中心指向本初子午线与赤道的交点0°经度、0°纬度的地表位置z 轴从 Kerbin 中心指向东经 90° 的赤道位置坐标轴随行星旋转即该参考系与 Kerbin 有相同的旋转/角速度。这意味着该参考系相对于 Kerbin 是“固定的”——它随行星中心移动也随行星旋转。因此该参考系中的位置是相对于行星中心的。以下代码打印出了当前活动航天器在 Kerbin 参考系中的位置import krpc conn krpc.connect() vessel conn.space_center.active_vessel print((%.1f, %.1f, %.1f) % vessel.position(vessel.orbit.body.reference_frame))对于停放在发射台上的航天器该位置矢量的大小约为 600,000 米等于 Kerbin 的半径。位置矢量不会随时间变化因为航天器停在 Kerbin 表面而参考系也随 Kerbin 一起旋转。航天器轨道参考系航天器的轨道参考系另一个例子是航天器的轨道参考系通过调用Vessel.orbital_reference_frame获取。该参考系固定在航天器上原点随航天器移动坐标轴指向轨道顺向/法向/径向方向。原点位于航天器的质心y 轴指向航天器轨道的顺向方向x 轴指向航天器轨道的反径向方向z 轴指向航天器轨道的法向方向坐标轴随顺向/法向/径向方向的变化而旋转例如当航天器沿轨道继续运动时顺向方向会发生变化。航天器参考系飞行器的参考系另一个例子是Vessel.reference_frame。与前一个例子一样它也固定在航天器上原点随航天器移动但坐标轴的朝向不同。它们跟踪航天器的朝向原点位于航天器的质心y 轴指向航天器所朝的方向x 轴指向航天器的右侧z 轴指向航天器底部向下坐标轴随航天器方向的任何变化而旋转。线速度和角速度参考系之间会相互移动和旋转。例如前面讨论的参考系的原点位置都固定在某些物体上如航天器或行星。这意味着它们会移动和旋转以跟踪该物体因此具有与之相关的线速度和角速度。例如通过调用Kerbin的CelestialBody.reference_frame获得的参考系是相对于 Kerbin 固定的。这意味着该参考系的角速度与 Kerbin 的角速度相同参考系的线速度与 Kerbin 当前的轨道速度一致。可用参考系kRPC 提供以下参考系Vessel.reference_frame Vessel.orbital_reference_frame Vessel.surface_reference_frame Vessel.surface_velocity_reference_frame CelestialBody.reference_frame CelestialBody.non_rotating_reference_frame CelestialBody.orbital_reference_frame Node.reference_frame Node.orbital_reference_frame Part.reference_frame Part.center_of_mass_reference_frame DockingPort.reference_frame Thruster.thrust_reference_frame同时还可以从上述参考系构造相对和混合参考系。自定义参考系自定义参考系可以从上面列出的内置参考系构造而来。它们有两种类型相对和混合。相对参考系由一个父参考系、一个固定的位置偏移和一个固定的旋转偏移构造而成。例如以下代码通过在Vessel.reference_frame的 z 轴上施加 10 米的位置偏移构建了一个原点在航天器下方 10 米处的参考系。相对参考系可通过调用ReferenceFrame.create_relative()来构造。混合参考系从其他参考系的组件位置、旋转、速度和角速度中继承其组件。注意这些组件不一定是固定的。例如你可以构建一个参考系其位置是航天器的质心继承自 Vessel.reference_frame旋转则是被环绕行星的旋转继承自 CelestialBody.reference_frame。混合参考系可通过调用 ReferenceFrame.create_hybrid() 来构造。自定义参考系的父参考系也可以是其他自定义参考系。例如你可以将上面两个例子结合起来先构造一个以航天器为中心、随被环绕行星旋转的混合参考系然后创建一个在该参考系的 z 轴上偏移 10 米位置的相对参考系。最终得到的参考系其原点在航天器下方 10 米处并且随被环绕的行星旋转。参考系之间的转换kRPC 提供了用于在不同参考系之间转换位置、方向、旋转和速度的实用方法SpaceCenter.transform_position() SpaceCenter.transform_direction() SpaceCenter.transform_rotation() SpaceCenter.transform_velocity()可视化调试参考系可能会让人困惑选择合适的参考系本身就是个挑战。为了辅助调试kRPC 的绘图功能可用于在游戏中可视化方向向量。Drawing.add_direction_from_com()将绘制一个方向向量从活动航天器的质心开始。例如以下代码绘制当前航天器相对于其所环绕天体表面的速度方向import krpc conn krpc.connect(nameVisual Debugging) vessel conn.space_center.active_vessel ref_frame vessel.surface_velocity_reference_frame conn.drawing.add_direction_from_com((0, 1, 0), ref_frame) while True: pass注意:客户端必须保持连接才能持续绘制该线条因此示例末尾使用了一个无限循环。示例下面的示例演示了参考系的各种用法。导航球方向此示例演示如何让航天器指向导航球上的各个方向import krpc conn krpc.connect(nameNavball directions) vessel conn.space_center.active_vessel ap vessel.auto_pilot ap.reference_frame vessel.surface_reference_frame ap.engage() # Point the vessel north on the navball, with a pitch of 0 degrees ap.target_direction (0, 1, 0) ap.wait() # Point the vessel vertically upwards on the navball ap.target_direction (1, 0, 0) ap.wait() # Point the vessel west (heading of 270 degrees), with a pitch of 0 degrees ap.target_direction (0, 0, -1) ap.wait() ap.disengage()该代码使用了航天器的表面参考系Vessel.surface_reference_frame如下图所示第一部分指示自动驾驶仪指向航天器表面参考系中的方向 (0,1,0)即沿 y 轴。该参考系的 y 轴指向北方符合要求。第二部分指示自动驾驶仪指向航天器表面参考系中的方向 (1,0,0)沿 x 轴。该参考系的 x 轴指向天顶远离行星符合要求。最后代码指示自动驾驶仪指向方向 (0,0,-1)沿负 z 轴。该参考系的 z 轴指向东方因此请求的方向指向西方——符合要求。轨道方向此示例演示如何让航天器指向导航球在「轨道」模式下的各个轨道方向。它使用了Vessel.orbital_reference_frame。import krpc conn krpc.connect(nameOrbital directions) vessel conn.space_center.active_vessel ap vessel.auto_pilot ap.reference_frame vessel.orbital_reference_frame ap.engage() # Point the vessel in the prograde direction ap.target_direction (0, 1, 0) ap.wait() # Point the vessel in the orbit normal direction ap.target_direction (0, 0, 1) ap.wait() # Point the vessel in the orbit radial direction ap.target_direction (-1, 0, 0) ap.wait() ap.disengage()该代码使用了航天器的轨道参考系如下图所示表面「顺向」此示例演示如何在导航球处于「表面」模式时让航天器指向「顺向」方向。这是航天器相对于表面的速度方向import krpc conn krpc.connect(nameSurface prograde) vessel conn.space_center.active_vessel ap vessel.auto_pilot ap.reference_frame vessel.surface_velocity_reference_frame ap.target_direction (0, 1, 0) ap.engage() ap.wait() ap.disengage()以下代码使用了 Vessel.surface_velocity_reference_frame如下图所示航天器速度本示例演示如何获取飞行器的轨道速度和表面速度其数值等同于导航球上显示的值。要计算飞行器的轨道速度需要获取相对于行星非旋转参考系CelestialBody.non_rotating_reference_frame的速度。该参考系相对于天体固定但不随天体旋转。对于表面速度则需要使用行星的参考系CelestialBody.reference_frame因为该参考系随天体一同旋转。import time import krpc conn krpc.connect(nameVessel speed) vessel conn.space_center.active_vessel obt_frame vessel.orbit.body.non_rotating_reference_frame srf_frame vessel.orbit.body.reference_frame while True: obt_speed vessel.flight(obt_frame).speed srf_speed vessel.flight(srf_frame).speed print(Orbital speed %.1f m/s, Surface speed %.1f m/s % (obt_speed, srf_speed)) time.sleep(1)本示例演示如何获取飞行器相对于被环绕天体表面的速度以向量形式。要实现这一点需要使用混合参考系。这是因为我们希望得到一个以飞行器为中心、但其线速度相对于地面保持固定的参考系。因此我们创建一个混合参考系将其旋转设置为飞行器的表面参考系Vessel.surface_reference_frame而将所有其他属性包括位置和速度设置为天体的参考系CelestialBody.reference_frame——该参考系随天体一同旋转。import time import krpc conn krpc.connect(nameOrbital speed) vessel conn.space_center.active_vessel ref_frame conn.space_center.ReferenceFrame.create_hybrid( positionvessel.orbit.body.reference_frame, rotationvessel.surface_reference_frame) while True: velocity vessel.flight(ref_frame).velocity print(Surface velocity (%.1f, %.1f, %.1f) % velocity) time.sleep(1)攻角本示例计算飞行器指向方向与其运动方向相对于表面之间的夹角。import math import time import krpc conn krpc.connect(nameAngle of attack) vessel conn.space_center.active_vessel while True: d vessel.direction(vessel.orbit.body.reference_frame) v vessel.velocity(vessel.orbit.body.reference_frame) # Compute the dot product of d and v dotprod d[0]*v[0] d[1]*v[1] d[2]*v[2] # Compute the magnitude of v vmag math.sqrt(v[0]**2 v[1]**2 v[2]**2) # Note: dont need to magnitude of d as it is a unit vector # Compute the angle between the vectors angle 0 if dotprod 0: angle abs(math.acos(dotprod / vmag) * (180.0 / math.pi)) print(Angle of attack %.1f degrees % angle) time.sleep(1)请注意用于获取方向向量和速度向量的参考系朝向并不重要因为两个向量之间的夹角与坐标轴的方向无关。然而如果我们使用随飞行器移动的参考系速度将返回(0,0,0)。因此我们需要一个相对于飞行器不是固定的参考系。CelestialBody.reference_frame恰好满足这些要求。着陆点本示例计算一个位于天体表面指定高度处的参考系该参考系可用作着陆自动驾驶仪的目标目标点。import time from math import sin, cos, pi import krpc conn krpc.connect(nameLanding Site) vessel conn.space_center.active_vessel body vessel.orbit.body create_relative conn.space_center.ReferenceFrame.create_relative # Define the landing site as the top of the VAB landing_latitude -(0(5.0/60)(48.38/60/60)) landing_longitude -(74(37.0/60)(12.2/60/60)) landing_altitude 111 # Determine landing site reference frame # (orientation: xzenith, ynorth, zeast) landing_position body.surface_position( landing_latitude, landing_longitude, body.reference_frame) q_long ( 0, sin(-landing_longitude * 0.5 * pi / 180), 0, cos(-landing_longitude * 0.5 * pi / 180) ) q_lat ( 0, 0, sin(landing_latitude * 0.5 * pi / 180), cos(landing_latitude * 0.5 * pi / 180) ) landing_reference_frame \ create_relative( create_relative( create_relative( body.reference_frame, landing_position, q_long), (0, 0, 0), q_lat), (landing_altitude, 0, 0)) # Draw axes conn.drawing.add_line((0, 0, 0), (1, 0, 0), landing_reference_frame) conn.drawing.add_line((0, 0, 0), (0, 1, 0), landing_reference_frame) conn.drawing.add_line((0, 0, 0), (0, 0, 1), landing_reference_frame) while True: time.sleep(1)