void
MulticopterPositionControl::control_manual(float dt)
{
	math::Vector<3> req_vel_sp; // X,Y in local frame and Z in global (D), in [-1,1] normalized range
	req_vel_sp.zero();

	if (_control_mode.flag_control_altitude_enabled) {
		/* set vertical velocity setpoint with throttle stick */
		/* 将自稳模式的油门杆转换成控制垂直速度设定值(以中间速度为0，往上拨速度向上，往下拨速度向下，速度大小与拨动幅度成正比) */
		req_vel_sp(2) = -scale_control(_manual.z - 0.5f, 0.5f, _params.alt_ctl_dz, _params.alt_ctl_dy); // D
	}

	if (_control_mode.flag_control_position_enabled) {
		/* set horizontal velocity setpoint with roll/pitch stick */
		/* 水平速度设定值由roll和pitch杆确定 */
		req_vel_sp(0) = _manual.x;
		req_vel_sp(1) = _manual.y;
	}

	if (_control_mode.flag_control_altitude_enabled) {
		/* reset alt setpoint to current altitude if needed */
		reset_alt_sp();//复位高度设定值
	}

	if (_control_mode.flag_control_position_enabled) {
		/* reset position setpoint to current position if needed */
		reset_pos_sp();//复位位置设定值
	}
//////////以下限制速度设定值///////////
	/* limit velocity setpoint */
	float req_vel_sp_norm = req_vel_sp.length();

	if (req_vel_sp_norm > 1.0f) {
		req_vel_sp /= req_vel_sp_norm;
	}
//////////以上限制速度设定值///////////
	/* _req_vel_sp scaled to 0..1, scale it to max speed and rotate around yaw */
	math::Matrix<3, 3> R_yaw_sp;
	R_yaw_sp.from_euler(0.0f, 0.0f, _att_sp.yaw_body);//由欧拉角得到旋转矩阵
	/**Firmware/src/lib/mathlib/math/Matrix.hpp
	 * create a rotation matrix from given euler angles
	 * based on http://gentlenav.googlecode.com/files/EulerAngles.pdf
	 *
	 *	void from_euler(float roll, float pitch, float yaw) {
	 *		float cp = cosf(pitch);
	 *		float sp = sinf(pitch);
	 *		float sr = sinf(roll);
	 *		float cr = cosf(roll);
	 *		float sy = sinf(yaw);
	 *		float cy = cosf(yaw);
	 *
	 *		data[0][0] = cp * cy;
	 *		data[0][1] = (sr * sp * cy) - (cr * sy);
	 *		data[0][2] = (cr * sp * cy) + (sr * sy);
	 *		data[1][0] = cp * sy;
	 *		data[1][1] = (sr * sp * sy) + (cr * cy);
	 *		data[1][2] = (cr * sp * sy) - (sr * cy);
	 *		data[2][0] = -sp;
	 *		data[2][1] = sr * cp;
	 *		data[2][2] = cr * cp;
	 *	}
	 */
	math::Vector<3> req_vel_sp_scaled = R_yaw_sp * req_vel_sp.emult(
			_params.vel_max); // in NED and scaled to actual velocity
							  // 在NED坐标系下，还原到真实的速度
/////////////以下为水平轴辅助速度模式：用户控制速度，但是如果速度很小，那么相应轴上的位置保持不变/////////////////
	/*
	 * assisted velocity mode: user controls velocity, but if	velocity is small enough, position
	 * hold is activated for the corresponding axis
	 */
	/* horizontal axes */
	/* 水平轴 */
	if (_control_mode.flag_control_position_enabled) {
		/* check for pos. hold */
		if (fabsf(req_vel_sp(0)) < _params.hold_xy_dz && fabsf(req_vel_sp(1)) < _params.hold_xy_dz) {
			if (!_pos_hold_engaged) {
				if (_params.hold_max_xy < FLT_EPSILON || (fabsf(_vel(0)) < _params.hold_max_xy
						&& fabsf(_vel(1)) < _params.hold_max_xy)) {
					_pos_hold_engaged = true;

				} else {
					_pos_hold_engaged = false;
				}
			}

		} else {
			_pos_hold_engaged = false;
		}
/////////////以上为辅助速度模式：用户控制速度，但是如果速度很小，那么相应轴上的位置保持不变/////////////////
/////////////以下为速度设定值，作为此函数的输出///////////////
		/* set requested velocity setpoint */
		if (!_pos_hold_engaged) {//不需要位置锁定(辅助速度模式)
			_pos_sp(0) = _pos(0);
			_pos_sp(1) = _pos(1);
			_run_pos_control = false; /* request velocity setpoint to be used, instead of position setpoint */
									  /* 用于速度设定而不是位置设定 */
			_vel_sp(0) = req_vel_sp_scaled(0);
			_vel_sp(1) = req_vel_sp_scaled(1);
		}
	}
////////////以下为垂直轴辅助速度模式：用户控制速度，但是如果速度很小，那么相应轴上的位置保持不变/////////////////
	/* vertical axis */
	if (_control_mode.flag_control_altitude_enabled) {
		/* check for pos. hold */
		if (fabsf(req_vel_sp(2)) < FLT_EPSILON) {
			if (!_alt_hold_engaged) {
				if (_params.hold_max_z < FLT_EPSILON || fabsf(_vel(2)) < _params.hold_max_z) {
					_alt_hold_engaged = true;

				} else {
					_alt_hold_engaged = false;
				}
			}

		} else {
			_alt_hold_engaged = false;
		}
////////////以上为垂直轴辅助速度模式：用户控制速度，但是如果速度很小，那么相应轴上的位置保持不变/////////////////
		/* set requested velocity setpoint */
		if (!_alt_hold_engaged) {
			_run_alt_control = false; /* request velocity setpoint to be used, instead of altitude setpoint */
									  /* 用于速度设定而不是位置设定 */
			_vel_sp(2) = req_vel_sp_scaled(2);
			_pos_sp(2) = _pos(2);
		}
	}
}