Example #1
0
 def drone_position_task(self, task):
     if self.calibrated:
         if task.frame == 0 or self.env.done:
             # in_state = np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0])
             in_state = None
             states, action = self.env.reset(in_state)
             self.network_in = self.aux_dl.dl_input(states, action)
             self.sensor.reset()
             pos = self.env.state[0:5:2]
             ang = self.env.ang
             self.a = np.zeros(4)
         else:
             action = self.policy.actor(torch.FloatTensor(self.network_in).to(device)).cpu().detach().numpy()
             states, _, done = self.env.step(action)
             time_iter = time.time()
             _, self.velocity_accel, self.pos_accel = self.sensor.accel_int()
             self.quaternion_gyro = self.sensor.gyro_int()
             self.ang_vel = self.sensor.gyro()
             quaternion_vel = deriv_quat(self.ang_vel, self.quaternion_gyro)
             self.pos_gps, self.vel_gps = self.sensor.gps()
             self.quaternion_triad, _ = self.sensor.triad()
             self.time_total_sens.append(time.time() - time_iter)
             
             #SENSOR CONTROL
             pos_vel = np.array([self.pos_accel[0], self.velocity_accel[0],
                                 self.pos_accel[1], self.velocity_accel[1],
                                 self.pos_accel[2], self.velocity_accel[2]])
             if REAL_STATE_CONTROL:
                 self.network_in = self.aux_dl.dl_input(states, [action])
             else:
                 states_sens = [np.concatenate((pos_vel, self.quaternion_gyro, quaternion_vel))]                
                 self.network_in = self.aux_dl.dl_input(states_sens, [action])
             
             error_i = np.concatenate((self.env.state[0:5:2]-self.pos_accel, self.env.state[6:10]-self.quaternion_gyro))
             self.error.append(error_i)   
             if len(self.error) > 1e4:
                 error_final = np.array(self.error)
                 time_total_img = np.mean(np.array(self.time_total_img))
                 time_total_sens = np.mean(np.array(self.time_total_sens))
                 print('Iteration Time: Img: %.5fms Sens: %.5fms' %(time_total_img*1000, time_total_sens*1000))
                 sys.exit()
             pos = self.env.state[0:5:2]
             ang = self.env.ang
             for i, w_i in enumerate(self.env.w):
                 self.a[i] += (w_i*time_int_step )*180/np.pi/30
     
         ang_deg = (ang[2]*180/np.pi, ang[0]*180/np.pi, ang[1]*180/np.pi)
         pos = (0+pos[0], 0+pos[1], 5+pos[2])
         
         self.quad.setHpr(*ang_deg)
         self.quad.setPos(*pos)
         self.cam.lookAt(self.quad)
         for v in self.env.w:
             if v<0:
                 print('negativo')
         self.prop_1.setHpr(self.a[0],0,0)
         self.prop_2.setHpr(self.a[1],0,0)
         self.prop_3.setHpr(self.a[2],0,0)
         self.prop_4.setHpr(self.a[3],0,0)
     return task.cont
 def gyro_int(self):
     w = self.gyro()
     q = self.quaternion_t0
     V_q = deriv_quat(w, q).flatten()
     for i in range(len(q)):
         q[i] = q[i] + V_q[i] * self.quad.t_step
     self.quaternion_t0 = q / np.linalg.norm(q)
     return q
    def drone_position_task(self, task):
        if task.frame == 0 or self.env.done:
            self.control_error_list = []
            self.estimation_error_list = []
            if self.HOVER:
                in_state = np.array([0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0])
            else:
                in_state = None
            states, action = self.env.reset(in_state)
            self.network_in = self.aux_dl.dl_input(states, action)
            self.sensor.reset()
            pos = self.env.state[0:5:2]
            ang = self.env.ang
            self.a = np.zeros(4)
            self.episode_n += 1
            print(f'Episode Number: {self.episode_n}')
        else:
            progress = self.env.i/self.env.n*100
            print(f'Progress: {progress:.2f}%', end='\r')
            action = self.policy.actor(torch.FloatTensor(self.network_in).to(device)).cpu().detach().numpy()
            states, _, done = self.env.step(action)
            time_iter = time.time()
            _, self.velocity_accel, self.pos_accel = self.sensor.accel_int()
            self.quaternion_gyro = self.sensor.gyro_int()
            self.ang_vel = self.sensor.gyro()
            quaternion_vel = deriv_quat(self.ang_vel, self.quaternion_gyro)
            self.pos_gps, self.vel_gps = self.sensor.gps()
            self.quaternion_triad, _ = self.sensor.triad()
            self.time_total_sens.append(time.time() - time_iter)
            
            #SENSOR CONTROL
            pos_vel = np.array([self.pos_accel[0], self.velocity_accel[0],
                                self.pos_accel[1], self.velocity_accel[1],
                                self.pos_accel[2], self.velocity_accel[2]])

            if self.REAL_CTRL:
                self.network_in = self.aux_dl.dl_input(states, [action])
            else:
                states_sens = [np.concatenate((pos_vel, self.quaternion_gyro, quaternion_vel))]                
                self.network_in = self.aux_dl.dl_input(states_sens, [action])
            
            pos = self.env.state[0:5:2]
            ang = self.env.ang
            for i, w_i in enumerate(self.env.w):
                self.a[i] += (w_i*time_int_step )*180/np.pi/10
    
        ang_deg = (ang[2]*180/np.pi, ang[0]*180/np.pi, ang[1]*180/np.pi)
        pos = (0+pos[0], 0+pos[1], 5+pos[2])
        
        # self.quad_model.setHpr((45, 0, 45))
        # self.quad_model.setPos((5, 5, 6))
        self.quad_model.setPos(*pos)
        self.quad_model.setHpr(*ang_deg)
        for prop, a in zip(self.prop_models, self.a):
            prop.setHpr(a, 0, 0)
        return task.cont
    def drone_eq(self, t, x, action):
        """"
        Main differential equation, not used directly by the user, rather used in the step function integrator.
        Dynamics based in: 
            MODELAGEM DINÂMICA E CONTROLE DE UM VEÍCULO AÉREO NÃO TRIPULADO DO TIPO QUADRIRROTOR 
            by ALLAN CARLOS FERREIRA DE OLIVEIRA
            BRASIL, SP-SANTO ANDRÉ, UFABC - 2019
        Incorporates:
            Drag Forces, Gyroscopic Forces
            In indirect mode: Force clipping (preventing motor shutoff and saturates over Thrust to Weight Ratio)
            In direct mode: maps [-1,1] to forces [0,T2WR*G*M/4]
        """
        self.w, f_in, m_action = self.f2F(action)

        #BODY INERTIAL VELOCITY
        vel_x = x[1]
        vel_y = x[3]
        vel_z = x[5]

        #QUATERNIONS
        q0 = x[6]
        q1 = x[7]
        q2 = x[8]
        q3 = x[9]

        #BODY ANGULAR VELOCITY
        w_xx = x[10]
        w_yy = x[11]
        w_zz = x[12]

        #QUATERNION NORMALIZATION (JUST IN CASE)
        q = np.array([[q0, q1, q2, q3]]).T
        q = q / np.linalg.norm(q)

        # DRAG FORCES ESTIMATION (BASED ON BODY VELOCITIES)
        self.mat_rot = quat_rot_mat(q)
        v_inertial = np.array([[vel_x, vel_y, vel_z]]).T
        v_body = np.dot(self.mat_rot.T, v_inertial)
        f_drag = -0.5 * RHO * C_D * np.multiply(
            A, np.multiply(abs(v_body), v_body))

        # DRAG MOMENTS ESTIMATION (BASED ON BODY ANGULAR VELOCITIES)

        #Discretization over 10 steps (linear velocity varies over the body)
        d_xx = np.linspace(0, D, 10)
        d_yy = np.linspace(0, D, 10)
        d_zz = np.linspace(0, D, 10)
        m_x = 0
        m_y = 0
        m_z = 0
        for xx, yy, zz in zip(d_xx, d_yy, d_zz):
            m_x += -RHO * C_D * BEAM_THICKNESS * D / 10 * (abs(xx * w_xx) *
                                                           (xx * w_xx))
            m_y += -RHO * C_D * BEAM_THICKNESS * D / 10 * (abs(yy * w_yy) *
                                                           (yy * w_yy))
            m_z += -2 * RHO * C_D * BEAM_THICKNESS * D / 10 * (abs(zz * w_zz) *
                                                               (zz * w_zz))

        m_drag = np.array([[m_x], [m_y], [m_z]])

        #GYROSCOPIC EFFECT ESTIMATION (BASED ON ELETRIC MOTOR ANGULAR VELOCITY)
        omega_r = (-self.w[0] + self.w[1] - self.w[2] + self.w[3])[0]

        m_gyro = np.array([[-w_xx * I_R * omega_r], [+w_yy * I_R * omega_r],
                           [0]])

        #BODY FORCES
        self.f_in = np.array([[0, 0, f_in]]).T
        self.f_body = self.f_in + f_drag

        #BODY FORCES ROTATION TO INERTIAL
        self.f_inertial = np.dot(self.mat_rot, self.f_body)

        #INERTIAL ACCELERATIONS
        accel_x = self.f_inertial[0, 0] / M
        accel_y = self.f_inertial[1, 0] / M
        accel_z = self.f_inertial[2, 0] / M - G
        self.accel = np.array([[accel_x, accel_y, accel_z]]).T

        #BODY MOMENTUM
        W = np.array([[w_xx], [w_yy], [w_zz]])

        m_in = m_action + m_gyro + m_drag - np.cross(
            W.flatten(),
            np.dot(J, W).flatten()).reshape((3, 1))

        #INERTIAL ANGULAR ACCELERATION
        accel_ang = np.dot(self.inv_j, m_in).flatten()
        accel_w_xx = accel_ang[0]
        accel_w_yy = accel_ang[1]
        accel_w_zz = accel_ang[2]

        #QUATERNION ANGULAR VELOCITY (INERTIAL)

        self.V_q = deriv_quat(W, q).flatten()
        dq0 = self.V_q[0]
        dq1 = self.V_q[1]
        dq2 = self.V_q[2]
        dq3 = self.V_q[3]

        # RESULTS ORDER:
        # 0 x, 1 vx, 2 y, 3 vy, 4 z, 5 vz, 6 q0, 7 q1, 8 q2, 9 q3, 10 w_xx, 11 w_yy, 12 w_zz
        out = np.array([
            vel_x, accel_x, vel_y, accel_y, vel_z, accel_z, dq0, dq1, dq2, dq3,
            accel_w_xx, accel_w_yy, accel_w_zz
        ])
        return out