def dynamics(self, pos, rot, vel, cmd): # unpacking the control input roll_cmd, pitch_cmd, thrust_cmd, yaw_rate_cmd = cmd ea = uf.rot_to_ea(rot) # current yaw yaw = ea[2] # maximum yaw rate max_yaw_rate_deg = sp.max_yaw_rate_deg max_yaw_rate = max_yaw_rate_deg * numpy.pi / 180 # maximum tilt max_tilt_deg = sp.max_tilt_deg max_tilt = max_tilt_deg * numpy.pi / 180 # desired roll roll_des = (roll_cmd - 1500) * max_tilt / 500 # desired pitch pitch_des = -(pitch_cmd - 1500) * max_tilt / 500 # gain of the inner loop for attitude control ktt = sp.inner_loop_gain # desired thrust versor e3 = numpy.array([0.0, 0.0, 1.0]) dtv = uf.ea_to_rot((roll_des, pitch_des, yaw)).dot(e3) # actual thrust versor atv = rot.dot(e3) # angular velocity aux = ktt * uf.skew(atv).dot(dtv) rot_t = numpy.transpose(rot) omega = rot_t.dot(aux) # yaw rate omega[2] = -(yaw_rate_cmd - 1500) * max_yaw_rate / 500 # neutral thrust nt = sp.neutral_thrust # thrust gain kt = sp.quad_mass * sp.g / nt # thrust command adjustment # The thrust sent to the motors is automatically adjusted according to # the tilt angle of the vehicle (bigger tilt leads to bigger thrust) # to reduce the thrust compensation that the pilot must give. thrust_cmd = thrust_cmd / numpy.dot(atv, e3) # dynamics dpos = vel dvel = kt * thrust_cmd * atv / sp.quad_mass - sp.g * e3 drot = rot.dot(uf.skew(omega)) return dpos, drot, dvel
def _cmd_to_thrust_omega(self, cmd, rot): """Computes the thrust as a 3D numpy array from the RC command.""" # unpacking the control input roll_cmd, pitch_cmd, throttle_cmd, yaw_rate_cmd = cmd # getting the current yaw from rot current_yaw = uf.rot_to_ea(rot)[2] # maximum yaw rate max_yaw_rate_deg = isp.max_yaw_rate_deg max_yaw_rate = max_yaw_rate_deg * np.pi / 180.0 # angular speed omega = np.zeros(3) omega[2] = -(float(yaw_rate_cmd) - 1500.0) * max_yaw_rate / 500.0 # maximum tilt max_tilt_deg = isp.max_tilt_deg max_tilt = max_tilt_deg * np.pi / 180.0 # desired roll roll_des = (float(roll_cmd) - 1500.0) * max_tilt / 500.0 # desired pitch pitch_des = -(float(pitch_cmd) - 1500.0) * max_tilt / 500.0 # desired acceleration ea = roll_des, pitch_des, current_yaw rot = uf.ea_to_rot(ea) throttle_gain = isp.quad_mass * isp.gravity / isp.neutral_throttle thrust = throttle_gain * throttle_cmd * rot.dot(uf.e3) return thrust, omega
def control_law(self, pos, rot, vel, rp, rv, ra, rj, rs, rc): """Returns the control input for the Iris quad in the stabilize mode.""" err_pos = rp[0:3] - pos err_vel = rv[0:3] - vel current_yaw = uf.rot_to_ea(rot)[2] err_yaw = rp[3] - current_yaw err_yaw = np.arctan2(np.sin(err_yaw), np.cos(err_yaw)) des_acc = icp.gravity * uf.e3 + icp.kp*(err_pos) + icp.kv*(err_vel) des_thrust = des_acc * icp.quad_mass des_throttle = np.linalg.norm(des_thrust) des_yaw_rate = icp.k_yaw*(err_yaw) if des_throttle < icp.min_throttle: des_roll = 0.0 des_pitch = 0.0 else: n_des = des_thrust/des_throttle n_des_rot = uf.rot_z(-current_yaw).dot(n_des) sin_roll = -n_des_rot[1] des_roll = np.arcsin(sin_roll) sin_pitch = n_des_rot[0]/np.cos(des_roll) cos_pitch = n_des_rot[2]/np.cos(des_roll) des_pitch = np.arctan2(sin_pitch,cos_pitch) cmd_throttle = des_throttle/icp.quad_mass/icp.gravity*icp.neutral_throttle cmd_throttle = int(self._saturation(cmd_throttle, 1000.0, 2000.0)) max_tilt = icp.max_tilt_deg * np.pi/180.0 cmd_roll = 1500.0 + des_roll*500.0/max_tilt cmd_roll = int(self._saturation(cmd_roll, 1000.0, 2000.0)) cmd_pitch = int(1500.0 - des_pitch*500.0/max_tilt) cmd_pitch = int(self._saturation(cmd_pitch, 1000.0, 2000.0)) max_yaw_rate = icp.max_yaw_rate_deg * np.pi / 180.0 cmd_yaw = int(1500.0 - des_yaw_rate*500.0/max_yaw_rate) cmd_yaw = int(self._saturation(cmd_yaw, 1000.0, 2000.0)) cmd = (cmd_roll, cmd_pitch, cmd_throttle, cmd_yaw) return cmd