Exemplo n.º 1
0
def _print_violations(violation_dicts, limits, limit_type):
    """
    Format and print limit violations.
    :param violation_dicts: A list of dicts of axis violations
    :param limits: A list of robot robot axes limits
    :param limit_type: Name string of the limit type
    :return:
    """
    warning = ''
    warning_template = '   {0:>{time_padding}}{1:>{frame_padding}}{2:>{limit_padding}}{3:>{val_padding}}\n'
    padding = {'val_padding' : 13, 'limit_padding' : 10, 'time_padding' : 10, 'frame_padding' : 10}
    
    for axis_name in sorted(violation_dicts):
        warning += axis_name + " {} Warnings:\n".format(limit_type)
        axis_num = int(axis_name.split(' ')[-1]) - 1  # This is super hacky... should fix.
        warning += warning_template.format('Time', 'Frame', 'Limit', 'Actual', **padding)
        for violation in violation_dicts[axis_name]:
            if limits[axis_name]['Max Limit']:
                axis_limit = general_utils.num_to_str(limits[axis_name]['Max Limit'], precision=3)
            else:
                return 

            warning += warning_template.format(
                general_utils.num_to_str(violation['Time Index'], precision=3),
                general_utils.num_to_str(violation['Frame'], precision=3),
                axis_limit,
                general_utils.num_to_str(violation[postproc.AXES][axis_num], precision=3),
                **padding)

    pm.scrollField(OUTPUT_WINDOW_NAME, insertText=warning, edit=True)
Exemplo n.º 2
0
def _process_records_command(command, opts):
    """
    Process records command.
    :param command: Command tuple
    :opts opts: UserOptions tuple
    :return:
    """
    params = []

    # Add timestamp
    timestamp_padding = 16
    timestamp = general_utils.num_to_str(command.time_index,
                                         include_sign=True,
                                         padding=timestamp_padding)
    params.append(timestamp)

    # Add primary parameters
    padding = 14
    if command.axes is not None:
        formatted_params = [
            general_utils.num_to_str(axis, include_sign=True, padding=padding)
            for axis in command.axes
        ]
        params.extend(formatted_params)

    if command.external_axes is not None:
        external_axes = [
            axis for axis in command.external_axes if axis is not None
        ]
        formatted_params = [
            general_utils.num_to_str(axis, include_sign=True, padding=padding)
            for axis in external_axes
        ]
        params.extend(formatted_params)

    if command.digital_output is not None:
        digital_output = [
            io for io in command.digital_output if io is not None
        ]

        bitfield = 0
        for output in digital_output:
            bitfield |= output.value << int(output.identifier)

        formatted_params = "\t{}".format(bitfield)
        params.extend(formatted_params)

    template = ''.join([TEMPLATES[RECORDS] for _ in params])

    # Structure and format data, command
    formatted_record = template.format(*params)
    return formatted_record
Exemplo n.º 3
0
def _process_records_command(command, opts):
    """
    Process records command.
    :param command: Command tuple
    :opts opts: UserOptions tuple
    :return:
    """
    params = []

    # Add timestamp if user option is selected
    if opts.Include_timestamp:
        timestamp = general_utils.num_to_str(command.time_index)
        params.append(timestamp)

    # Add primary parameters
    if command.axes is not None:
        formatted_params = [
            general_utils.num_to_str(axis) for axis in command.axes
        ]
        params.extend(formatted_params)

    if command.external_axes is not None:
        external_axes = [
            axis for axis in command.external_axes if axis is not None
        ]
        formatted_params = [
            general_utils.num_to_str(axis) for axis in external_axes
        ]
        params.extend(formatted_params)

    if command.digital_output is not None:
        digital_output = [
            io for io in command.digital_output if io is not None
        ]

        formatted_params = [
            general_utils.num_to_str(io) for io in digital_output
        ]

        params.extend(formatted_params)

    # Structure and format data, command
    formatted_record = '\t'.join(param for param in params)
    return formatted_record
Exemplo n.º 4
0
def _print_axis_stats(axis_stats, limit_type):
    """
    Format and print axis statistics.
    :param axis_stats: A dict of axis statistics
    :param limit_type: Name string of the limit type
    :return:
    """
    # TODO: This function is a mess. Should definitely be cleaned up,
    # but since this is all getting graphed anyway... 
    # TODO: stop hardcoding num_axes
    num_axes = 6
    axis_template = '>>> {0:>{axis_padding}} '
    axis_padding = {'axis_padding' : 2}

    res = [None] * (num_axes + 1)

    # Header        
    res[0] = axis_template.format('A', **axis_padding)
    for axis_index in range(num_axes):
        res[axis_index + 1] = axis_template.format(axis_index + 1, **axis_padding)

    # Min
    min_max_template = '{0:>{time_padding}}{1:>{frame_padding}}{2:>{val_padding}}   |'
    min_max_padding = {'val_padding' : 13, 'time_padding' : 10, 'frame_padding' : 10}
    if axis_stats['min']:
        res[0] += min_max_template.format('Time', 'Frame', 'Min', **min_max_padding)
        for axis_index, command in enumerate(axis_stats['min']):
            res[axis_index+1] += min_max_template.format(
                general_utils.num_to_str(command['Time Index'], precision=3),
                general_utils.num_to_str(command['Frame'], precision=3),
                general_utils.num_to_str(command[postproc.AXES][axis_index], precision=3),
                **min_max_padding)

    # Max
    if axis_stats['max']:
        res[0] += min_max_template.format('Time', 'Frame', 'Max', **min_max_padding)
        for axis_index, command in enumerate(axis_stats['max']):
            res[axis_index+1] += min_max_template.format(
                general_utils.num_to_str(command['Time Index'], precision=3),
                general_utils.num_to_str(command['Frame'], precision=3),
                general_utils.num_to_str(command[postproc.AXES][axis_index], precision=3),
                **min_max_padding)

    # Avg
    avg_template = '{0:>{avg_padding}}'
    avg_padding = {'avg_padding' : 10}
    if axis_stats['avg']:
        res[0] += avg_template.format('Avg', **avg_padding)
        for axis_index, axis_avg in enumerate(axis_stats['avg']):
            res[axis_index+1] += avg_template.format(
                general_utils.num_to_str(axis_avg, precision=3), **avg_padding)

    # Formatting
    stats_str = '{} Stats:\n'.format(limit_type) + '\n'.join(res) + '\n'
    pm.scrollField(OUTPUT_WINDOW_NAME, insertText=stats_str, edit=True)
Exemplo n.º 5
0
def _check_velocity_of_axes(robot, command_dicts, framerate):
    """
    Check a list of commands for velocity errors. Construct string to return
    printable statement of all exceeded velocities for each axis; ex. range
    [0, 1, 2, 3] will be formatted '0-3'.
    :param robot: name string of the selected robot
    :param command_dicts: A list of list of robot axes
    :param framerate: Maya animation framerate (fps)
    :return:
    """
    frames = [c['Frame'] for c in command_dicts]
    axes_at_each_frame = [c[postproc.AXES] for c in command_dicts]
    velocity_limits = mimic_utils.get_velocity_limits(robot)
    max_velocities = [0 for _ in range(6)]
    max_velocities_frames = [0 for _ in range(6)]
    violations = {}
    _previous_frame = 0
    _previous_axes = []

    for i in range(len(axes_at_each_frame)):
        # Get time and axes right now
        _current_frame = frames[i]
        _current_axes = axes_at_each_frame[i]
        if i > 0:  # skip zeroth
            displacement_time = abs(_current_frame -
                                    _previous_frame) / framerate
            for j in range(len(_current_axes)):
                _previous_axis = _previous_axes[j]
                _current_axis = _current_axes[j]
                displacement = abs(_current_axis - _previous_axis)
                velocity = displacement / displacement_time
                # Record max velocities
                if velocity > max_velocities[j]:
                    max_velocities[j] = velocity
                    max_velocities_frames[j] = _current_frame
                # Check if a limit has been violated
                if velocity > velocity_limits[j]:
                    # Add axis name to violations dict
                    axis_name = 'Axis {}'.format(j + 1)
                    if axis_name not in violations:
                        violations[axis_name] = []
                    # Add time to violations dict
                    violations[axis_name].append(_current_frame)
        _previous_frame = _current_frame
        _previous_axes = _current_axes

    # TODO: This is a hack!
    print 'Max velocities:'
    template_string = '>>> {0:>{padding1}}{1:>{padding2}}{2:>{padding3}}'
    print template_string.format('A',
                                 'Velocity',
                                 'Frame',
                                 padding1=2,
                                 padding2=10,
                                 padding3=10)
    for i in range(6):
        print template_string.format(
            i + 1,
            general_utils.num_to_str(max_velocities[i], precision=3),
            general_utils.num_to_str(max_velocities_frames[i], precision=3),
            padding1=2,
            padding2=10,
            padding3=10)

    # Format a warning
    warning_params = []
    # Get axis keys in order
    axes = violations.keys()
    if axes:
        axes.sort()
        for axis_name in axes:
            # Check if the axis key has values
            times = violations[axis_name]
            time_ranges = general_utils.list_as_range_strings(times)
            time_ranges_formatted = '\n'.join('\t{}'.format(time_range)
                                              for time_range in time_ranges)
            warning_params.append(axis_name)
            warning_params.append(time_ranges_formatted)
        # Create warning
        warning = 'WARNING!\n' \
                  'Velocity limits have been violated!\n' \
                  'See the following frames:\n'
        warning_params.insert(0, warning)
        return '\n'.join(warning_params) + '\n', max_velocities
    else:
        return '', max_velocities
Exemplo n.º 6
0
def _process_motion_command(command, opts):
    """
    Process motion command.
    :param command: Command tuple
    :param opts: UserOptions tuple
    :return:
    """
    motion_data_type = None
    motion_data = []  # empty data container

    # Interpret linear motion command
    if opts.Use_linear_motion:
        motion_type = MOVE_LIN
        if command.pose is not None:
            motion_data.extend(_convert_pose(command.pose))
            if command.configuration is not None:
                if command.external_axes is not None:
                    motion_data_type = E6POS
                    external_axes = [axis if axis is not None else 0 for axis in command.external_axes]
                    motion_data.extend(external_axes)
                else:
                    motion_data_type = POS
                motion_data.extend(_convert_configuration(command.configuration))
            else:
                motion_data_type = FRAME
        else:
            raise ValueError('Invalid command')

    # Interpret nonlinear motion command
    elif opts.Use_nonlinear_motion:
        if opts.Use_continuous_motion:
            motion_type = MOVE_CPTP
        else:
            motion_type = MOVE_PTP
        if command.axes is not None:
            motion_data.extend(command.axes)
            if command.external_axes is not None:
                motion_data_type = E6AXIS
                external_axes = [axis if axis is not None else 0 for axis in command.external_axes]
                motion_data.extend(external_axes)
            else:
                motion_data_type = AXIS
        elif command.pose is not None:
            motion_data_type = FRAME
            motion_data.extend(_convert_pose(command.pose))
        else:
            raise ValueError('Invalid command')

    else:  # User never supplied a motion type
        raise ValueError('Invalid motion type')

    # Format parameters into string
    motion_data = [general_utils.num_to_str(d, include_sign=False, precision=3)
                   for d in motion_data]

    # Structure and format data, command
    formatted_motion_data = postproc.fill_template(
        motion_data,
        STRUCTURES[motion_data_type],
        TEMPLATES[motion_data_type])

    formatted_motion = postproc.fill_template(
        formatted_motion_data,
        STRUCTURES[motion_type],
        TEMPLATES[motion_type])
    return formatted_motion
Exemplo n.º 7
0
def _process_motion_command(command, opts):  # Implement in base class!
    """
    Process motion command.
    :param command: Command tuple
    :param opts: UserOptions tuple
    :return:
    """
    motion_type = None
    target_data_type = None
    target_data = []

    # Interpret linear motion command
    if opts.Use_linear_motion:
        if command.pose is not None:
            motion_type = MOVE_L
            target_data_type = ROBTARGET
            pose = _convert_pose(command.pose)
            params = [
                general_utils.num_to_str(p, include_sign=False, precision=3)
                for p in pose
            ]
            target_data.extend(params)
            if command.configuration is not None:
                configuration = _convert_configuration(command.configuration)
                params = [
                    general_utils.num_to_str(p,
                                             include_sign=False,
                                             precision=3,
                                             simplify_ints=True)
                    for p in configuration
                ]
                target_data.extend(params)
            else:
                target_data.extend(rapid_config.DEFAULT_CONF)
            if command.external_axes is not None:
                external_axes = [
                    axis if axis is not None else '9E9'
                    for axis in command.external_axes
                ]
                params = [
                    general_utils.num_to_str(p,
                                             include_sign=False,
                                             precision=3)
                    for p in external_axes
                ]
                target_data.extend(params)
            else:
                target_data.extend(rapid_config.DEFAULT_EXAX)

        else:
            raise ValueError('Invalid command')

    # Interpret nonlinear motion command
    elif opts.Use_nonlinear_motion:
        if command.axes is not None:
            motion_type = MOVE_ABS_J
            target_data_type = JOINTTARGET
            axes = command.axes
            params = [
                general_utils.num_to_str(p, include_sign=False, precision=3)
                for p in axes
            ]
            target_data.extend(params)
            if command.external_axes is not None:
                external_axes = [
                    axis if axis is not None else '9E9'
                    for axis in command.external_axes
                ]
                params = [
                    general_utils.num_to_str(p,
                                             include_sign=False,
                                             precision=3)
                    for p in external_axes
                ]
                target_data.extend(params)
            else:
                target_data.extend(rapid_config.DEFAULT_EXAX)

        elif command.pose is not None:
            motion_type = MOVE_J
            target_data_type = ROBTARGET

            pose = _convert_pose(command.pose)
            params = [
                general_utils.num_to_str(p, include_sign=False, precision=3)
                for p in pose
            ]
            target_data.extend(params)
            if command.configuration is not None:
                configuration = _convert_configuration(command.configuration)
                params = [
                    general_utils.num_to_str(p,
                                             include_sign=False,
                                             precision=3,
                                             simplify_ints=True)
                    for p in configuration
                ]
                target_data.extend(params)
            else:
                target_data.extend(rapid_config.DEFAULT_CONF)
            if command.external_axes is not None:
                external_axes = [
                    axis if axis is not None else '9E9'
                    for axis in command.external_axes
                ]
                params = [
                    general_utils.num_to_str(p,
                                             include_sign=False,
                                             precision=3)
                    for p in external_axes
                ]
                target_data.extend(params)
            else:
                target_data.extend(rapid_config.DEFAULT_EXAX)
        else:
            raise ValueError('Invalid command')

    else:  # User never supplied a motion type
        raise ValueError('Invalid motion type')

    # Structure and format data, command
    formatted_target_data = postproc.fill_template(
        target_data, STRUCTURES[target_data_type], TEMPLATES[target_data_type])

    if opts.Use_motion_as_variables:
        formatted_variable = postproc.fill_template(formatted_target_data,
                                                    STRUCTURES[VARIABLE],
                                                    TEMPLATES[VARIABLE])
        return formatted_variable
    else:
        motion_data = [
            motion_type, formatted_target_data, rapid_config.DEFAULT_SPEED,
            rapid_config.DEFAULT_ZONE, rapid_config.DEFAULT_TOOL,
            rapid_config.DEFAULT_WOBJ
        ]

        formatted_motion = postproc.fill_template(motion_data,
                                                  STRUCTURES[MOVE],
                                                  TEMPLATES[MOVE])
        return formatted_motion