Example #1
0
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos, velocities
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll, f_desx, f_desy
    global vel_x, vel_y, vel_z
    global sl_currentPos, sl_xPIDvalue, sl_yPIDvalue, slx_posPID, sly_posPID

    # Start simulation messages
    print "\n\nStarting simulation!!\n"
    print "Simulation size -> %d" % (data.shape[0])
    print "Estimated completion time -> %0.2f minutes" % (
        (data.shape[0] * update_rate) / 60)
    time.sleep(3)

    # Start Neural network
    network = 'modules/networks/sl_rtrl_step_control.csv'

    print "Starting \'%s\' neural network..." % (network)
    net = prn.loadNN(network)
    # Array of inputs to network
    memory = 100
    inputs = np.zeros((10, memory))
    print "Neural network active!"
    time.sleep(1)

    #while True:
    #    if udp.active:
    #        print "UDP server is active..."
    #        break
    #    else:
    #        print "Waiting for UDP server to be active..."
    #    time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(
                time.time()).strftime('%m_%d_%H-%M-%S') + ".csv"
            f = open("logs/ground-test-" + st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position
            # M -> motion capture | C -> commanded controls | sl -> Second marker | Mode
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'slx','sly','slz','slr','slp','sly', \
                             'vel_x', 'vel_fx', 'vel_y', 'vel_fy', 'vel_z', 'vel_fz', \
                             'NNslX','NNslY','NNslZ' ))

        # Index for scrolling the data csv file
        data_index = 0

        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            #for channel in range(0, 4):
            #rcCMD[channel] = int(udp.message[channel])
            rcCMD[0] = int(data['Proll'][data_index])
            rcCMD[1] = int(data['Ppitch'][data_index])
            rcCMD[2] = int(data['Pyaw'][data_index])
            rcCMD[3] = int(data['Pthrottle'][data_index])

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative.
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = data['x'][data_index]  #udp.message[5]
            currentPos['y'] = data['y'][data_index]  #udp.message[6]
            currentPos['z'] = data['z'][data_index]  #-udp.message[7]

            # Update position of the slung load
            sl_currentPos['x'] = data['slx'][data_index]  #udp.message[8]
            sl_currentPos['y'] = data['slx'][data_index]  #udp.message[9]

            # Get velocities of the vehicle
            velocities['x'], velocities['fx'] = vel_x.get_velocity(
                currentPos['x'])
            velocities['y'], velocities['fy'] = vel_y.get_velocity(
                currentPos['y'])
            velocities['z'], velocities['fz'] = vel_z.get_velocity(
                currentPos['z'])

            # Update vehicle Attitude
            #vehicle.getData(MultiWii.ATTITUDE)

            # Slung load PID calculation, the relative position of the vehicle vs the slung load
            sl_xPIDvalue = slx_posPID.update(sl_currentPos['x'] -
                                             currentPos['x'])
            sl_yPIDvalue = sly_posPID.update(sl_currentPos['y'] -
                                             currentPos['y'])

            # Desired position changed using slung load movements
            if int(data['Mode'][data_index]) == 1:  #udp.message[4] == 1:
                desiredPos['x'] = 0.0
                desiredPos['y'] = 0.0
            if int(data['Mode'][data_index]) == 2:  #udp.message[4] == 2:
                desiredPos['x'] = limit(f_desx.update(sl_xPIDvalue), -1.0, 1.0)
                desiredPos['y'] = limit(f_desy.update(sl_yPIDvalue), -1.0, 1.0)

            # Filter new values before using them
            heading = f_yaw.update(data['Myaw'][data_index])  #udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(desiredPos['y'] - currentPos['y'])
            pPIDvalue = pitchPID.update(desiredPos['x'] - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)

            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll = toPWM(
                degrees((rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g)),
                1)
            desiredPitch = toPWM(
                degrees((pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g)),
                1)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (
                cos(f_pitch.update(radians(data['Vroll'][data_index]))) *
                cos(f_roll.update(radians(data['Vpitch'][data_index]))))
            if int(data['Mode'][data_index]) == 2:
                desiredThrottle = round((desiredThrottle / kt_sl) + u0, 0)
            else:
                desiredThrottle = round((desiredThrottle / kt) + u0, 0)
            desiredYaw = round(1500 - (yPIDvalue * ky), 0)

            # Limit commands for safety
            if int(data['Mode'][data_index]) == 1:
                rcCMD[0] = limit(desiredRoll, 1200, 1800)
                rcCMD[1] = limit(desiredPitch, 1200, 1800)
                rcCMD[2] = limit(desiredYaw, 1000, 2000)
                rcCMD[3] = limit(desiredThrottle, 1000, 2000)
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Auto'
            elif int(data['Mode'][data_index]) == 2:
                #rcCMD[0] = limit(desiredRoll,1200,1800)
                #rcCMD[1] = limit(desiredPitch,1200,1800)
                #rcCMD[2] = limit(desiredYaw,1000,2000)
                #rcCMD[3] = limit(desiredThrottle,1000,2000)
                mode = 'SlungLoad'
            else:
                # Prevent integrators/derivators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n, 1000, 2000) for n in rcCMD]

            # Neural network update
            # Order of the inputs -> vehicle roll, vehicle pitch, vehicle yaw, x, y, z, roll, pitch, yaw, throttle
            inputs = np.delete(inputs, 0,
                               1)  # Delete the oldest element on the array
            # Add new column of data to the front of the stack
            inputs = np.column_stack((inputs, \
                [data['Vroll'][data_index], data['Vpitch'][data_index], data['Vyaw'][data_index], \
                 currentPos['x'], currentPos['y'], currentPos['z'], \
                 rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3] ]))
            # Get output of neural network
            outputs = prn.NNOut(inputs, net)

            # Send commands to vehicle
            #vehicle.sendCMD(8,MultiWii.SET_RAW_RC,rcCMD)
            udp.message[0] = data['Proll'][data_index]
            udp.message[1] = data['Ppitch'][data_index]
            udp.message[2] = data['Pyaw'][data_index]
            udp.message[3] = data['Pthrottle'][data_index]
            udp.message[4] = data['Mode'][data_index]

            udp.message[11] = data['Mroll'][data_index]
            udp.message[13] = data['Mpitch'][data_index]
            udp.message[12] = data['Myaw'][data_index]

            udp.message[8] = data['slx'][data_index]
            udp.message[9] = data['sly'][data_index]
            udp.message[10] = data['slz'][data_index]
            udp.message[14] = data['slr'][data_index]
            udp.message[15] = data['slp'][data_index]
            udp.message[16] = data['sly'][data_index]

            row =   (time.time(), \
                    data['Vroll'][data_index], data['Vpitch'][data_index], data['Vyaw'][data_index], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[13], udp.message[12], \
                    udp.message[4], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    udp.message[8], udp.message[9], udp.message[10], udp.message[14],udp.message[15], udp.message[16], \
                    velocities['x'], velocities['fx'], velocities['y'], velocities['fy'], velocities['z'], velocities['fz'], \
                    # The output we care about is the latest....

                    outputs[0,memory-1], outputs[1,memory-1], outputs[2,memory-1] )

            if logging:
                logger.writerow(row)

            if mode == 'Manual':
                print "[%d] Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f | Heading: %0.3f" % (
                    data_index, mode, currentPos['x'], currentPos['y'],
                    currentPos['z'], heading)
            if mode == 'Auto':
                print "[%d] Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f" % (
                    data_index, mode, currentPos['x'], currentPos['y'],
                    currentPos['z'])
            elif mode == 'SlungLoad':
                print "[%d] Mode: %s | SL_X: %0.3f | SL_Y: %0.3f" % (
                    data_index, mode, sl_currentPos['x'], sl_currentPos['y'])

            # Wait until the update_rate is completed
            while elapsed < update_rate:
                elapsed = time.time() - current

            # Update data index and kill the thread when its done
            data_index = data_index + 1
            if data_index == data.shape[0]:
                print "\n\nSimulation terminated!\n"
                break
    except Exception, error:
        print "Error in control thread: " + str(error)
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos, velocities
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll, f_desx, f_desy
    global vel_x, vel_y, vel_z
    global sl_currentPos, sl_xPIDvalue, sl_yPIDvalue, slx_posPID, sly_posPID

    # Start Neural network
    print "Starting neural network..."
    #net = prn.loadNN('modules/sl_rtrl_best.csv')
    net = prn.loadNN('modules/networks/sl_rtrl_step_control.csv')
    # Array of inputs to network 
    inputs = np.zeros((10,1))
    print "Neural network active!"

    while True:
        if udp.active:
            print "UDP server is active..."
            break
        else:
            print "Waiting for UDP server to be active..."
        time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(time.time()).strftime('%m_%d_%H-%M-%S')+".csv"
            f = open("logs/mw-sl-neural-"+st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position 
            # M -> motion capture | C -> commanded controls | sl -> Second marker | Mode 
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'slx','sly','slz','slr','slp','sly', \
                             'vel_x', 'vel_fx', 'vel_y', 'vel_fy', 'vel_z', 'vel_fz', \
                             'NNslX','NNslY' ))
        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            for channel in range(0, 4):
                rcCMD[channel] = int(udp.message[channel])

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative. 
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = udp.message[5]
            currentPos['y'] = udp.message[6]
            currentPos['z'] = -udp.message[7]

            # Get velocities of the vehicle
            velocities['x'],velocities['fx'] = vel_x.get_velocity(currentPos['x'])
            velocities['y'],velocities['fy'] = vel_y.get_velocity(currentPos['y'])
            velocities['z'],velocities['fz'] = vel_z.get_velocity(currentPos['z'])

            # Update vehicle Attitude 
            vehicle.getData(MultiWii.ATTITUDE)

            # Neural network update
            # Order of the inputs -> vehicle roll, vehicle pitch, vehicle yaw, x, y, z, roll, pitch, yaw, throttle
            np.put(inputs, [0,1,2,3,4,5,6,7,8,9], \
                [vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                 currentPos['x'], currentPos['y'], currentPos['z'], \
                 rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3] ])
            # Get output of neural network
            outputs = prn.NNOut(inputs,net)

            # Update position of the slung load
            #sl_currentPos['x'] = udp.message[8]
            #sl_currentPos['y'] = udp.message[9]
            sl_currentPos['x'] = outputs[0,0]
            sl_currentPos['y'] = outputs[1,0]

            # Slung load PID calculation, the relative position of the vehicle vs the slung load
            sl_xPIDvalue = slx_posPID.update(sl_currentPos['x'] - currentPos['x'])
            sl_yPIDvalue = sly_posPID.update(sl_currentPos['y'] - currentPos['y'])

            # Desired position changed using slung load movements
            if udp.message[4] == 1:  
                desiredPos['x'] = 0.0
                desiredPos['y'] = 0.0
                wp_index = 0
                wp_step = 0
            if udp.message[4] == 2:
                # Aggressive step response
                #desiredPos['x'] = 1.0
                #desiredPos['y'] = 1.0
                # Slung load control staying at 0,0 (normal with filter)
                #desiredPos['x'] = limit(f_desx.update(sl_xPIDvalue), -1.0, 1.0)
                #desiredPos['y'] = limit(f_desy.update(sl_yPIDvalue), -1.0, 1.0)
                # Slung load control staying at 0,0 (normal with no filter)
                #desiredPos['x'] = limit(sl_xPIDvalue, -1.0, 1.0)
                #desiredPos['y'] = limit(sl_yPIDvalue, -1.0, 1.0)
                # Slung load control aggressive step response
                #desiredPos['x'] = 1.0 + limit(f_desx.update(sl_xPIDvalue), -2.0, 2.0)
                #desiredPos['y'] = 1.0 + limit(f_desy.update(sl_yPIDvalue), -2.0, 2.0)
                # Slung load control aggressive step response (no filter)
                #desiredPos['x'] = 1.0 + limit(sl_xPIDvalue, -2.0, 2.0)
                #desiredPos['y'] = 1.0 + limit(sl_yPIDvalue, -2.0, 2.0)
                # Way-point control
                if wp_step >= wp_time:
                    wp_step = 0
                    wp_index += 1 # to iterate on the WP list
                    if wp_index > len(wp)-1:
                        wp_index = 0
                else:
                    desiredPos['x'] = wp[wp_index][0]
                    desiredPos['y'] = wp[wp_index][1]
                    wp_step += 1 # increase the time step to let time pass

            # Filter new values before using them
            heading = f_yaw.update(udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(  desiredPos['y'] - currentPos['y'])
            pPIDvalue = pitchPID.update( desiredPos['x'] - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)
            
            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll  = toPWM(degrees( (rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g) ),1)
            desiredPitch = toPWM(degrees( (pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g) ),1)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (cos(f_pitch.update(radians(vehicle.attitude['angx'])))*cos(f_roll.update(radians(vehicle.attitude['angy']))))
            #if udp.message[4] == 2:
            desiredThrottle = round((desiredThrottle / kt_sl) + u0, 0)
            #else:
            #    desiredThrottle = round((desiredThrottle / kt) + u0, 0)
            desiredYaw = round(1500 - (yPIDvalue * ky), 0)

            # Limit commands for safety
            if udp.message[4] == 1:
                rcCMD[0] = limit(desiredRoll,1000,2000)
                rcCMD[1] = limit(desiredPitch,1000,2000)
                rcCMD[2] = limit(desiredYaw,1000,2000)
                rcCMD[3] = limit(desiredThrottle,1000,2000)
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Auto'
            elif udp.message[4] == 2:
                rcCMD[0] = limit(desiredRoll,1000,2000)
                rcCMD[1] = limit(desiredPitch,1000,2000)
                rcCMD[2] = limit(desiredYaw,1000,2000)
                rcCMD[3] = limit(desiredThrottle,1000,2000)
                mode = 'SlungLoad'
            else:
                # Prevent integrators/derivators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n,1000,2000) for n in rcCMD]

            # Send commands to vehicle
            vehicle.sendCMD(8,MultiWii.SET_RAW_RC,rcCMD)

            row =   (time.time(), \
                    vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[13], udp.message[12], \
                    udp.message[4], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    udp.message[8], udp.message[9], udp.message[10], udp.message[14],udp.message[15], udp.message[16], \
                    velocities['x'], velocities['fx'], velocities['y'], velocities['fy'], velocities['z'], velocities['fz'], \
                    outputs[0,0], outputs[1,0] )

            if logging:
                logger.writerow(row)

            if mode == 'Manual':
                print "Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f | Heading: %0.3f" % (mode, currentPos['x'], currentPos['y'], currentPos['z'], heading)                
            if mode == 'Auto':
                print "Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f" % (mode, currentPos['x'], currentPos['y'], currentPos['z'])
            elif mode == 'SlungLoad':
                print "Mode: %s | WP: %d | SL_X: %0.3f | SL_Y: %0.3f" % (mode, wp_index, sl_currentPos['x'], sl_currentPos['y'])                

            # Wait until the update_rate is completed 
            while elapsed < update_rate:
                elapsed = time.time() - current

    except Exception,error:
        print "Error in control thread: "+str(error)
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos, velocities
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll, f_desx, f_desy
    global vel_x, vel_y, vel_z

    # Start Neural network
    print("Starting neural network...")
    net = prn.loadNN('modules/networkNOV.csv')
    # Array of inputs to network
    inputs = np.zeros((10, 1))
    print("Neural network active!")

    while True:
        if udp.active:
            print("UDP server is active...")
            break
        else:
            print("Waiting for UDP server to be active...")
        time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(
                time.time()).strftime('%m_%d_%H-%M-%S') + ".csv"
            f = open("logs/mw-neural-" + st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position
            # M -> motion capture | C -> commanded controls | sl -> Second marker | Mode
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'slx','sly','slz','slr','slp','sly', \
                             'vel_x', 'vel_fx', 'vel_y', 'vel_fy', 'vel_z', 'vel_fz', \
                             'NNroll','NNpitch','NNyaw','NNx','NNy','NNz' ))
        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            for channel in range(0, 4):
                rcCMD[channel] = int(udp.message[channel])

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative.
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = udp.message[5]
            currentPos['y'] = udp.message[6]
            currentPos['z'] = -udp.message[7]

            # Get velocities of the vehicle
            velocities['x'], velocities['fx'] = vel_x.get_velocity(
                currentPos['x'])
            velocities['y'], velocities['fy'] = vel_y.get_velocity(
                currentPos['y'])
            velocities['z'], velocities['fz'] = vel_z.get_velocity(
                currentPos['z'])

            # Update vehicle Attitude
            vehicle.getData(MultiWii.ATTITUDE)

            # Desired position changed using joystick movements
            if udp.message[4] == 1:
                desiredPos['x'] = radius
                desiredPos['y'] = 0.0
                trajectory_step = 0.0
            if udp.message[4] == 2:
                if trajectory == 'circle':
                    desiredPos['x'], desiredPos['y'] = circle_trajectory(
                        radius, w, trajectory_step)
                    trajectory_step += update_rate
                elif trajectory == 'infinity':
                    desiredPos['x'], desiredPos['y'] = infinity_trajectory(
                        a, b, w, trajectory_step)
                    trajectory_step += update_rate

            # Filter new values before using them
            heading = f_yaw.update(udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(desiredPos['y'] - currentPos['y'])
            pPIDvalue = pitchPID.update(desiredPos['x'] - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)

            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll = toPWM(
                degrees((rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g)),
                1, 50)
            desiredPitch = toPWM(
                degrees((pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g)),
                1, 50)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (
                cos(f_pitch.update(radians(vehicle.attitude['angx']))) *
                cos(f_roll.update(radians(vehicle.attitude['angy']))))
            desiredThrottle = round((desiredThrottle / kt) + u0, 0)
            desiredYaw = round(1500 - (yPIDvalue * ky), 0)

            # Limit commands for safety
            if udp.message[4] == 1:
                rcCMD[0] = limit(desiredRoll, 1200, 1800)
                rcCMD[1] = limit(desiredPitch, 1200, 1800)
                rcCMD[2] = limit(desiredYaw, 1000, 2000)
                rcCMD[3] = limit(desiredThrottle, 1000, 2000)
                mode = 'Hold'
            elif udp.message[4] == 2:
                rcCMD[0] = limit(desiredRoll, 1200, 1800)
                rcCMD[1] = limit(desiredPitch, 1200, 1800)
                rcCMD[2] = limit(desiredYaw, 1000, 2000)
                rcCMD[3] = limit(desiredThrottle, 1000, 2000)
                mode = 'Trajectory'
            else:
                # Prevent integrators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n, 1000, 2000) for n in rcCMD]

            # Neural network update
            # Order of the inputs -> roll, pitch, yaw, throttle, vehicle roll, vehicle pitch, motion capture yaw, x, y, z
            np.put(inputs, [0,1,2,3,4,5,6,7,8,9], \
                [rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                 vehicle.attitude['angx'], vehicle.attitude['angy'], udp.message[9], \
                 currentPos['x'], currentPos['y'], currentPos['z'] ])
            # Get output of neural network
            outputs = prn.NNOut(inputs, net)

            # Send commands to vehicle
            vehicle.sendCMD(8, MultiWii.SET_RAW_RC, rcCMD)

            row =   (time.time(), \
                    vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[13], udp.message[12], \
                    udp.message[4], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    udp.message[8], udp.message[9], udp.message[10], udp.message[14],udp.message[15], udp.message[16], \
                    velocities['x'], velocities['fx'], velocities['y'], velocities['fy'], velocities['z'], velocities['fz'], \
                    outputs[0,0], outputs[1,0], outputs[2,0], outputs[3,0], outputs[4,0], outputs[5,0] )

            if logging:
                logger.writerow(row)

            if mode == 'Hold' or 'Manual':
                print(
                    "Mode: %s | X: %0.2f | Y: %0.2f | Z: %0.2f" %
                    (mode, currentPos['x'], currentPos['y'], currentPos['z']))
            elif mode == 'Trajectory':
                print("Mode: %s | Des_X: %0.2f | Des_Y: %0.2f" %
                      (mode, desiredPos['x'], desiredPos['y']))

            # Wait until the update_rate is completed
            while elapsed < update_rate:
                elapsed = time.time() - current

    except Exception as error:
        print("Error in control thread: " + str(error))
Example #4
0
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll
    global ky

    # Start Neural network
    net = prn.loadNN('modules/network.csv')
    # Array of inputs to network 
    inputs = np.zeros((10,1))

    while True:
        if udp.active:
            print "UDP server is active..."
            break
        else:
            print "Waiting for UDP server to be active..."
        time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(time.time()).strftime('%m_%d_%H-%M-%S')+".csv"
            f = open("logs/mw-"+st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position | M -> motion capture | C -> commanded controls | NN -> Neural Network prediction
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'NNroll','NNpitch','NNyaw','NNx','NNy','NNz'))
        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            rcCMD[0] = udp.message[0]
            rcCMD[1] = udp.message[1]
            rcCMD[2] = udp.message[2]
            rcCMD[3] = udp.message[3]

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative. 
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = udp.message[5]
            currentPos['y'] = udp.message[6]
            currentPos['z'] = -udp.message[7]

            # Update Attitude 
            vehicle.getData(MultiWii.ATTITUDE)

            # Filter new values before using them
            heading = f_yaw.update(udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(desiredPos['y'] - currentPos['y'])
            pPIDvalue = pitchPID.update(desiredPos['x'] - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)
            
            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll  = toPWM(degrees( (rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g) ),1)
            desiredPitch = toPWM(degrees( (pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g) ),1)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (cos(f_pitch.update(radians(vehicle.attitude['angx'])))*cos(f_roll.update(radians(vehicle.attitude['angy']))))
            desiredThrottle = (desiredThrottle / kt) + u0
            desiredYaw = 1500 - (yPIDvalue * ky)

            # Limit commands for safety
            if udp.message[4] == 1:
                rcCMD[0] = limit(desiredRoll,1000,2000)
                rcCMD[1] = limit(desiredPitch,1000,2000)
                rcCMD[2] = limit(desiredYaw,1000,2000)
                rcCMD[3] = limit(desiredThrottle,1000,2000)
                mode = 'Auto'
            else:
                # Prevent integrators/derivators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n,1000,2000) for n in rcCMD]

            # Neural network update
            # Order of the inputs -> roll, pitch, yaw, throttle, vehicle roll, vehicle pitch, motion capture yaw, x, y, z
            np.put(inputs, [0,1,2,3,4,5,6,7,8,9], \
                [rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                 vehicle.attitude['angx'], vehicle.attitude['angy'], udp.message[9], \
                 currentPos['x'], currentPos['y'], currentPos['z'] ])
            # Get output of neural network
            outputs = prn.NNOut(inputs,net)

            # Send commands to vehicle
            vehicle.sendCMD(8,MultiWii.SET_RAW_RC,rcCMD)

            row =   (time.time(), \
                    vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                    #vehicle.rawIMU['ax'], vehicle.rawIMU['ay'], vehicle.rawIMU['az'], vehicle.rawIMU['gx'], vehicle.rawIMU['gy'], vehicle.rawIMU['gz'], \
                    #vehicle.rcChannels['roll'], vehicle.rcChannels['pitch'], vehicle.rcChannels['throttle'], vehicle.rcChannels['yaw'], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[12], udp.message[13], \
                    udp.message[7], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    outputs[0,0], outputs[1,0], outputs[2,0], outputs[3,0], outputs[4,0], outputs[5,0] )
            if logging:
                logger.writerow(row)

            print "Mode: %s | Z: %0.3f | X: %0.3f | Y: %0.3f " % (mode, currentPos['z'], currentPos['x'], currentPos['y'])
            #print "Mode: %s | heading: %0.3f | desiredYaw: %0.3f" % (mode, heading, desiredYaw)

            # Wait until the update_rate is completed 
            while elapsed < update_rate:
                elapsed = time.time() - current

    except Exception,error:
        print "Error in control thread: "+str(error)
Example #5
0
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos, velocities
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll, f_desx, f_desy
    global vel_x, vel_y, vel_z
    global sl_currentPos, sl_xPIDvalue, sl_yPIDvalue, slx_posPID, sly_posPID

    # Start Neural network
    print "Starting neural network..."
    #net = prn.loadNN('modules/sl_rtrl_best.csv')
    net = prn.loadNN('modules/networks/sl_rtrl_step_control.csv')
    # Array of inputs to network
    inputs = np.zeros((10, 1))
    print "Neural network active!"

    while True:
        if udp.active:
            print "UDP server is active..."
            break
        else:
            print "Waiting for UDP server to be active..."
        time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(
                time.time()).strftime('%m_%d_%H-%M-%S') + ".csv"
            f = open("logs/mw-sl-neural-" + st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position
            # M -> motion capture | C -> commanded controls | sl -> Second marker | Mode
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'slx','sly','slz','slr','slp','sly', \
                             'vel_x', 'vel_fx', 'vel_y', 'vel_fy', 'vel_z', 'vel_fz', \
                             'NNslX','NNslY' ))
        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            for channel in range(0, 4):
                rcCMD[channel] = int(udp.message[channel])

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative.
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = udp.message[5]
            currentPos['y'] = udp.message[6]
            currentPos['z'] = -udp.message[7]

            # Get velocities of the vehicle
            velocities['x'], velocities['fx'] = vel_x.get_velocity(
                currentPos['x'])
            velocities['y'], velocities['fy'] = vel_y.get_velocity(
                currentPos['y'])
            velocities['z'], velocities['fz'] = vel_z.get_velocity(
                currentPos['z'])

            # Update vehicle Attitude
            vehicle.getData(MultiWii.ATTITUDE)

            # Neural network update
            # Order of the inputs -> vehicle roll, vehicle pitch, vehicle yaw, x, y, z, roll, pitch, yaw, throttle
            np.put(inputs, [0,1,2,3,4,5,6,7,8,9], \
                [vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                 currentPos['x'], currentPos['y'], currentPos['z'], \
                 rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3] ])
            # Get output of neural network
            outputs = prn.NNOut(inputs, net)

            # Update position of the slung load
            #sl_currentPos['x'] = udp.message[8]
            #sl_currentPos['y'] = udp.message[9]
            sl_currentPos['x'] = outputs[0, 0]
            sl_currentPos['y'] = outputs[1, 0]

            # Slung load PID calculation, the relative position of the vehicle vs the slung load
            sl_xPIDvalue = slx_posPID.update(sl_currentPos['x'] -
                                             currentPos['x'])
            sl_yPIDvalue = sly_posPID.update(sl_currentPos['y'] -
                                             currentPos['y'])

            # Desired position changed using slung load movements
            if udp.message[4] == 1:
                desiredPos['x'] = 0.0
                desiredPos['y'] = 0.0
                wp_index = 0
                wp_step = 0
            if udp.message[4] == 2:
                # Aggressive step response
                #desiredPos['x'] = 1.0
                #desiredPos['y'] = 1.0
                # Slung load control staying at 0,0 (normal with filter)
                #desiredPos['x'] = limit(f_desx.update(sl_xPIDvalue), -1.0, 1.0)
                #desiredPos['y'] = limit(f_desy.update(sl_yPIDvalue), -1.0, 1.0)
                # Slung load control staying at 0,0 (normal with no filter)
                #desiredPos['x'] = limit(sl_xPIDvalue, -1.0, 1.0)
                #desiredPos['y'] = limit(sl_yPIDvalue, -1.0, 1.0)
                # Slung load control aggressive step response
                #desiredPos['x'] = 1.0 + limit(f_desx.update(sl_xPIDvalue), -2.0, 2.0)
                #desiredPos['y'] = 1.0 + limit(f_desy.update(sl_yPIDvalue), -2.0, 2.0)
                # Slung load control aggressive step response (no filter)
                #desiredPos['x'] = 1.0 + limit(sl_xPIDvalue, -2.0, 2.0)
                #desiredPos['y'] = 1.0 + limit(sl_yPIDvalue, -2.0, 2.0)
                # Way-point control
                if wp_step >= wp_time:
                    wp_step = 0
                    wp_index += 1  # to iterate on the WP list
                    if wp_index > len(wp) - 1:
                        wp_index = 0
                else:
                    desiredPos['x'] = wp[wp_index][0]
                    desiredPos['y'] = wp[wp_index][1]
                    wp_step += 1  # increase the time step to let time pass

            # Filter new values before using them
            heading = f_yaw.update(udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(desiredPos['y'] - currentPos['y'])
            pPIDvalue = pitchPID.update(desiredPos['x'] - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)

            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll = toPWM(
                degrees((rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g)),
                1)
            desiredPitch = toPWM(
                degrees((pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g)),
                1)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (
                cos(f_pitch.update(radians(vehicle.attitude['angx']))) *
                cos(f_roll.update(radians(vehicle.attitude['angy']))))
            #if udp.message[4] == 2:
            desiredThrottle = round((desiredThrottle / kt_sl) + u0, 0)
            #else:
            #    desiredThrottle = round((desiredThrottle / kt) + u0, 0)
            desiredYaw = round(1500 - (yPIDvalue * ky), 0)

            # Limit commands for safety
            if udp.message[4] == 1:
                rcCMD[0] = limit(desiredRoll, 1000, 2000)
                rcCMD[1] = limit(desiredPitch, 1000, 2000)
                rcCMD[2] = limit(desiredYaw, 1000, 2000)
                rcCMD[3] = limit(desiredThrottle, 1000, 2000)
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Auto'
            elif udp.message[4] == 2:
                rcCMD[0] = limit(desiredRoll, 1000, 2000)
                rcCMD[1] = limit(desiredPitch, 1000, 2000)
                rcCMD[2] = limit(desiredYaw, 1000, 2000)
                rcCMD[3] = limit(desiredThrottle, 1000, 2000)
                mode = 'SlungLoad'
            else:
                # Prevent integrators/derivators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n, 1000, 2000) for n in rcCMD]

            # Send commands to vehicle
            vehicle.sendCMD(8, MultiWii.SET_RAW_RC, rcCMD)

            row =   (time.time(), \
                    vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[13], udp.message[12], \
                    udp.message[4], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    udp.message[8], udp.message[9], udp.message[10], udp.message[14],udp.message[15], udp.message[16], \
                    velocities['x'], velocities['fx'], velocities['y'], velocities['fy'], velocities['z'], velocities['fz'], \
                    outputs[0,0], outputs[1,0] )

            if logging:
                logger.writerow(row)

            if mode == 'Manual':
                print "Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f | Heading: %0.3f" % (
                    mode, currentPos['x'], currentPos['y'], currentPos['z'],
                    heading)
            if mode == 'Auto':
                print "Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f" % (
                    mode, currentPos['x'], currentPos['y'], currentPos['z'])
            elif mode == 'SlungLoad':
                print "Mode: %s | WP: %d | SL_X: %0.3f | SL_Y: %0.3f" % (
                    mode, wp_index, sl_currentPos['x'], sl_currentPos['y'])

            # Wait until the update_rate is completed
            while elapsed < update_rate:
                elapsed = time.time() - current

    except Exception, error:
        print "Error in control thread: " + str(error)
Example #6
0
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos, velocities
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll, f_desx, f_desy
    global vel_x, vel_y, vel_z

    # Start Neural network
    print "Starting neural network..."
    net = prn.loadNN('modules/networkNOV.csv')
    # Array of inputs to network 
    inputs = np.zeros((10,1))
    print "Neural network active!"

    while True:
        if udp.active:
            print "UDP server is active..."
            break
        else:
            print "Waiting for UDP server to be active..."
        time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(time.time()).strftime('%m_%d_%H-%M-%S')+".csv"
            f = open("logs/mw-neural-"+st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position 
            # M -> motion capture | C -> commanded controls | sl -> Second marker | Mode 
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'slx','sly','slz','slr','slp','sly', \
                             'vel_x', 'vel_fx', 'vel_y', 'vel_fy', 'vel_z', 'vel_fz', \
                             'NNroll','NNpitch','NNyaw','NNx','NNy','NNz' ))
        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            for channel in range(0, 4):
                rcCMD[channel] = int(udp.message[channel])

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative. 
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = udp.message[5]
            currentPos['y'] = udp.message[6]
            currentPos['z'] = -udp.message[7]

            # Get velocities of the vehicle
            velocities['x'],velocities['fx'] = vel_x.get_velocity(currentPos['x'])
            velocities['y'],velocities['fy'] = vel_y.get_velocity(currentPos['y'])
            velocities['z'],velocities['fz'] = vel_z.get_velocity(currentPos['z'])

            # Update vehicle Attitude 
            vehicle.getData(MultiWii.ATTITUDE)

            # Desired position changed using joystick movements
            if udp.message[4] == 1:
                desiredPos['x'] = radius
                desiredPos['y'] = 0.0
                trajectory_step = 0.0
            if udp.message[4] == 2:
                if trajectory == 'circle':
                    desiredPos['x'], desiredPos['y'] = circle_trajectory(radius, w, trajectory_step)
                    trajectory_step += update_rate
                elif trajectory == 'infinity':
                    desiredPos['x'], desiredPos['y'] = infinity_trajectory(a, b, w, trajectory_step)
                    trajectory_step += update_rate

            # Filter new values before using them
            heading = f_yaw.update(udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(desiredPos['y']   - currentPos['y'])
            pPIDvalue = pitchPID.update(desiredPos['x']  - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)
            
            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll  = toPWM(degrees( (rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g) ), 1, 50)
            desiredPitch = toPWM(degrees( (pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g) ), 1, 50)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (cos(f_pitch.update(radians(vehicle.attitude['angx'])))*cos(f_roll.update(radians(vehicle.attitude['angy']))))
            desiredThrottle = round((desiredThrottle / kt) + u0 ,0)
            desiredYaw = round(1500 - (yPIDvalue * ky) ,0)

            # Limit commands for safety
            if udp.message[4] == 1:
                rcCMD[0] = limit(desiredRoll,1200,1800)
                rcCMD[1] = limit(desiredPitch,1200,1800)
                rcCMD[2] = limit(desiredYaw,1000,2000)
                rcCMD[3] = limit(desiredThrottle,1000,2000)
                mode = 'Hold'
            elif udp.message[4] == 2:
                rcCMD[0] = limit(desiredRoll,1200,1800)
                rcCMD[1] = limit(desiredPitch,1200,1800)
                rcCMD[2] = limit(desiredYaw,1000,2000)
                rcCMD[3] = limit(desiredThrottle,1000,2000)
                mode = 'Trajectory'
            else:
                # Prevent integrators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n,1000,2000) for n in rcCMD]

            # Neural network update
            # Order of the inputs -> roll, pitch, yaw, throttle, vehicle roll, vehicle pitch, motion capture yaw, x, y, z
            np.put(inputs, [0,1,2,3,4,5,6,7,8,9], \
                [rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                 vehicle.attitude['angx'], vehicle.attitude['angy'], udp.message[9], \
                 currentPos['x'], currentPos['y'], currentPos['z'] ])
            # Get output of neural network
            outputs = prn.NNOut(inputs,net)

            # Send commands to vehicle
            vehicle.sendCMD(8,MultiWii.SET_RAW_RC,rcCMD)

            row =   (time.time(), \
                    vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[13], udp.message[12], \
                    udp.message[4], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    udp.message[8], udp.message[9], udp.message[10], udp.message[14],udp.message[15], udp.message[16], \
                    velocities['x'], velocities['fx'], velocities['y'], velocities['fy'], velocities['z'], velocities['fz'], \
                    outputs[0,0], outputs[1,0], outputs[2,0], outputs[3,0], outputs[4,0], outputs[5,0] )

            if logging:
                logger.writerow(row)

            if mode == 'Hold' or 'Manual':
                print "Mode: %s | X: %0.2f | Y: %0.2f | Z: %0.2f" % (mode, currentPos['x'], currentPos['y'], currentPos['z'])
            elif mode == 'Trajectory':
                print "Mode: %s | Des_X: %0.2f | Des_Y: %0.2f" % (mode, desiredPos['x'], desiredPos['y'])                

            # Wait until the update_rate is completed 
            while elapsed < update_rate:
                elapsed = time.time() - current

    except Exception,error:
        print "Error in control thread: "+str(error)
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos, velocities
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll, f_desx, f_desy
    global vel_x, vel_y, vel_z
    global sl_currentPos, sl_xPIDvalue, sl_yPIDvalue, slx_posPID, sly_posPID

    # Start simulation messages
    print "\n\nStarting simulation!!\n"
    print "Simulation size -> %d" % (data.shape[0])
    print "Estimated completion time -> %0.2f minutes" % ((data.shape[0]*update_rate)/60)
    time.sleep(3)

    # Start Neural network
    network = 'modules/networks/sl_rtrl_step_control.csv'

    print "Starting \'%s\' neural network..." % (network)
    net = prn.loadNN(network)
    # Array of inputs to network 
    memory = 100
    inputs = np.zeros((10,memory))
    print "Neural network active!"
    time.sleep(1)

    #while True:
    #    if udp.active:
    #        print "UDP server is active..."
    #        break
    #    else:
    #        print "Waiting for UDP server to be active..."
    #    time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(time.time()).strftime('%m_%d_%H-%M-%S')+".csv"
            f = open("logs/ground-test-"+st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position 
            # M -> motion capture | C -> commanded controls | sl -> Second marker | Mode 
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'slx','sly','slz','slr','slp','sly', \
                             'vel_x', 'vel_fx', 'vel_y', 'vel_fy', 'vel_z', 'vel_fz', \
                             'NNslX','NNslY','NNslZ' ))

        # Index for scrolling the data csv file
        data_index = 0

        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            #for channel in range(0, 4):
                #rcCMD[channel] = int(udp.message[channel])
            rcCMD[0] = int(data['Proll'][data_index])
            rcCMD[1] = int(data['Ppitch'][data_index])
            rcCMD[2] = int(data['Pyaw'][data_index])
            rcCMD[3] = int(data['Pthrottle'][data_index])

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative. 
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = data['x'][data_index]#udp.message[5]
            currentPos['y'] = data['y'][data_index]#udp.message[6]
            currentPos['z'] = data['z'][data_index]#-udp.message[7]

            # Update position of the slung load
            sl_currentPos['x'] = data['slx'][data_index]#udp.message[8]
            sl_currentPos['y'] = data['slx'][data_index]#udp.message[9]

            # Get velocities of the vehicle
            velocities['x'],velocities['fx'] = vel_x.get_velocity(currentPos['x'])
            velocities['y'],velocities['fy'] = vel_y.get_velocity(currentPos['y'])
            velocities['z'],velocities['fz'] = vel_z.get_velocity(currentPos['z'])

            # Update vehicle Attitude 
            #vehicle.getData(MultiWii.ATTITUDE)

            # Slung load PID calculation, the relative position of the vehicle vs the slung load
            sl_xPIDvalue = slx_posPID.update(sl_currentPos['x'] - currentPos['x'])
            sl_yPIDvalue = sly_posPID.update(sl_currentPos['y'] - currentPos['y'])

            # Desired position changed using slung load movements
            if int(data['Mode'][data_index]) == 1:#udp.message[4] == 1:  
                desiredPos['x'] = 0.0
                desiredPos['y'] = 0.0
            if int(data['Mode'][data_index]) == 2:#udp.message[4] == 2:
                desiredPos['x'] = limit(f_desx.update(sl_xPIDvalue), -1.0, 1.0)
                desiredPos['y'] = limit(f_desy.update(sl_yPIDvalue), -1.0, 1.0)

            # Filter new values before using them
            heading = f_yaw.update(data['Myaw'][data_index])#udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(  desiredPos['y'] - currentPos['y'])
            pPIDvalue = pitchPID.update( desiredPos['x'] - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)
            
            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll  = toPWM(degrees( (rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g) ),1)
            desiredPitch = toPWM(degrees( (pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g) ),1)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (cos(f_pitch.update(radians(data['Vroll'][data_index])))*cos(f_roll.update(radians(data['Vpitch'][data_index]))))
            if int(data['Mode'][data_index]) == 2:
                desiredThrottle = round((desiredThrottle / kt_sl) + u0, 0)
            else:
                desiredThrottle = round((desiredThrottle / kt) + u0, 0)
            desiredYaw = round(1500 - (yPIDvalue * ky), 0)

            # Limit commands for safety
            if int(data['Mode'][data_index]) == 1:
                rcCMD[0] = limit(desiredRoll,1200,1800)
                rcCMD[1] = limit(desiredPitch,1200,1800)
                rcCMD[2] = limit(desiredYaw,1000,2000)
                rcCMD[3] = limit(desiredThrottle,1000,2000)
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Auto'
            elif int(data['Mode'][data_index]) == 2:
                #rcCMD[0] = limit(desiredRoll,1200,1800)
                #rcCMD[1] = limit(desiredPitch,1200,1800)
                #rcCMD[2] = limit(desiredYaw,1000,2000)
                #rcCMD[3] = limit(desiredThrottle,1000,2000)
                mode = 'SlungLoad'
            else:
                # Prevent integrators/derivators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                slx_posPID.resetIntegrator()
                sly_posPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n,1000,2000) for n in rcCMD]

            # Neural network update
            # Order of the inputs -> vehicle roll, vehicle pitch, vehicle yaw, x, y, z, roll, pitch, yaw, throttle
            inputs = np.delete(inputs,0,1) # Delete the oldest element on the array
            # Add new column of data to the front of the stack
            inputs = np.column_stack((inputs, \
                [data['Vroll'][data_index], data['Vpitch'][data_index], data['Vyaw'][data_index], \
                 currentPos['x'], currentPos['y'], currentPos['z'], \
                 rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3] ]))
            # Get output of neural network
            outputs = prn.NNOut(inputs,net)

            # Send commands to vehicle
            #vehicle.sendCMD(8,MultiWii.SET_RAW_RC,rcCMD)
            udp.message[0] = data['Proll'][data_index]
            udp.message[1] = data['Ppitch'][data_index]
            udp.message[2] = data['Pyaw'][data_index]
            udp.message[3] = data['Pthrottle'][data_index]
            udp.message[4] = data['Mode'][data_index]

            udp.message[11] = data['Mroll'][data_index]
            udp.message[13] = data['Mpitch'][data_index]
            udp.message[12] = data['Myaw'][data_index]

            udp.message[8] = data['slx'][data_index]
            udp.message[9] = data['sly'][data_index]
            udp.message[10] = data['slz'][data_index]
            udp.message[14] = data['slr'][data_index]
            udp.message[15] = data['slp'][data_index]
            udp.message[16] = data['sly'][data_index]

            row =   (time.time(), \
                    data['Vroll'][data_index], data['Vpitch'][data_index], data['Vyaw'][data_index], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[13], udp.message[12], \
                    udp.message[4], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    udp.message[8], udp.message[9], udp.message[10], udp.message[14],udp.message[15], udp.message[16], \
                    velocities['x'], velocities['fx'], velocities['y'], velocities['fy'], velocities['z'], velocities['fz'], \
                    # The output we care about is the latest....
                    outputs[0,memory-1], outputs[1,memory-1], outputs[2,memory-1] )

            if logging:
                logger.writerow(row)

            if mode == 'Manual':
                print "[%d] Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f | Heading: %0.3f" % (data_index, mode, currentPos['x'], currentPos['y'], currentPos['z'], heading)                
            if mode == 'Auto':
                print "[%d] Mode: %s | X: %0.3f | Y: %0.3f | Z: %0.3f" % (data_index, mode, currentPos['x'], currentPos['y'], currentPos['z'])
            elif mode == 'SlungLoad':
                print "[%d] Mode: %s | SL_X: %0.3f | SL_Y: %0.3f" % (data_index, mode, sl_currentPos['x'], sl_currentPos['y'])                

            # Wait until the update_rate is completed 
            while elapsed < update_rate:
                elapsed = time.time() - current
            
            # Update data index and kill the thread when its done
            data_index = data_index + 1
            if data_index == data.shape[0]:
                print "\n\nSimulation terminated!\n"
                break
    except Exception,error:
        print "Error in control thread: "+str(error)
Example #8
0
def control():
    global vehicle, rcCMD
    global rollPID, pitchPID, heightPID, yawPID
    global desiredPos, currentPos
    global desiredRoll, desiredPitch, desiredThrottle
    global rPIDvalue, pPIDvalue, yPIDvalue
    global f_yaw, f_pitch, f_roll
    global ky

    # Start Neural network
    net = prn.loadNN('modules/network.csv')
    # Array of inputs to network
    inputs = np.zeros((10, 1))

    while True:
        if udp.active:
            print "UDP server is active..."
            break
        else:
            print "Waiting for UDP server to be active..."
        time.sleep(0.5)

    try:
        if logging:
            st = datetime.datetime.fromtimestamp(
                time.time()).strftime('%m_%d_%H-%M-%S') + ".csv"
            f = open("logs/mw-" + st, "w")
            logger = csv.writer(f)
            # V -> vehicle | P -> pilot (joystick) | D -> desired position | M -> motion capture | C -> commanded controls | NN -> Neural Network prediction
            logger.writerow(('timestamp','Vroll','Vpitch','Vyaw','Proll','Ppitch','Pyaw','Pthrottle', \
                             'x','y','z','Dx','Dy','Dz','Mroll','Mpitch','Myaw','Mode','Croll','Cpitch','Cyaw','Cthrottle', \
                             'NNroll','NNpitch','NNyaw','NNx','NNy','NNz'))
        while True:
            # Variable to time the loop
            current = time.time()
            elapsed = 0

            # Update joystick commands from UDP communication, order (roll, pitch, yaw, throttle)
            rcCMD[0] = udp.message[0]
            rcCMD[1] = udp.message[1]
            rcCMD[2] = udp.message[2]
            rcCMD[3] = udp.message[3]

            # Coordinate map from Optitrack in the MAST Lab: X, Y, Z. NED: If going up, Z is negative.
            ######### WALL ########
            #Door      | x+       |
            #          |          |
            #          |       y+ |
            #---------------------|
            # y-       |          |
            #          |          |
            #        x-|          |
            #######################
            # Update current position of the vehicle
            currentPos['x'] = udp.message[5]
            currentPos['y'] = udp.message[6]
            currentPos['z'] = -udp.message[7]

            # Update Attitude
            vehicle.getData(MultiWii.ATTITUDE)

            # Filter new values before using them
            heading = f_yaw.update(udp.message[12])

            # PID updating, Roll is for Y and Pitch for X, Z is negative
            rPIDvalue = rollPID.update(desiredPos['y'] - currentPos['y'])
            pPIDvalue = pitchPID.update(desiredPos['x'] - currentPos['x'])
            hPIDvalue = heightPID.update(desiredPos['z'] - currentPos['z'])
            yPIDvalue = yawPID.update(0.0 - heading)

            # Heading must be in radians, MultiWii heading comes in degrees, optitrack in radians
            sinYaw = sin(heading)
            cosYaw = cos(heading)

            # Conversion from desired accelerations to desired angle commands
            desiredRoll = toPWM(
                degrees((rPIDvalue * cosYaw + pPIDvalue * sinYaw) * (1 / g)),
                1)
            desiredPitch = toPWM(
                degrees((pPIDvalue * cosYaw - rPIDvalue * sinYaw) * (1 / g)),
                1)
            desiredThrottle = ((hPIDvalue + g) * vehicle_weight) / (
                cos(f_pitch.update(radians(vehicle.attitude['angx']))) *
                cos(f_roll.update(radians(vehicle.attitude['angy']))))
            desiredThrottle = (desiredThrottle / kt) + u0
            desiredYaw = 1500 - (yPIDvalue * ky)

            # Limit commands for safety
            if udp.message[4] == 1:
                rcCMD[0] = limit(desiredRoll, 1000, 2000)
                rcCMD[1] = limit(desiredPitch, 1000, 2000)
                rcCMD[2] = limit(desiredYaw, 1000, 2000)
                rcCMD[3] = limit(desiredThrottle, 1000, 2000)
                mode = 'Auto'
            else:
                # Prevent integrators/derivators to increase if they are not in use
                rollPID.resetIntegrator()
                pitchPID.resetIntegrator()
                heightPID.resetIntegrator()
                yawPID.resetIntegrator()
                mode = 'Manual'
            rcCMD = [limit(n, 1000, 2000) for n in rcCMD]

            # Neural network update
            # Order of the inputs -> roll, pitch, yaw, throttle, vehicle roll, vehicle pitch, motion capture yaw, x, y, z
            np.put(inputs, [0,1,2,3,4,5,6,7,8,9], \
                [rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                 vehicle.attitude['angx'], vehicle.attitude['angy'], udp.message[9], \
                 currentPos['x'], currentPos['y'], currentPos['z'] ])
            # Get output of neural network
            outputs = prn.NNOut(inputs, net)

            # Send commands to vehicle
            vehicle.sendCMD(8, MultiWii.SET_RAW_RC, rcCMD)

            row =   (time.time(), \
                    vehicle.attitude['angx'], vehicle.attitude['angy'], vehicle.attitude['heading'], \
                    #vehicle.rawIMU['ax'], vehicle.rawIMU['ay'], vehicle.rawIMU['az'], vehicle.rawIMU['gx'], vehicle.rawIMU['gy'], vehicle.rawIMU['gz'], \
                    #vehicle.rcChannels['roll'], vehicle.rcChannels['pitch'], vehicle.rcChannels['throttle'], vehicle.rcChannels['yaw'], \
                    udp.message[0], udp.message[1], udp.message[2], udp.message[3], \
                    currentPos['x'], currentPos['y'], currentPos['z'], desiredPos['x'], desiredPos['y'], desiredPos['z'], \
                    udp.message[11], udp.message[12], udp.message[13], \
                    udp.message[7], \
                    rcCMD[0], rcCMD[1], rcCMD[2], rcCMD[3], \
                    outputs[0,0], outputs[1,0], outputs[2,0], outputs[3,0], outputs[4,0], outputs[5,0] )
            if logging:
                logger.writerow(row)

            print "Mode: %s | Z: %0.3f | X: %0.3f | Y: %0.3f " % (
                mode, currentPos['z'], currentPos['x'], currentPos['y'])
            #print "Mode: %s | heading: %0.3f | desiredYaw: %0.3f" % (mode, heading, desiredYaw)

            # Wait until the update_rate is completed
            while elapsed < update_rate:
                elapsed = time.time() - current

    except Exception, error:
        print "Error in control thread: " + str(error)