Example #1
0
def main():
    """
    OUTPUT THE MINIMUM REQUIRED TIME FOR THE RNN PATH TO COMPLETE
    """
    # Define generated data file name
    generated_file = '../../results/generated/efficiency-test.dat'

    # Collect path data from the file
    generated_path = datastore.retrieve(generated_file)

    # Calculate the indices of the end effector position columns
    pos_start_col = constants.G_POS_IDX
    pos_end_col = pos_start_col + constants.G_NUM_POS_DIMS

    # Assume time to complete path is 1 second
    dt = 1.0 / 60.0  # [s]
    t_total = (1.0 / dt) * float(len(generated_path))

    # Get the defined acceleration limit of the PA-10
    a_limit_norm = constants.G_MAX_ACCEL
    a_max_norm = 0.0

    x_curr = np.array([0.0, 0.0, 0.0])
    v_curr = np.array([0.0, 0.0, 0.0])

    for idx in xrange(len(generated_path) - 1):
        # Get the tooltip position for this and the next sample
        x_curr = pathutils.get_path_tooltip_pos(generated_path, idx)
        x_next = pathutils.get_path_tooltip_pos(generated_path, idx + 1)

        # Calculate the velocity from current to next sample
        v_next = (x_next - x_curr) / dt

        # Calculate the acceleration from current to next sample
        a = (v_next - v_curr) / dt
        a_norm = np.linalg.norm(a)

        # Store this acceleration if it's greater than the current max
        if a_norm > a_max_norm:
            a_max_norm = a_norm

        # Set the current to the next velocity
        v_curr = v_next.copy()

    print('dt: %f [s]' % dt)
    print('a_max: %f [m/s^2]' % a_max_norm)

    # Calculate the gain factor needed to bring the max norm acceleration to
    # the acceleration norm limit
    a_gain = a_limit_norm / a_max_norm

    print('gain_factor: %f' % a_gain)

    return
Example #2
0
def main():
    """
    OUTPUT THE MINIMUM REQUIRED TIME FOR THE RNN PATH TO COMPLETE
    """
    # Define generated data file name
    generated_file = '../../results/generated/efficiency-test.dat'

    # Collect path data from the file
    generated_path = datastore.retrieve(generated_file)

    # Calculate the indices of the end effector position columns
    pos_start_col = constants.G_POS_IDX
    pos_end_col = pos_start_col + constants.G_NUM_POS_DIMS

    # Assume time to complete path is 1 second
    dt = 1.0 / 60.0 # [s]
    t_total = (1.0 / dt) * float(len(generated_path))

    # Get the defined acceleration limit of the PA-10
    a_limit_norm = constants.G_MAX_ACCEL
    a_max_norm = 0.0

    x_curr = np.array([0.0, 0.0, 0.0])
    v_curr = np.array([0.0, 0.0, 0.0])

    for idx in xrange(len(generated_path)-1):
        # Get the tooltip position for this and the next sample
        x_curr = pathutils.get_path_tooltip_pos(generated_path, idx)
        x_next = pathutils.get_path_tooltip_pos(generated_path, idx+1)

        # Calculate the velocity from current to next sample
        v_next = (x_next - x_curr) / dt

        # Calculate the acceleration from current to next sample
        a = (v_next - v_curr) / dt
        a_norm = np.linalg.norm(a)

        # Store this acceleration if it's greater than the current max
        if a_norm > a_max_norm:
            a_max_norm = a_norm

        # Set the current to the next velocity
        v_curr = v_next.copy()

    print('dt: %f [s]' % dt)
    print('a_max: %f [m/s^2]' % a_max_norm)

    # Calculate the gain factor needed to bring the max norm acceleration to
    # the acceleration norm limit
    a_gain = a_limit_norm / a_max_norm

    print('gain_factor: %f' % a_gain)

    return
Example #3
0
def train_path_planning_network():
    """Train Path Planning Network

    Trains an Evolino LSTM neural network for long-term path planning for
    use in the surgical simulator.

    Returns:
        A copy of the fully-trained path planning neural network.
    """
    # Build up the list of files to use as training set
    training_dir = constants.G_TRAINING_DATA_DIR

    # Find all data files in the training data directory
    training_files = pathutils.list_data_files(training_dir)

    # Get the training data and place it into a dataset
    training_dataset = None

    # Store all training set ratings
    ratings = np.array([])

    for training_file in training_files:
        training_data = datastore.retrieve(training_file)

        # Normalize the time input of the data
        training_data = pathutils.normalize_time(training_data, t_col=constants.G_TIME_IDX)

        # Add this data sample to the training dataset
        training_dataset = datastore.list_to_dataset(
            training_data[:,constants.G_RNN_INPUT_IDX:constants.G_RNN_INPUT_IDX+constants.G_RNN_NUM_INPUTS],
            training_data[:,constants.G_RNN_OUTPUT_IDX:constants.G_RNN_OUTPUT_IDX+constants.G_RNN_NUM_OUTPUTS],
            dataset=training_dataset
        )

        # Store the rating of the data
        this_rating = training_data[1:,constants.G_RATING_IDX]
        ratings = np.hstack((ratings, this_rating))


    # Get the starting point information for testing
    output_start_idx = constants.G_RNN_OUTPUT_IDX
    output_end_idx = output_start_idx + constants.G_RNN_NUM_OUTPUTS

    output_initial_condition = training_data[0,output_start_idx:output_end_idx]
    
    # Generate the time sequence input data for testing
    time_steps = constants.G_RNN_GENERATED_TIME_STEPS
    t_input = np.linspace(start=0.0, stop=1.0, num=time_steps)
    t_input = np.reshape(t_input, (len(t_input), 1))

    gate_start_idx = constants.G_GATE_IDX
    gate_end_idx = gate_start_idx + constants.G_NUM_GATE_INPUTS

    # Pull the gate data from the last training dataset
    gate_data = training_data[0:1,gate_start_idx:gate_end_idx]
    gate_data = np.tile(gate_data, (time_steps, 1))

    # Build up a full ratings matrix
    nd_ratings = None

    for rating in ratings:
        this_rating = rating * np.ones((1, constants.G_RNN_NUM_OUTPUTS))

        if nd_ratings is None:
            nd_ratings = this_rating
        else:
            nd_ratings = np.vstack((nd_ratings, this_rating))

    # Create network and trainer
    print('>>> Building Network...')
    net = PathPlanningNetwork()

    print('>>> Initializing Trainer...')
    trainer = PathPlanningTrainer(
        evolino_network=net,
        dataset=training_dataset,
        nBurstMutationEpochs=10,
        importance=nd_ratings
    )

    # Begin the training iterations
    fitness_list = []
    max_fitness = None
    max_fitness_epoch = None

    # Draw the generated path plot
    fig = plt.figure(1, facecolor='white')
    testing_axis = fig.add_subplot(111, projection='3d')

    fig.show()

    idx = 0
    current_convergence_streak = 0
    
    while True:
        print('>>> Training Network (Iteration: %3d)...' % (idx+1))
        trainer.train()

        # Determine fitness of this network
        current_fitness = trainer.evaluation.max_fitness
        fitness_list.append(current_fitness)

        print('>>> FITNESS: %f' % current_fitness)

        # Determine if this is the minimal error network
        if max_fitness is None or max_fitness < current_fitness:
            # This is the minimum, record it
            max_fitness = current_fitness
            max_fitness_epoch = idx

        # Draw the generated path after training
        print('>>> Testing Network...')

        generated_output = net.extrapolate(t_input, [output_initial_condition], len(t_input)-1)
        generated_output = np.vstack((output_initial_condition, generated_output))

        generated_input = np.hstack((t_input, gate_data))

        # Smash together the input and output
        generated_data = np.hstack((generated_input, generated_output))

        print('>>> Drawing Generated Path...')
        pathutils.display_path(testing_axis, generated_data, title='Generated Testing Path')
       
        plt.draw()

        if current_fitness > constants.G_RNN_CONVERGENCE_THRESHOLD:
            # We've encountered a fitness higher than threshold
            current_convergence_streak += 1
        else:
            # Streak ended. Reset the streak counter
            current_convergence_streak = 0

        if current_convergence_streak == constants.G_RNN_REQUIRED_CONVERGENCE_STREAK:
            print('>>> Convergence Achieved: %d Iterations' % idx)
            break
        elif idx == constants.G_RNN_MAX_ITERATIONS - 1:
            print('>>> Reached maximum iterations (%d)' % constants.G_RNN_MAX_ITERATIONS)
            break

        idx += 1

    # Draw the iteration fitness plot
    plt.figure(facecolor='white')
    plt.cla()
    plt.title('Fitness of RNN over %d Iterations' % (idx-1))
    plt.xlabel('Training Iterations')
    plt.ylabel('Fitness')
    plt.grid(True)

    plt.plot(range(len(fitness_list)), fitness_list, 'r-')

    plt.annotate('local max', xy=(max_fitness_epoch, fitness_list[max_fitness_epoch]),
            xytext=(max_fitness_epoch, fitness_list[max_fitness_epoch]+0.01),
            arrowprops=dict(facecolor='black', shrink=0.05))

    plt.show()

    # Return a full copy of the trained neural network
    return copy.deepcopy(net)
Example #4
0
def train_lt_network():
    """Train Long-Term Network

    Trains an Evolino LSTM neural network for long-term path planning for
    use in the surgical simulator.

    Returns:
        A copy of the fully-trained path planning neural network.
    """
    # Build up the list of files to use as training set
    filepath = '../../results/'

    training_filenames = [
        'sample1.dat',
        'sample2.dat',
        'sample3.dat',
        'sample4.dat',
    ]

    testing_filename = 'sample5.dat'

    # Get the training data and place it into a dataset
    training_dataset = None

    # Store all training set ratings
    ratings = np.array([])

    for training_filename in training_filenames:
        training_file = filepath + training_filename
        training_data = datastore.retrieve(training_file)

        # Normalize the time input of the data
        training_data = pathutils.normalize_time(training_data,
                                                 t_col=constants.G_TIME_IDX)

        # Add this data sample to the training dataset
        training_dataset = datastore.list_to_dataset(
            training_data[:,
                          constants.G_LT_INPUT_IDX:constants.G_LT_INPUT_IDX +
                          constants.G_LT_NUM_INPUTS],
            training_data[:,
                          constants.G_LT_OUTPUT_IDX:constants.G_LT_OUTPUT_IDX +
                          constants.G_LT_NUM_OUTPUTS],
            dataset=training_dataset)

        # Store the rating of the data
        this_rating = training_data[1:, constants.G_RATING_IDX]
        ratings = np.hstack((ratings, this_rating))

    # Get testing data
    testing_file = filepath + testing_filename
    testing_data = datastore.retrieve(testing_file)

    testing_data = pathutils.normalize_time(testing_data,
                                            t_col=constants.G_TIME_IDX)

    # Store the testing data in a datastore object
    testing_dataset = datastore.list_to_dataset(
        testing_data[:, constants.G_LT_INPUT_IDX:constants.G_LT_INPUT_IDX +
                     constants.G_LT_NUM_INPUTS],
        testing_data[:, constants.G_LT_OUTPUT_IDX:constants.G_LT_OUTPUT_IDX +
                     constants.G_LT_NUM_OUTPUTS],
        dataset=None)

    # Build up a full ratings matrix
    nd_ratings = None

    for rating in ratings:
        this_rating = rating * np.ones((1, constants.G_LT_NUM_OUTPUTS))

        if nd_ratings is None:
            nd_ratings = this_rating
        else:
            nd_ratings = np.vstack((nd_ratings, this_rating))

    # Create network and trainer
    print('>>> Building Network...')
    net = network.LongTermPlanningNetwork()

    print('>>> Initializing Trainer...')
    trainer = network.LongTermPlanningTrainer(evolino_network=net,
                                              dataset=training_dataset,
                                              nBurstMutationEpochs=20,
                                              importance=nd_ratings)

    # Begin the training iterations
    fitness_list = []
    max_fitness = None
    max_fitness_epoch = None

    # Draw the generated path plot
    fig = plt.figure(1, facecolor='white')
    testing_axis = fig.add_subplot(111, projection='3d')

    fig.show()

    # Define paramters for convergence
    CONVERGENCE_THRESHOLD = -0.000005
    REQUIRED_CONVERGENCE_STREAK = 20

    idx = 0
    current_convergence_streak = 0

    while True:
        print('>>> Training Network (Iteration: %3d)...' % (idx + 1))
        trainer.train()

        # Determine fitness of this network
        current_fitness = trainer.evaluation.max_fitness
        fitness_list.append(current_fitness)

        print('>>> FITNESS: %f' % current_fitness)

        # Determine if this is the minimal error network
        if max_fitness is None or max_fitness < current_fitness:
            # This is the minimum, record it
            max_fitness = current_fitness
            max_fitness_epoch = idx

        # Draw the generated path after training
        print('>>> Testing Network...')
        washout_ratio = 1.0 / len(testing_data)
        _, generated_output, _ = net.calculateOutput(
            testing_dataset, washout_ratio=washout_ratio)

        generated_input = testing_data[:len(generated_output), :constants.
                                       G_TOTAL_NUM_INPUTS]

        # Smash together the input and output
        generated_data = np.hstack((generated_input, generated_output))

        print('>>> Drawing Generated Path...')
        pathutils.display_path(testing_axis,
                               generated_data,
                               testing_data,
                               title='Generated Testing Path')

        plt.draw()

        if current_fitness > CONVERGENCE_THRESHOLD:
            # We've encountered a fitness higher than threshold
            current_convergence_streak += 1
        else:
            # Streak ended. Reset the streak counter
            current_convergence_streak = 0

        if current_convergence_streak == REQUIRED_CONVERGENCE_STREAK:
            print('>>> Convergence Achieved: %d Iterations' % idx)
            break

        idx += 1

    # Draw the iteration fitness plot
    plt.figure(facecolor='white')
    plt.cla()
    plt.title('Fitness of RNN over %d Iterations' % (idx - 1))
    plt.xlabel('Training Iterations')
    plt.ylabel('Fitness')
    plt.grid(True)

    plt.plot(range(len(fitness_list)), fitness_list, 'r-')

    plt.annotate('local max',
                 xy=(max_fitness_epoch, fitness_list[max_fitness_epoch]),
                 xytext=(max_fitness_epoch,
                         fitness_list[max_fitness_epoch] + 0.01),
                 arrowprops=dict(facecolor='black', shrink=0.05))

    plt.show()

    # Return a full copy of the trained neural network
    return copy.deepcopy(net)
Example #5
0
def main():
    """
    PLOT GENERATED PATH VS TRAINING PATH
    """
    # Define generated and trained data file names
    generated_file = '../../results/generated/rnn-path.dat'

    trained_files = [
            '../../data/sample1.dat',
            '../../data/sample2.dat',
            '../../data/sample3.dat',
            '../../data/sample4.dat',
            '../../data/sample5.dat',
    ] 

    # Collect data from the files
    generated_path = datastore.retrieve(generated_file)

    trained_paths = []
    for file in trained_files:
        path_data = datastore.retrieve(file)
        trained_paths.append(path_data)

    # Calculate the closest point for each path to the markers
    generated_distances = calculate_closest_approaches(generated_path)

    trained_distances = []
    for path in trained_paths:
        distances = calculate_closest_approaches(path)
        trained_distances.append(distances)


    # Print out the individual distances in meters as well as the average
    # of the human-generated path distances
    cumulative_distance_per_gate = []
    for _ in xrange(constants.G_NUM_GATES):
        cumulative_distance_per_gate.append(0.0)

    for dataset_idx, gate_distances in enumerate(trained_distances):
        for gate_idx, distance in enumerate(gate_distances):
            # Gather up the sum of the distances for each gate
            cumulative_distance_per_gate[gate_idx] += distance

            print('Human Dataset %d, Gate %d, Closest Approach: %f [m]' %
                    (dataset_idx, gate_idx, distance))

    # Show the distance of closest approach of the RNN dataset
    rnn_overall_cumulative_distance = 0.0

    for gate_idx, distance in enumerate(generated_distances):
        rnn_overall_cumulative_distance += distance

        print('RNN Dataset, Gate %d, Closest Approach: %f [m]' %
                (gate_idx, distance))

    # Calculate the average RNN distance of closest approach
    rnn_overall_average = (rnn_overall_cumulative_distance /
            float(constants.G_NUM_GATES))

    # Calculate the average for each gate (human-performed data)
    average_distance_per_gate = []
    human_overall_cumulative = 0.0

    for gate_idx in xrange(constants.G_NUM_GATES):
        average_distance_this_gate = (cumulative_distance_per_gate[gate_idx] /
                float(len(trained_distances)))

        human_overall_cumulative += average_distance_this_gate

        print('All Human Datasets, Gate %d, Average Closest Approach: %f [m]' %
                (gate_idx, average_distance_this_gate))

    human_overall_average = (human_overall_cumulative / 
            float(constants.G_NUM_GATES))

    print('Human overall average: %f [m]' % human_overall_average)
    print('RNN overall average: %f [m]' % rnn_overall_average)

    # Draw up the plot...

    # Number of indicies in the chart (each marker)
    indices = np.arange(constants.G_NUM_GATES)

    # Width of the bars in the bar chart
    width = 0.1

    plt.subplots(facecolor='white')

    # Draw the generated path's closest approaches
    plt.bar(indices, generated_distances, width, color='b', label='generated path')

    # Draw the closest approaches for all trained paths
    for idx, distances in enumerate(trained_distances):
        this_label = None

        if idx == 0:
            this_label = 'training path'

        plt.bar(indices+(width*(idx+1)), distances, width, color='r', label=this_label)

    plt.xlabel('Marker Number')
    plt.xlim(right=indices[-1]+(width+(width*len(trained_files))))
    plt.ylabel('Distance of Closest Approach [m]')
    plt.title('Distance of Closest Approach of Tooltip to Each Marker (Generated vs Training Paths)')
    plt.legend()

    plt.show()

    """
    PLOT DYNAMIC VS STATIC PATH CLOSEST APPROACH
    """
    # Define files holding the static and dynamic path data
    dynamic_file = '../../results/generated/final-path.dat'
    static_file = '../../results/generated/rnn-path.dat'

    # Retrieve the path data from these files
    dynamic_path = datastore.retrieve(dynamic_file)
    static_path = datastore.retrieve(static_file)

    # Calculate distances of closest approach
    dynamic_distances = calculate_closest_approaches(dynamic_path)
    static_distances = calculate_closest_approaches(static_path)

    for gate_idx in xrange(constants.G_NUM_GATES):
        print('Gate %d, Static Distance: %f [m]' % (gate_idx, 
                static_distances[gate_idx]))
        print('Gate %d, Dynamic Distance: %f [m]' % (gate_idx,
                dynamic_distances[gate_idx]))

    print('Average Static Distances: %f [m]' % np.average(static_distances))
    print('Average Dyanmic Distances: %f [m]' % np.average(dynamic_distances))
    width = 0.2

    # Clear the current plot
    plt.cla()

    # Plot the distance of closest approach of the paths to each marker
    plt.subplots(facecolor='white')

    plt.bar(indices, dynamic_distances, width, color='b', label='dynamic path')
    plt.bar(indices+width, static_distances, width, color='r', label='static path')

    plt.xlabel('Marker Number')
    plt.xlim(right=indices[-1]+(width*2))
    plt.ylabel('Distance of Closest Approach [m]')
    plt.title('Distance of Closest Approach of Tooltip to Each Marker (Dynamic vs Static Paths)')
    plt.legend()

    plt.show()
   
    return
def train_lt_network():
    """Train Long-Term Network

    Trains an Evolino LSTM neural network for long-term path planning for
    use in the surgical simulator.

    Returns:
        A copy of the fully-trained path planning neural network.
    """
    # Build up the list of files to use as training set
    filepath = "../../results/"

    training_filenames = ["sample1.dat", "sample2.dat", "sample3.dat", "sample4.dat"]

    testing_filename = "sample5.dat"

    # Get the training data and place it into a dataset
    training_dataset = None

    # Store all training set ratings
    ratings = np.array([])

    for training_filename in training_filenames:
        training_file = filepath + training_filename
        training_data = datastore.retrieve(training_file)

        # Normalize the time input of the data
        training_data = pathutils.normalize_time(training_data, t_col=constants.G_TIME_IDX)

        # Add this data sample to the training dataset
        training_dataset = datastore.list_to_dataset(
            training_data[:, constants.G_LT_INPUT_IDX : constants.G_LT_INPUT_IDX + constants.G_LT_NUM_INPUTS],
            training_data[:, constants.G_LT_OUTPUT_IDX : constants.G_LT_OUTPUT_IDX + constants.G_LT_NUM_OUTPUTS],
            dataset=training_dataset,
        )

        # Store the rating of the data
        this_rating = training_data[1:, constants.G_RATING_IDX]
        ratings = np.hstack((ratings, this_rating))

    # Get testing data
    testing_file = filepath + testing_filename
    testing_data = datastore.retrieve(testing_file)

    testing_data = pathutils.normalize_time(testing_data, t_col=constants.G_TIME_IDX)

    # Store the testing data in a datastore object
    testing_dataset = datastore.list_to_dataset(
        testing_data[:, constants.G_LT_INPUT_IDX : constants.G_LT_INPUT_IDX + constants.G_LT_NUM_INPUTS],
        testing_data[:, constants.G_LT_OUTPUT_IDX : constants.G_LT_OUTPUT_IDX + constants.G_LT_NUM_OUTPUTS],
        dataset=None,
    )

    # Build up a full ratings matrix
    nd_ratings = None

    for rating in ratings:
        this_rating = rating * np.ones((1, constants.G_LT_NUM_OUTPUTS))

        if nd_ratings is None:
            nd_ratings = this_rating
        else:
            nd_ratings = np.vstack((nd_ratings, this_rating))

    # Create network and trainer
    print(">>> Building Network...")
    net = network.LongTermPlanningNetwork()

    print(">>> Initializing Trainer...")
    trainer = network.LongTermPlanningTrainer(
        evolino_network=net, dataset=training_dataset, nBurstMutationEpochs=20, importance=nd_ratings
    )

    # Begin the training iterations
    fitness_list = []
    max_fitness = None
    max_fitness_epoch = None

    # Draw the generated path plot
    fig = plt.figure(1, facecolor="white")
    testing_axis = fig.add_subplot(111, projection="3d")

    fig.show()

    # Define paramters for convergence
    CONVERGENCE_THRESHOLD = -0.000005
    REQUIRED_CONVERGENCE_STREAK = 20

    idx = 0
    current_convergence_streak = 0

    while True:
        print(">>> Training Network (Iteration: %3d)..." % (idx + 1))
        trainer.train()

        # Determine fitness of this network
        current_fitness = trainer.evaluation.max_fitness
        fitness_list.append(current_fitness)

        print(">>> FITNESS: %f" % current_fitness)

        # Determine if this is the minimal error network
        if max_fitness is None or max_fitness < current_fitness:
            # This is the minimum, record it
            max_fitness = current_fitness
            max_fitness_epoch = idx

        # Draw the generated path after training
        print(">>> Testing Network...")
        washout_ratio = 1.0 / len(testing_data)
        _, generated_output, _ = net.calculateOutput(testing_dataset, washout_ratio=washout_ratio)

        generated_input = testing_data[: len(generated_output), : constants.G_TOTAL_NUM_INPUTS]

        # Smash together the input and output
        generated_data = np.hstack((generated_input, generated_output))

        print(">>> Drawing Generated Path...")
        pathutils.display_path(testing_axis, generated_data, testing_data, title="Generated Testing Path")

        plt.draw()

        if current_fitness > CONVERGENCE_THRESHOLD:
            # We've encountered a fitness higher than threshold
            current_convergence_streak += 1
        else:
            # Streak ended. Reset the streak counter
            current_convergence_streak = 0

        if current_convergence_streak == REQUIRED_CONVERGENCE_STREAK:
            print(">>> Convergence Achieved: %d Iterations" % idx)
            break

        idx += 1

    # Draw the iteration fitness plot
    plt.figure(facecolor="white")
    plt.cla()
    plt.title("Fitness of RNN over %d Iterations" % (idx - 1))
    plt.xlabel("Training Iterations")
    plt.ylabel("Fitness")
    plt.grid(True)

    plt.plot(range(len(fitness_list)), fitness_list, "r-")

    plt.annotate(
        "local max",
        xy=(max_fitness_epoch, fitness_list[max_fitness_epoch]),
        xytext=(max_fitness_epoch, fitness_list[max_fitness_epoch] + 0.01),
        arrowprops=dict(facecolor="black", shrink=0.05),
    )

    plt.show()

    # Return a full copy of the trained neural network
    return copy.deepcopy(net)
    training_filenames = [
        'sample1.dat',
        'sample2.dat',
        'sample3.dat',
        'sample4.dat',
    ]

    testing_filename = 'sample5.dat'

    # Build a training dataset from all training file data
    training_dataset = None

    for training_filename in training_filenames:
        training_file = filepath + training_filename
        training_data = datastore.retrieve(training_file)

        # Split the file into gate segments
        training_segments = pathutils.split_segments(training_data)

        # Add each segment as a new entry in the dataset
        for gate, path in enumerate(training_segments):
            # Get short-term training inputs
            input_start_idx = constants.G_ST_INPUT_IDX + (gate * constants.G_NUM_GATE_DIMS)
            input_end_idx = input_start_idx + constants.G_ST_NUM_INPUTS
            input = path[:,input_start_idx:input_end_idx]

            # Get short-term training outputs
            output_start_idx = constants.G_ST_OUTPUT_IDX
            output_end_idx = output_start_idx + constants.G_ST_NUM_OUTPUTS
            output = path[:,output_start_idx:output_end_idx]
Example #8
0
    training_filenames = [
        'sample1.dat',
        'sample2.dat',
        'sample3.dat',
        'sample4.dat',
    ]

    testing_filename = 'sample5.dat'

    # Build a training dataset from all training file data
    training_dataset = None

    for training_filename in training_filenames:
        training_file = filepath + training_filename
        training_data = datastore.retrieve(training_file)

        # Split the file into gate segments
        training_segments = pathutils.split_segments(training_data)

        # Add each segment as a new entry in the dataset
        for gate, path in enumerate(training_segments):
            # Get short-term training inputs
            input_start_idx = constants.G_ST_INPUT_IDX + (
                gate * constants.G_NUM_GATE_DIMS)
            input_end_idx = input_start_idx + constants.G_ST_NUM_INPUTS
            input = path[:, input_start_idx:input_end_idx]

            # Get short-term training outputs
            output_start_idx = constants.G_ST_OUTPUT_IDX
            output_end_idx = output_start_idx + constants.G_ST_NUM_OUTPUTS
Example #9
0
    def start(self, fps, fast_step=False):
        """Start

        Begin the continuous event loop for the simulation. This event loop
        can be exited using the ctrl+c keyboard interrupt. Real-time
        constraints are enforced. [Hz]

        Arguments:
            fps: The value of frames per second of the simulation.
            fast_step: If True, the ODE fast step algorithm will be used.
                This is faster and requires less memory but is less accurate.
                (Default: False)
        """
        paused = False
        stopped = False

        # Define the total time for the tooltip traversal
        t_total = 20.0

        # Define the simulation frame rate
        t = 0.0  # [s]
        dt = 1.0 / float(fps)  # [s]

        # Keep track of time overshoot in the case that simulation time must be
        # increased in order to maintain real-time constraints
        t_overshoot = 0.0

        # Get the initial path position (center of gate7)
        pos_start = self.env.get_body_pos('gate7')  # [m]

        # Get the first position of the PA10 at rest
        pos_init = self.env.get_body_pos('tooltip')  # [m]

        # Calculate the new required joint angles of the PA10
        #pa10_joint_angles = self.kinematics.calc_inverse_kinematics(pos_init, pos_start)

        # TODO: Move the PA10 end-effector to the starting position along the path

        # TODO: TEMP - Move the temporary end-effector pointer to the starting position
        self.env.set_group_pos('pointer', pos_start)

        # Generate long-term path from initial position
        t_input = np.linspace(start=0.0, stop=1.0, num=t_total / dt)
        t_input = np.reshape(t_input, (len(t_input), 1))

        rnn_path = self.rnn.extrapolate(t_input, [pos_start], len(t_input) - 1)

        # Add the initial condition point back onto the data
        rnn_path = np.vstack((pos_start, rnn_path))

        # Retrieve one set of standard gate position/orientation data
        file_path = pathutils.list_data_files(constants.G_TRAINING_DATA_DIR)[0]

        gate_data = datastore.retrieve(file_path)

        gate_start_idx = constants.G_GATE_IDX
        gate_end_idx = gate_start_idx + constants.G_NUM_GATE_INPUTS

        # Reshape the gate positions data
        gate_data = gate_data[0:1, gate_start_idx:gate_end_idx]
        gate_data = np.tile(gate_data, (len(rnn_path), 1))

        # Complete the rnn path data
        rnn_path = np.hstack((t_input, gate_data, rnn_path))

        # Save generated path for later examination
        datastore.store(rnn_path, constants.G_RNN_STATIC_PATH_OUT)

        # Define a variable to hold the final path (with real-time correction)
        final_path = rnn_path[:-1].copy()
        path_saved = False

        # Detect all path segments between gates in the generated path
        segments = pathutils._detect_segments(rnn_path)

        path_idx = 0

        x_path_offset = np.array([0.0, 0.0, 0.0])  # [m]
        v_curr = np.array([0.0, 0.0, 0.0])  # [m/s]
        a_max = constants.G_MAX_ACCEL  # [m/s^2]

        # Get the static table position
        x_table = self.env.get_body_pos('table')

        while not stopped:
            t_start = time.time()

            # If the last calculation took too long, catch up
            dt_warped = dt + t_overshoot

            self.env.set_dt(dt_warped)

            # Determine if the viewer is stopped. Then we can quit
            if self.viewer.is_dead:
                break

            # Pause the simulation if we are at the end
            if path_idx == len(rnn_path) - 1 or paused:
                self.env.step(paused=True, fast=fast_step)

                # If we have really hit the end of the simulation, save/plot the path
                if not paused and not path_saved:
                    # Save the final data to a file
                    datastore.store(final_path,
                                    constants.G_RNN_DYNAMIC_PATH_OUT)
                    path_saved = True

                continue

            # Not a very elegant solution to pausing at the start, but it works
            if t <= 1000.0:
                self.env.step(paused=True, fast=fast_step)
                t += dt_warped
                continue

            # Determine the current path segment
            curr_segment_idx = 0

            for segment_idx, segment_end in enumerate(segments):
                if path_idx <= segment_end:
                    curr_segment_idx = segment_idx
                    break

            x_curr = pathutils.get_path_tooltip_pos(rnn_path,
                                                    path_idx) + x_path_offset
            x_next = pathutils.get_path_tooltip_pos(
                rnn_path, path_idx + 1) + x_path_offset

            # Get the expected gate position
            x_gate_expected = pathutils.get_path_gate_pos(
                rnn_path, segments[curr_segment_idx], curr_segment_idx)

            # Get the actual gate position
            x_gate_actual = self.env.get_body_pos('gate%d' % curr_segment_idx)

            # Calculate the new position from change to new gate position
            dx_gate = x_gate_actual - (x_gate_expected + x_path_offset)
            x_new = x_next + dx_gate

            # Calculate the new velocity
            v_new = (x_new - x_curr) / dt_warped

            # Calculate the new acceleration
            a_new = (v_new - v_curr) / dt_warped

            # Calculate the acceleration vector norm
            a_new_norm = np.linalg.norm(a_new)

            # Limit the norm vector
            a_new_norm_clipped = np.clip(a_new_norm, -a_max, a_max)

            # Determine the ratio of the clipped norm, protect against divide by zero
            if a_new_norm != 0.0:
                ratio_unclipped = a_new_norm_clipped / a_new_norm
            else:
                ratio_unclipped = 0.0

            # Scale the acceleration vector by this ratio
            a_new = a_new * ratio_unclipped

            # Calculate the new change in velocity
            dv_new = a_new * dt_warped
            v_new = v_curr + dv_new

            # Calculate the new change in position
            dx_new = v_new * dt_warped
            x_new = x_curr + dx_new

            # Modify final path data with current tooltip and gate positions
            pathutils.set_path_time(final_path, path_idx, t)
            pathutils.set_path_tooltip_pos(final_path, path_idx, x_curr)

            for gate_idx in range(constants.G_NUM_GATES):
                gate_name = 'gate%d' % gate_idx
                x_gate = self.env.get_body_pos(gate_name)
                pathutils.set_path_gate_pos(final_path, path_idx, gate_idx,
                                            x_gate)

            # Store this velocity for the next time step
            v_curr = v_new

            # Recalculate the current offset
            x_path_offset += x_new - x_next

            # Perform inverse kinematics to get joint angles
            pa10_joint_angles = self.kinematics.calc_inverse_kinematics(
                x_curr, x_new)

            # TODO: TEMP - MOVE ONLY POINTER, NO PA10
            self.env.set_group_pos('pointer', x_new)

            if constants.G_TABLE_IS_OSCILLATING:
                # Move the table with y-axis oscillation
                x_table_next = shaker_table(t, x_table)
            else:
                x_table_next = x_table

            self.env.set_body_pos('table', x_table_next)

            # Step through the world by 1 time frame and actuate pa10 joints
            self.env.performAction(pa10_joint_angles, fast=fast_step)

            # Update current time after this step
            t += dt_warped
            path_idx += 1

            # Determine the difference in virtual vs actual time
            t_warped = dt - (time.time() - t_start)

            # Attempt to enforce real-time constraints
            if t_warped >= 0.0:
                # The calculation took less time than the virtual time. Sleep
                # the rest off
                time.sleep(t_warped)
                t_overshoot = 0.0
            else:
                # The calculation took more time than the virtual time. We need
                # to catch up with the virtual time on the next time step
                t_overshoot = -t_warped

        return
Example #10
0
def main():
    path_file = '../../neuralsim/generated.dat'  #'../../results/sample5.dat'
    path = datastore.retrieve(path_file)

    # A list of the the segments of the optimized path
    segments = pathutils._detect_segments(path)

    # The new path generated by original path and corrective algorithm
    new_path = None

    x_path_offset = np.array([0.0, 0.0, 0.0])  # [m]
    v_curr = np.array([0.0, 0.0, 0.0])  # [m/s]
    a_max = constants.G_MAX_ACCEL  # [m/s^2]

    for i, _ in enumerate(path):
        if i == len(path) - 1:
            continue

        # Detect current segment
        seg_idx = 0

        for j in range(len(segments)):
            if i <= segments[j]:
                seg_idx = j
                break

        # Get current time and position
        t_curr = pathutils.get_path_time(path, i) * t_total
        t_next = pathutils.get_path_time(path, i + 1) * t_total

        dt = (t_next - t_curr)

        x_curr = pathutils.get_path_tooltip_pos(path, i) + x_path_offset
        x_next = pathutils.get_path_tooltip_pos(path, i + 1) + x_path_offset

        # Get the expected gate position at this timestep
        x_gate_expected = pathutils.get_path_gate_pos(path, segments[seg_idx],
                                                      seg_idx)

        # Get current gate position
        x_gate_actual = generate_gate_pos(t_curr, path, seg_idx)

        dx_gate = x_gate_actual - (x_gate_expected + x_path_offset)

        # Calculate the new position with positional change from target to gate
        x_new = x_next + dx_gate

        # Calculate the new velocity
        v_new = (x_new - x_curr) / dt

        # Calculate the new acceleration
        a_new = (v_new - v_curr) / dt

        # Calculate the acceleration vector norm
        a_new_norm = np.linalg.norm(a_new)

        # Limit the norm vector
        a_new_norm_clipped = np.clip(a_new_norm, -a_max, a_max)

        # Determine the ratio of the clipped norm
        if a_new_norm != 0:
            ratio_unclipped = a_new_norm_clipped / a_new_norm
        else:
            ratio_unclipped = 0.0

        # Scale the acceleration vector by this ratio
        a_new = a_new * ratio_unclipped

        # Calculate the new change in velocity
        dv_new = a_new * dt
        v_new = v_curr + dv_new

        # Calculate the new change in position
        dx_new = v_new * dt
        x_new = x_curr + dx_new

        # Store the next movement for later
        if new_path is None:
            new_path = x_new
        else:
            new_path = np.vstack((new_path, x_new))

        # Store this velocity for the next time step
        v_curr = v_new

        # Recalculate the current offset
        x_path_offset += x_new - x_next

    # Plot the inputted path
    fig = plt.figure(facecolor='white')
    axis = fig.gca(projection='3d')

    pos_start_idx = constants.G_POS_IDX
    pos_end_idx = pos_start_idx + constants.G_NUM_POS_DIMS

    full_path = path[:-1].copy()
    full_path[:, pos_start_idx:pos_end_idx] = new_path

    pathutils.display_path(axis, full_path, title='Path')

    plt.show()

    return
Example #11
0
    parser.add_argument('-d',
                        '--two-dimensional',
                        help='show 2d representation of the path (x, z)',
                        action='store_true')
    parser.add_argument('-a',
                        '--label-axes',
                        help='show plot axes labels',
                        action='store_true')
    parser.add_argument('-r',
                        '--ratings',
                        help='print out segment ratings along with the plot',
                        action='store_true')
    args = parser.parse_args()

    main_file = args.paths[0]
    main_path = datastore.retrieve(main_file)

    # Plot all reference paths
    reference_paths = []

    for reference_file in args.paths[1:]:
        reference_data = datastore.retrieve(reference_file)
        reference_paths.append(reference_data)

    # Trim if requested
    if args.trim:
        main_path = trim_path(main_path)

    # Normalize time if requested
    if args.normalize:
        main_path = normalize_time(main_path)
Example #12
0
    def start(self, fps, fast_step=False):
        """Start

        Begin the continuous event loop for the simulation. This event loop
        can be exited using the ctrl+c keyboard interrupt. Real-time
        constraints are enforced. [Hz]

        Arguments:
            fps: The value of frames per second of the simulation.
            fast_step: If True, the ODE fast step algorithm will be used.
                This is faster and requires less memory but is less accurate.
                (Default: False)
        """
        paused = False
        stopped = False

        # Define the total time for the tooltip traversal
        t_total = 20.0

        # Define the simulation frame rate
        t = 0.0 # [s]
        dt = 1.0 / float(fps) # [s]

        # Keep track of time overshoot in the case that simulation time must be
        # increased in order to maintain real-time constraints
        t_overshoot = 0.0

        # Get the initial path position (center of gate7)
        pos_start = self.env.get_body_pos('gate7') # [m]

        # Get the first position of the PA10 at rest
        pos_init = self.env.get_body_pos('tooltip') # [m]

        # Calculate the new required joint angles of the PA10
        #pa10_joint_angles = self.kinematics.calc_inverse_kinematics(pos_init, pos_start)

        # TODO: Move the PA10 end-effector to the starting position along the path

        # TODO: TEMP - Move the temporary end-effector pointer to the starting position
        self.env.set_group_pos('pointer', pos_start)

        # Generate long-term path from initial position
        t_input = np.linspace(start=0.0, stop=1.0, num=t_total/dt)
        t_input = np.reshape(t_input, (len(t_input), 1))

        rnn_path = self.rnn.extrapolate(t_input, [pos_start], len(t_input)-1)

        # Add the initial condition point back onto the data
        rnn_path = np.vstack((pos_start, rnn_path))

        # Retrieve one set of standard gate position/orientation data
        file_path = pathutils.list_data_files(constants.G_TRAINING_DATA_DIR)[0]

        gate_data = datastore.retrieve(file_path)

        gate_start_idx = constants.G_GATE_IDX
        gate_end_idx = gate_start_idx + constants.G_NUM_GATE_INPUTS

        # Reshape the gate positions data
        gate_data = gate_data[0:1,gate_start_idx:gate_end_idx]
        gate_data = np.tile(gate_data, (len(rnn_path), 1))

        # Complete the rnn path data
        rnn_path = np.hstack((t_input, gate_data, rnn_path))

        # Save generated path for later examination
        datastore.store(rnn_path, constants.G_RNN_STATIC_PATH_OUT)

        # Define a variable to hold the final path (with real-time correction)
        final_path = rnn_path[:-1].copy()
        path_saved = False

        # Detect all path segments between gates in the generated path
        segments = pathutils._detect_segments(rnn_path)

        path_idx = 0

        x_path_offset = np.array([0.0, 0.0, 0.0]) # [m]
        v_curr = np.array([0.0, 0.0, 0.0]) # [m/s]
        a_max = constants.G_MAX_ACCEL # [m/s^2]

        # Get the static table position
        x_table = self.env.get_body_pos('table')

        while not stopped:
            t_start = time.time()

            # If the last calculation took too long, catch up
            dt_warped = dt + t_overshoot

            self.env.set_dt(dt_warped)

            # Determine if the viewer is stopped. Then we can quit
            if self.viewer.is_dead:
                break

            # Pause the simulation if we are at the end
            if path_idx == len(rnn_path) - 1 or paused:
                self.env.step(paused=True, fast=fast_step)

                # If we have really hit the end of the simulation, save/plot the path
                if not paused and not path_saved:
                    # Save the final data to a file
                    datastore.store(final_path, constants.G_RNN_DYNAMIC_PATH_OUT)
                    path_saved = True

                continue

            # Not a very elegant solution to pausing at the start, but it works
            if t <= 1000.0:
                self.env.step(paused=True, fast=fast_step)
                t += dt_warped
                continue

            # Determine the current path segment
            curr_segment_idx = 0

            for segment_idx, segment_end in enumerate(segments):
                if path_idx <= segment_end:
                    curr_segment_idx = segment_idx
                    break

            x_curr = pathutils.get_path_tooltip_pos(rnn_path, path_idx) + x_path_offset
            x_next = pathutils.get_path_tooltip_pos(rnn_path, path_idx+1) + x_path_offset

            # Get the expected gate position
            x_gate_expected = pathutils.get_path_gate_pos(
                    rnn_path,
                    segments[curr_segment_idx],
                    curr_segment_idx
            )

            # Get the actual gate position
            x_gate_actual = self.env.get_body_pos('gate%d'%curr_segment_idx)

            # Calculate the new position from change to new gate position
            dx_gate = x_gate_actual - (x_gate_expected + x_path_offset)
            x_new = x_next + dx_gate

            # Calculate the new velocity
            v_new = (x_new - x_curr) / dt_warped

            # Calculate the new acceleration
            a_new = (v_new - v_curr) / dt_warped

            # Calculate the acceleration vector norm
            a_new_norm = np.linalg.norm(a_new)

            # Limit the norm vector
            a_new_norm_clipped = np.clip(a_new_norm, -a_max, a_max)

            # Determine the ratio of the clipped norm, protect against divide by zero
            if a_new_norm != 0.0:
                ratio_unclipped = a_new_norm_clipped / a_new_norm
            else:
                ratio_unclipped = 0.0

            # Scale the acceleration vector by this ratio
            a_new = a_new * ratio_unclipped

            # Calculate the new change in velocity
            dv_new = a_new * dt_warped
            v_new = v_curr + dv_new

            # Calculate the new change in position
            dx_new = v_new * dt_warped
            x_new = x_curr + dx_new

            # Modify final path data with current tooltip and gate positions
            pathutils.set_path_time(final_path, path_idx, t)
            pathutils.set_path_tooltip_pos(final_path, path_idx, x_curr)

            for gate_idx in range(constants.G_NUM_GATES):
                gate_name = 'gate%d' % gate_idx
                x_gate = self.env.get_body_pos(gate_name)
                pathutils.set_path_gate_pos(final_path, path_idx, gate_idx, x_gate)

            # Store this velocity for the next time step
            v_curr = v_new

            # Recalculate the current offset
            x_path_offset += x_new - x_next

            # Perform inverse kinematics to get joint angles
            pa10_joint_angles = self.kinematics.calc_inverse_kinematics(x_curr, x_new)

            # TODO: TEMP - MOVE ONLY POINTER, NO PA10
            self.env.set_group_pos('pointer', x_new)

            if constants.G_TABLE_IS_OSCILLATING:
                # Move the table with y-axis oscillation
                x_table_next = shaker_table(t, x_table)
            else:
                x_table_next = x_table

            self.env.set_body_pos('table', x_table_next)

            # Step through the world by 1 time frame and actuate pa10 joints
            self.env.performAction(pa10_joint_angles, fast=fast_step)

            # Update current time after this step
            t += dt_warped
            path_idx += 1

            # Determine the difference in virtual vs actual time
            t_warped = dt - (time.time() - t_start)

            # Attempt to enforce real-time constraints
            if t_warped >= 0.0:
                # The calculation took less time than the virtual time. Sleep
                # the rest off
                time.sleep(t_warped)
                t_overshoot = 0.0
            else:
                # The calculation took more time than the virtual time. We need
                # to catch up with the virtual time on the next time step
                t_overshoot = -t_warped

        return
Example #13
0
def main():
    path_file = '../../neuralsim/generated.dat'#'../../results/sample5.dat'
    path = datastore.retrieve(path_file)

    # A list of the the segments of the optimized path
    segments = pathutils._detect_segments(path)

    # The new path generated by original path and corrective algorithm
    new_path = None

    x_path_offset = np.array([0.0, 0.0, 0.0]) # [m]
    v_curr = np.array([0.0, 0.0, 0.0]) # [m/s]
    a_max = constants.G_MAX_ACCEL # [m/s^2]

    for i, _ in enumerate(path):
        if i == len(path) - 1:
            continue

        # Detect current segment
        seg_idx = 0

        for j in range(len(segments)):
            if i <= segments[j]:
                seg_idx = j
                break

        # Get current time and position
        t_curr = pathutils.get_path_time(path, i) * t_total
        t_next = pathutils.get_path_time(path, i+1) * t_total

        dt = (t_next - t_curr)

        x_curr = pathutils.get_path_tooltip_pos(path, i) + x_path_offset
        x_next = pathutils.get_path_tooltip_pos(path, i+1) + x_path_offset

        # Get the expected gate position at this timestep
        x_gate_expected = pathutils.get_path_gate_pos(path, segments[seg_idx], seg_idx)

        # Get current gate position
        x_gate_actual = generate_gate_pos(t_curr, path, seg_idx)

        dx_gate = x_gate_actual - (x_gate_expected + x_path_offset)

        # Calculate the new position with positional change from target to gate
        x_new = x_next + dx_gate

        # Calculate the new velocity
        v_new = (x_new - x_curr) / dt

        # Calculate the new acceleration
        a_new = (v_new - v_curr) / dt

        # Calculate the acceleration vector norm
        a_new_norm = np.linalg.norm(a_new)

        # Limit the norm vector
        a_new_norm_clipped = np.clip(a_new_norm, -a_max, a_max)

        # Determine the ratio of the clipped norm
        if a_new_norm != 0:
            ratio_unclipped = a_new_norm_clipped / a_new_norm
        else:
            ratio_unclipped = 0.0

        # Scale the acceleration vector by this ratio
        a_new = a_new * ratio_unclipped

        # Calculate the new change in velocity
        dv_new = a_new * dt
        v_new = v_curr + dv_new

        # Calculate the new change in position
        dx_new = v_new * dt
        x_new = x_curr + dx_new

        # Store the next movement for later
        if new_path is None:
            new_path = x_new
        else:
            new_path = np.vstack((new_path, x_new))

        # Store this velocity for the next time step
        v_curr = v_new

        # Recalculate the current offset
        x_path_offset += x_new - x_next 

    # Plot the inputted path
    fig = plt.figure(facecolor='white')
    axis = fig.gca(projection='3d')

    pos_start_idx = constants.G_POS_IDX
    pos_end_idx = pos_start_idx + constants.G_NUM_POS_DIMS

    full_path = path[:-1].copy()
    full_path[:,pos_start_idx:pos_end_idx] = new_path

    pathutils.display_path(axis, full_path, title='Path')

    plt.show()

    return
Example #14
0
                        default=None)
    parser.add_argument('paths', nargs='+',
                        help='file(s) containing path data')
    parser.add_argument('-d', '--two-dimensional',
                        help='show 2d representation of the path (x, z)',
                        action='store_true')
    parser.add_argument('-a', '--label-axes',
                        help='show plot axes labels',
                        action='store_true')
    parser.add_argument('-r', '--ratings',
                        help='print out segment ratings along with the plot',
                        action='store_true')
    args = parser.parse_args()

    main_file = args.paths[0]
    main_path = datastore.retrieve(main_file)

    # Plot all reference paths
    reference_paths = []

    for reference_file in args.paths[1:]:
        reference_data = datastore.retrieve(reference_file)
        reference_paths.append(reference_data)

    # Trim if requested
    if args.trim:
        main_path = trim_path(main_path)

    # Normalize time if requested
    if args.normalize:
        main_path = normalize_time(main_path)