示例#1
0
class Solar_Trainer():
    """
    This class creates a base Trainer module to train a SOLAR_GP model on training input-output pairs.
    SOLAR_GP models are serialized and sent across a custom topic message interpreted by the SolarPredictor
    """
    def __init__(self, njit, degrees, num_inducing, wgen, use_old_Z=False):
        """
        njit: number of initial jittered ponts
        degrees: degree range of jittered joints
        num_inducing: number of inducing points for sparse GP models
        wgen: weigted threshold for generating new models
        """
        self.solar = []
        self.pub_solar = rospy.Publisher('solarGP',
                                         LocalGP,
                                         queue_size=10,
                                         latch=True)
        self.njit = njit
        self.degrees = degrees
        self.num_inducing = num_inducing
        self.wgen = wgen
        self.use_old_Z = use_old_Z
        self.joint_names = []
        self.TrainData = []
        self.rate = []
        self.stop = False
        self.pub_traintime = rospy.Publisher('traintime',
                                             Float64,
                                             queue_size=10)
        self.x_topic = ""
        self.y_topic = ""

        rospy.wait_for_service('set_neutral')
        self.set_neutral = rospy.ServiceProxy('set_neutral', SetNeutral)

        rospy.wait_for_service('jitter')
        self.jitter_init = rospy.ServiceProxy('jitter', Jitter)

    def initialize(self):

        R = rospy.get_param('~train_pub_rate', 100)
        self.rate = rospy.Rate(R)
        self.buffer_duration = rospy.get_param('~buffer_duration', 0.1)
        self.buffer_size = rospy.get_param('~buffer_size', 500)

        # Robot-specific setup implemented by derived class
        self.setup_robot()

        # Jitter robot initially
        XI, YI = self.jitter_robot()
        num_joints = np.size(YI, 1)

        # Create and initialize SOLAR_GP model
        self.solar = LocalModels(self.num_inducing,
                                 wgen=self.wgen,
                                 xdim=3,
                                 ndim=num_joints * 2)
        self.solar.initializeF(XI, YI)

        # Serialize SOLAR_GP model into custom message and publish
        SolarMsg = self.constructMsg(self.solar)
        self.pub_solar.publish(SolarMsg)

        # Create Data buffer listening on training input-output topics
        self.TrainData = DataBuffer(self.x_topic, self.y_topic,
                                    self.joint_names, self.buffer_duration,
                                    self.buffer_size)

    def setup_robot(self):
        print("Setup Robot not implemented")
        return False

    def jitter_robot(self):
        XI = []
        YI = []
        print("Jitter Robot not implemented")

        #        Service based implementation
        #        self.set_neutral()
        #        self.TrainData = DataBuffer(self.x_topic, self.y_topic, self.joint_names, self.buffer_duration, self.buffer_size)
        #        self.jitter_init(self.njit, self.degrees)
        #
        #        XI = np.asarray(self.TrainData.Xexp).reshape(len(self.TrainData.Xexp),3)
        #        YI = np.asarray(self.TrainData.Yexp).reshape(len(self.TrainData.Yexp),len(self.joint_names))
        #        rospy.loginfo("Number of initial points: %s", len(XI))
        #        self.TrainData.clear()

        return XI, YI

    def jitter(self, n, Y_init, deg=5):
        """
        Randomly sample joint states within specified degree range from initial joint position
        """
        max_rough = 0.0174533
        pert = deg * max_rough * np.random.uniform(-1., 1.,
                                                   (n, np.size(Y_init, 1)))
        Y_start = Y_init + pert
        return Y_start

    def constructMsg(self, local):
        """
        Serializes SOLAR_GP object into custom ROS topic msg
        """
        LocMsg = LocalGP()
        L = []
        for count, m in enumerate(local.Models):
            GP = OSGPR_GP()
            GP.kern_var = m.kern.variance[0]
            GP.kern_lengthscale = np.array(m.kern.lengthscale).tolist()
            GP.likelihood_var = m.likelihood.variance[0]
            GP.xmean = local.LocalData[count][2][0].tolist()
            GP.ymean = local.LocalData[count][3][0].tolist()
            GP.numloc = local.LocalData[count][0]
            Z = np.array(m.Z)
            Z_old = np.array(m.Z_old)
            mu_old = np.array(m.mu_old)
            Su_old = np.array(m.Su_old)
            Kaa_old = np.array(m.Kaa_old)

            X_arr = []
            Y_arr = []
            Z_arr = []
            Z_old_arr = []
            mu_old_arr = []
            Su_old_arr = []
            Kaa_old_arr = []

            for j in range(0, np.shape(m.X)[0]):
                X_row = Arrays()
                Y_row = Arrays()
                X_row.array = np.array(m.X[j, :]).tolist()
                Y_row.array = np.array(m.Y[j, :]).tolist()
                X_arr.append(X_row)
                Y_arr.append(Y_row)

            for j in range(0, np.shape(Z)[0]):
                Z_row = Arrays()
                Z_row.array = Z[j, :].tolist()
                Z_arr.append(Z_row)

            for j in range(0, np.shape(Z_old)[0]):

                Z_old_row = Arrays()
                mu_old_row = Arrays()
                Su_old_row = Arrays()
                Kaa_old_row = Arrays()

                Z_old_row.array = Z_old[j, :].tolist()
                mu_old_row.array = mu_old[j, :].tolist()
                Su_old_row.array = Su_old[j, :].tolist()
                Kaa_old_row.array = Kaa_old[j, :].tolist()

                Z_old_arr.append(Z_old_row)
                mu_old_arr.append(mu_old_row)
                Su_old_arr.append(Su_old_row)
                Kaa_old_arr.append(Kaa_old_row)

            GP.X = X_arr
            GP.Y = Y_arr
            GP.Z = Z_arr
            GP.Z_old = Z_old_arr
            GP.mu_old = mu_old_arr
            GP.Su_old = Su_old_arr
            GP.Kaa_old = Kaa_old_arr

            L.append(GP)

        LocMsg.localGPs = L
        LocMsg.W = local.W.diagonal().tolist()
        LocMsg.M = local.M
        LocMsg.xdim = local.xdim
        LocMsg.ndim = local.ndim

        return LocMsg

    def run(self):

        while not rospy.is_shutdown() and not self.stop:
            t1 = time.time()

            # Skip training if data buffer is empty
            if not self.TrainData.Xexp:
                continue
            else:
                try:
                    # Grab training pairs from buffer
                    Xexp = np.asarray(self.TrainData.Xexp).reshape(
                        len(self.TrainData.Xexp), 3)
                    Y = np.asarray(self.TrainData.Yexp).reshape(
                        len(self.TrainData.Yexp), len(self.joint_names))
                    Yexp = self.solar.encode_ang(Y)
                except:
                    continue

            # Clear buffer
            self.TrainData.clear()
            try:
                # Train drifting model and save trained hyperparameters
                mdrift = self.solar.doOSGPR(Xexp,
                                            Yexp,
                                            self.solar.mdrift,
                                            100,
                                            use_old_Z=True,
                                            driftZ=False)
                mkl = []
                for j in range(0, self.solar.xdim):
                    mkl.append(1 / (mdrift.kern.lengthscale[j]**2))

                W = np.diag(mkl)
                self.solar.W = W
                self.solar.mdrift = mdrift
            except:
                pass

            # Partition training pairs
            self.solar.partition(Xexp.reshape(len(Xexp), self.solar.xdim),
                                 Yexp.reshape(len(Yexp), self.solar.ndim))
            try:
                # Train SOLAR_GP model
                self.solar.train()
            except:
                pass
            # Construct and publish custom SOLAR_GP ROS topic
            LocMsg = self.constructMsg(self.solar)
            self.pub_solar.publish(LocMsg)

            # Publish training time
            t2 = time.time()
            self.pub_traintime.publish(t2 - t1)
            self.rate.sleep()
示例#2
0
     
    " Train 'drift' GP"
    if i % drift == 0:
        mdrift = local.doOSGPR(Xtot[-drift:], Ytot[-drift:], local.mdrift,num_inducing ,use_old_Z=False)
        
        mkl = []
        for j in range(0, local.xdim):
            mkl.append(1/(mdrift.kern.lengthscale[j]**2))
        W = np.diag(mkl)
        
        #W = np.diag([1/(mdrift.kern.lengthscale[0]**2), 1/(mdrift.kern.lengthscale[1]**2)])
        local.W = W
        local.mdrift = mdrift    
      
    "Partition experience "    
    local.partition(Xexp.reshape(len(Xexp),local.xdim),Yexp.reshape(len(Yexp),local.ndim), flag = partition_flag)
#    local.train()
    " Train Local Models "
    try:
        local.train(flag = train_flag)
    except:
        pass
    

           
    t2 = time.time()              
    tc[i-1]= t2-t1      
    error = np.linalg.norm(X_test[i]-Xexp) 
    Error = np.hstack((Error,error))  
    i +=1