Source code for actuation_tutorial.servo_sequence_demo

#!/usr/bin/env python3

# Enable basic compatibility features to work with either Python 2 or 3.
from __future__ import print_function, absolute_import, unicode_literals

# Standard library modules.
import os, sys, time, argparse

# This requires a pySerial installation.
from serial.serialutil import SerialException

# Configure load path to include the parent folder so the course library can be found in a parallel folder.
sys.path.insert(0, os.path.dirname(os.path.abspath(os.path.dirname(__file__))))

# Import modules from the course library.
import ase.logging
import ase.events
import ase.SerialTransport
import ase.MiniMaestroProtocol

#================================================================
[docs]def animation_sequence(servos, numservos, step, logger): """Produce an animation motion sequence on a set of servos by issuing motion commands to the servo interface and performing delays using ase.events.sleep(). This is a good starting point for customizing the script. :param servos: handle to the Mini Maestro transport object :param numservos: number of servos to assume are connected :param step: flag to indicate frame-by-frame stepping :param logger: logging object for debugging and status output """ # Define a convenience function to separate each frame. def sleep_or_wait(duration): if step: print("Press Enter to continue...") ase.events.wait_for_keyboard_input([servos]) else: ase.events.sleep(duration, [servos]) # Extract the MiniMaestroProtocol object from the transport for convenience. protocol = servos.protocol # Endless loop to run the sequence in a loop. while True: # Send motion commands to the given number of channels. # The list notation '[2.0]*numservos' duplicates the 2.0 to make a list # of position values the right length (one per channel). protocol.send_multiple_speeds(0, [2.0]*numservos) protocol.send_multiple_accelerations(0, [5.0]*numservos) protocol.send_multiple_targets(0, [1.0]*numservos) # Sleep for one second while processing data replies from the interface. sleep_or_wait(1.0) # Send position commands to individual servos. for i in range(numservos): protocol.send_target(i, 1.5) sleep_or_wait(0.2) # Move all back to start. protocol.send_multiple_targets(0, [1.0]*numservos) sleep_or_wait(1.0) # Set unlimited speed and acceleration and move to the far position. protocol.send_multiple_speeds(0, [0.0]*numservos) protocol.send_multiple_accelerations(0, [0.0]*numservos) protocol.send_multiple_targets(0, [2.0]*numservos) sleep_or_wait(1.0)
#================================================================
[docs]def main(argv): """Main program entry point. :param argv: list of command line arguments as individual strings """ # Initialize the command parser. parser = argparse.ArgumentParser( description = """Test animation using a Mini Maestro servo interface board.""") ase.logging.add_logging_arguments(parser) parser.add_argument('--list', action='store_true', help='Print list of available serial ports.') parser.add_argument('--step', action='store_true', help='Step frame by frame through sequence.') parser.add_argument('--servos', type=int, default=6, help='Specify the number of servo channels. Default: 6.') default_serial_port = '/dev/tty.usbmodem00146911' parser.add_argument( '--maestro', default=default_serial_port, help='Specify the name of the Mini Maestro Command Port device. Default: %s.' % default_serial_port) args = parser.parse_args(argv) # Configure a typical logging setup. logger, handlers = ase.logging.create_script_logger('animation', args) # Print the list of serial ports to console if requested. if args.list: ase.SerialTransport.print_serial_port_list() # Create an object to manage the serial port. servos = ase.SerialTransport.SerialTransport(ase.MiniMaestroProtocol.MiniMaestroProtocol(), args.maestro, 115200) # Connect to the board. logger.info("Connecting to Mini Maestro on %s.", args.maestro) try: servos.open() except SerialException as exp: logger.error("Unable to open port: %r", exp) logger.info("You might try the --list argument to see the available serial ports.\nExiting.") sys.exit(1); # Now run the event loop until it exits or control-C is pressed. try: animation_sequence(servos, args.servos, args.step, logger) except KeyboardInterrupt: logger.info("User interrupted operation.") # Shut down the connection. servos.close()
#================================================================ # The following section is run when this is loaded as a script. if __name__ == "__main__": # Call the main function with most of the command line arguments. # This could be customized by pre-defining particular arguments: constant_args = [] # constant_args = ['--maestro', '/dev/tty.usbmodem00146911'] main(constant_args + sys.argv[1:])