Joystick目的是让开发者使用程序进行飞行控制,可以通过SDK实现遥控器模拟。相比于Waypoint的功能,Joystick显得更加灵活。
在使用这个方法前,请确保你对飞行动力学有一定了解。如果没有,我们也为你准备了一个理论速成指导。如果你已经是专业人士,那么请自动跳到后半部分直接阅读Joystick的使用方法。
理论:基础速成
飞机可以在两种坐标系下运动:地面坐标系(Ground Coordinate System)和机体坐标系(Body Coordinate System),为了区别,可以简单地理解为“绝对”坐标系和“相对”坐标系。“绝对”是指,在地面坐标系下,不管飞机怎么运动,东南西北的方向是“绝对”的,不会变动。而“相对”是指,在机体坐标系下,飞机在运动中机体本身相对地面的姿态改变。
- 机体坐标系(Body Coordinate System)下
Note:这里讨论的不是严谨的机体坐标系,简单的说,是飞机在水平面上的投影。如果你想知道更详细的内容,可以参考Onboard SDK的文档。
图1 机体坐标系(1)
如图1定义机体的坐标系,原点为飞机质心。
图2 机体坐标系(2)
飞机的姿态由坐标系上的三个转动的角度表示。我们又称Y Axis为Pitch Axis,X Axis为Roll Axis,Z Axis 为Yaw Axis,如图2所示,用你的右手,大拇指指向坐标轴(黑色箭头)的方向,想象用剩下四指握住坐标轴,这时四指所指的方向应与红色箭头方向一致,该方向是绕坐标轴转动的正方向。
用上面说的右手定则,分别握住三个坐标轴Pitch Axis, Roll Axis和Yaw Axis,并沿红色箭头转动。 你会发现,pitch控制的是飞机机头上下摆动的角度(图3)。
图3 pitch控制
roll控制的是飞机机翼上下摆动的角度。
图4 roll控制
yaw控制的是飞机机身水平旋转的角度。
图5 yaw控制
控制角度可理解为给飞机相应的加速度。
若是控制飞机的速度,右手定则对于图1依然有效。在图1中,使用右手定则,控制X即让飞机在Y Axis上移动,控制Y即让飞机在X Axis上移动。控制Z依然是控制飞机机身水平的旋转。
- 地面坐标系(Ground Coordinate System)下
该坐标系下,X Axis指向北,Y Axis指向东,至于Z Axis,我们把指向天空作为正方向。三个坐标轴依然满足上面的右手定则(请注意,地面坐标系的X,Y,Z与机体坐标系的X,Y,Z意义不同)。在这个坐标系下,定义航向向北为0,顺时钟到180°,逆时针到-180°。通过这两个数值,我们就可以知道飞机在空间的朝向。
实践:SDK使用
在Mobile SDK里,一个发送给飞机的指令需要四个参数x或roll,y或pitch,yaw和throttle。x或roll,y或pitch归为水平控制,throttle是竖直控制。水平控制、竖直控制与yaw控制是三个方面的控制,互相不影响,但飞机实际运动的效果是三个方面的效果叠加。这四个参数在不同的模式下有不同的解释。例如x或roll,y或pitch这两个参数,在水平控制机体坐标系角度模式下,就会被解释成pitch和roll, 在速度模式下就会解释成y和x。 throttle可以被解释成高度,也可以被解释成速度。yaw可以被解释为角度,也可以是角速度。所以在发送指令前,必须要明确我们对每一个方面的控制模式。
RollPitch Coordinate System(坐标系控制):Ground Coordinate System或者Body Coordinate System。该坐标系只作用于水平控制和yaw控制。
RollPitch Control Mode(水平控制模式):仅作用于x(或roll),y(或pitch)。可以选择角度模式或者速度模式。
Vertical Control Mode:仅作用于z,即飞机在竖直方向(上升、下降)的运动。可以选择速度模式或位置模式。不受坐标系模式影响,都是相对地面。
Yaw Control Mode:仅作用于yaw。角度模式是指地面坐标系下的目标角度。角速度模式可以选择不同的坐标系。请注意坐标系的选择。
Joystick使用逻辑
Android:
1. 开启虚拟摇杆。
/**
* 使用虚拟摇杆功能前请先开启
*/
public void setVirtualStickModeEnabled(boolean enabled, @Nullable final CompletionCallback callback)
* 使用虚拟摇杆功能前请先开启
*/
public void setVirtualStickModeEnabled(boolean enabled, @Nullable final CompletionCallback callback)
2. 请确保以下四个设置是你所需要的:
/**
* 推荐是速度模式
*/
public void setRollPitchControlMode(RollPitchControlMode rollPitchControlMode)
/**
* 推荐是Body坐标系
*/
public void setRollPitchCoordinateSystem(FlightCoordinateSystem rollPitchCoordinateSystem)
/**
* 默认值是速度模式
*/
public void setVerticalControlMode(VerticalControlMode verticalControlMode)
/**
* 默认值是角速度模式
*/
public void setYawControlMode(YawControlMode yawControlMode)
* 推荐是速度模式
*/
public void setRollPitchControlMode(RollPitchControlMode rollPitchControlMode)
/**
* 推荐是Body坐标系
*/
public void setRollPitchCoordinateSystem(FlightCoordinateSystem rollPitchCoordinateSystem)
/**
* 默认值是速度模式
*/
public void setVerticalControlMode(VerticalControlMode verticalControlMode)
/**
* 默认值是角速度模式
*/
public void setYawControlMode(YawControlMode yawControlMode)
3. 使用sendFlightControlData(float mYaw, float mPitch, float mRoll, float mThrottle, DJIExecuteResultCallback mCallBack)方法对飞机进行控制。 这里需要注意的是mPitch和mRoll所控制方向与定义相反了,所以需要反过来填入。
iOS:
1. 首先调用DJINavigation以下方法开启地面站:
-(void) setVirtualStickModeEnabled:withCompletion
2. 然后设置以下四个模式:
/**
* Vertical control mode, 推荐是速度模式。
*/
@property(nonatomic, assign) DJIVerticalControlMode verticalControlMode;
/**
* PitchRoll control mode, 推荐是速度模式。
*/
@property(nonatomic, assign) DJIHorizontalControlMode horizontalControlMode;
/**
* Yaw control mode, 推荐是角速度模式。
*/
@property(nonatomic, assign) DJIYawControlMode yawControlMode;
/**
* PitchRoll control coordinate system, 推荐是Body坐标系。
*/
@property(nonatomic, assign) DJIFlightCoordinateSystem horizontalCoordinateSystem;
* Vertical control mode, 推荐是速度模式。
*/
@property(nonatomic, assign) DJIVerticalControlMode verticalControlMode;
/**
* PitchRoll control mode, 推荐是速度模式。
*/
@property(nonatomic, assign) DJIHorizontalControlMode horizontalControlMode;
/**
* Yaw control mode, 推荐是角速度模式。
*/
@property(nonatomic, assign) DJIYawControlMode yawControlMode;
/**
* PitchRoll control coordinate system, 推荐是Body坐标系。
*/
@property(nonatomic, assign) DJIFlightCoordinateSystem horizontalCoordinateSystem;
3. 接着创建好DJIVirtualStickFlightControlData结构:
typedef struct
{
float pitch;
float roll;
float yaw;
float verticalThrottle;
} DJIVirtualStickFlightControlData
{
float pitch;
float roll;
float yaw;
float verticalThrottle;
} DJIVirtualStickFlightControlData
再使用DJIFlightControl的以下方法对飞机进行控制:
-(void) sendVirtualStickFlightControlData:
Note:
- yaw控制下的角度模式是指地面坐标系下的目标角度;
- 当竖直方向是位置模式时,数值一定是对地的高度;
- 其他模式请注意坐标系的选择。
参数
|
模式
|
数值限制
|
x
|
速度模式
|
[-10 m/s, +10 m/s] 超过最大值,仍按最大值运动
|
角度模式
|
[-30°, +30 °]
|
|
y
|
速度模式
|
[-10 m/s, +10 m/s] 超过最大值,仍按最大值运动
|
角度模式
|
[-30°, +30 °]
|
|
z
|
速度模式
|
[-4 m/s, +4 m/s] 超过最大值,仍按最大值运动
|
位置模式
|
[0m, 100m]
|
|
yaw
|
角度模式
|
[-180°, +180 °]
|
角速度模式
|
[-100°/s, +100 °/s]
|
请留意指令发送的频率。如果指令只发送一次,飞控视为连接中断进入自动悬停状态。因此,可以用Timer去重复发送指令,建议频率是25Hz,最低5Hz以上。
FAQ:
- 一定要同时设置4个模式吗?(4个模式指setHorizontalControlCoordinateSystem(),setHorizontalControlMode(),setVerticalControlMode()和setYawControlMode())如果我只需要飞机向前飞,不需要改变yaw,我也需要设置yaw的运动模式吗?
一定要同时设置。参数x,y,z,yaw是同时传给飞控的指令,如果不设置对应的运动模式,飞机不知道要如何解释参数的值,是速度,角度还是角速度。如果不需要改变yaw,可以设置yaw的模式为角度模式,传值的时候传0,即解释为yaw转动0度。由于SDK本身给四个模式设置了默认值(见上),开发者可以偷懒只改变一个或两个模式的值。但是为了代码质量起见,建议在代码中同时设置好4个模式。
评论
3 条评论
说的这些都很好, 但都不关键.
最大的问题是,
按照官方说明确保了所有前提:
https://sdk-forum.dji.net/hc/zh-cn/articles/4402495686553-%E4%BB%80%E4%B9%88%E6%9D%A1%E4%BB%B6%E4%B8%8B%E6%89%8D%E8%83%BD%E4%BD%BF%E7%94%A8MSDK%E7%9A%84%E8%99%9A%E6%8B%9F%E6%91%87%E6%9D%86
之后调用方法
后, 你依然不知道无人机会不会处于 JoyStick 模式, 每次就像猜盲盒一样...
不处于 JoyStick 模式, 无人机根本不会响应
方法...
当成功进入虚拟摇杆模式后,getFlightMode会变成JOYSTICK模式,可以通过这个得知是否进入成功。
请留意指令发送的频率。如果指令只发送一次,飞控视为连接中断进入自动悬停状态。因此,可以用Timer去重复发送指令,建议频率是50Hz,最低5Hz以
用Timer重复发送指令,啥时停止呢? 就一直发吗
请登录写评论。