Motor

class bapsf_motion.actors.motor_.Motor(*, ip: str, limit_mode: int = None, current: float | int = 0.8, speed: float | int = 4.0, name: str = None, logger: Logger = None, loop: AbstractEventLoop = None, auto_run: bool = False, parent: EventActor | None = None)

Bases: EventActor

An actor class for directly communicating to an ethernet based stepper motor. This actor is only aware of the motor, and is ignorant of how it is situated within a probe drive. Thus, all units are in motor units, i.e. steps, counts, rev, and sec.

Parameters:
  • ip (str) – IPv4 address for the motor

  • limit_mode (int, optional) – Define the operational mode of the motor limit switches. Value should be an integer of value 1, 2, or 3. 1 indicates limit is activated when energized, 2 indicates limit is activated when de-energized, and 3 indicates no limits. (DEFAULT: 1)

  • current (float, optional) – A value between 0 (non-inclusive) and 1 (inclusive) which indicates what the motor current should be set to as a fraction of the max allowed current motor["DEFAULTS"]["max_current"]. (DEFAULT: 0.8)

  • name (str, optional) – Name the motor. If None, then the name will be automatically generated. (DEFAULT: None)

  • logger (Logger, optional) – An instance of Logger that the Actor will record events and status updates to. If None, then a logger will automatically be generated. (DEFAULT: None)

  • loop (asyncio.AbstractEventLoop, optional) – Instance of an asyncio event loop. Communication with the motor will happen primaritly through the evenet loop. If None, then an event loop will be auto-generated. (DEFAULT: None)

  • auto_run (bool, optional) – If True, then the event loop will be placed in a separate thread and started. This is all done via the run() method. (DEFAULT: False)

Examples

Using Motor with auto_start=True.

>>> import logging
>>> logging.basicConfig(level=logging.NOTSET)
>>> lgr = logging.getLogger()
>>> m1 = Motor(
...     ip="192.168.0.70",
...     name="m1",
...     logger=lgr,
...     auto_run=True,
... )
>>> # now stop the actor, which stops the event loop
>>> m1.terminate()

Using Motor with auto_start=False.

>>> import logging
>>> logging.basicConfig(level=logging.NOTSET)
>>> lgr = logging.getLogger()
>>> m1 = Motor(
...     ip="192.168.0.70",
...     name="m1",
...     logger=lgr,
... )
>>> # start the actor, with starts the event loop
>>> m1.run()
>>> # now stop the actor, which stops the event loop
>>> m1.terminate()

Attributes Summary

config

Configuration dictionary of the actor.

connected

True if the TCP connection is established with the physical motor.

counts_per_rev

The number of encoder counts per motor revolution.

encoder

Current encoder positional reading for the motor, in encoder units counts.

heartbeat_task

The asyncio.Task associated with the motor's heartbeat.

heartrate

Heartrate of the motor monitor, or the time (in sec) between motor checks.

ip

IPv4 address for the motor

is_moving

True if the motor is actively moving, False otherwise.

local_address

logger

The Logger instance being used for the actor.

loop

The asyncio event loop for the actor.

motor

Dictionary containing properties of the Applied Motion STM motor.

name

(str) A unique name given for the instance of the actor.

parent

port

Port used for motor communication.

position

Current position of the motor, in motor units steps.

setup

Dictionary of class setup parameters.

signals

Collection of all the signals emitted by the Motor class.

socket

Instance of the socket used for motor communication.

status

Current status of the motor.

steps_per_rev

The number of steps the motor does per revolution.

tasks

List of asyncio.Tasks this actor has in its event loop.

terminated

Indicates if the actor has been terminated.

thread

The Thread the event loop is running in.

Methods Summary

connect()

Open the ethernet connection to the motor.

continuous_jog([direction])

Start a continuous jog.

disable()

Disable motor (i.e. reduce motor current to zero).

enable()

Enable motor (i.e. restore drive current to motor).

encoder_correct_position()

Set the motor absolute position 'SP' to be consistent with the current encoder reading.

move_off_limit()

Move the motor off of a CW (forward) or CCW (backward) limit switch.

move_to(pos)

Move the motor to a specified location.

reset_currents()

Reset running and idle currents to their default values.

retrieve_motor_alarm([defer_status_update,Β ...])

Retrieve [if any] motor alarm codes.

retrieve_motor_status([direct_send])

Retrieve motor status and update self._status.

run([auto_run])

Activate the asyncio event loop.

send_command(command,Β *args[,Β thread_id])

Send command to the motor, and receive its response.

set_current(percent[,Β skip_setting])

Set the peak current setting ("peak of sine") of the stepper drive, also known as the running current.

set_idle_current(percent)

Set the motor's idle current.

set_limit_mode(limit_mode[,Β skip_setting])

set_position(pos)

Set current motor's absolute and encoder position.

set_speeds(speed[,Β skip_setting])

setup_event_loop([loop])

Set up the asyncio event loop.

sleep(delay)

Sleep for X seconds defined by delay.

start_heartbeat()

Start or restart the heartbeat asyncio.Task.

stop([soft])

Stop motor movement.

terminate([delay_loop_stop])

Stop the actor's event loop.

zero()

Define current motor position as zero.

Attributes Documentation

config

Configuration dictionary of the actor.

Warning

This dictionary should never be written to from outside the owning actor.

connected

True if the TCP connection is established with the physical motor.

counts_per_rev

The number of encoder counts per motor revolution.

encoder

Current encoder positional reading for the motor, in encoder units counts.

heartbeat_task

The asyncio.Task associated with the motor’s heartbeat.

heartrate

Heartrate of the motor monitor, or the time (in sec) between motor checks. There are two different heartrates: (1) heartrate.base for when the motor is not moving, and (2) heartrate.active for when the motor is moving.

ip

IPv4 address for the motor

is_moving

True if the motor is actively moving, False otherwise.

local_address
logger

The Logger instance being used for the actor.

loop

The asyncio event loop for the actor.

motor

Dictionary containing properties of the Applied Motion STM motor.

name

(str) A unique name given for the instance of the actor. This name is used as an identifier in the actor logger (see logger).

If the user does not specify a name, then the Actor should auto-generate a name.

parent
port

Port used for motor communication.

position

Current position of the motor, in motor units steps.

setup

Dictionary of class setup parameters.

signals

Collection of all the signals emitted by the Motor class.

See MotorSignals for additional documentation on the individual signals.

socket

Instance of the socket used for motor communication.

status

Current status of the motor.

steps_per_rev

The number of steps the motor does per revolution.

tasks

List of asyncio.Tasks this actor has in its event loop.

terminated

Indicates if the actor has been terminated.

thread

The Thread the event loop is running in.

If loop was given during instantiation, then there is no way of obtaining the thread object the event loop is running in. In this case thread will be None.

The thread id can always be retrieved using _thread_id.

Methods Documentation

connect()

Open the ethernet connection to the motor. The number of reconnection attempts before an exception is raised is defined by self._setup["max_connection_attempts"].

continuous_jog(direction='forward')

Start a continuous jog. The motor will not stop until commanded to.

disable()

Disable motor (i.e. reduce motor current to zero).

enable()

Enable motor (i.e. restore drive current to motor).

encoder_correct_position()

Set the motor absolute position β€˜SP’ to be consistent with the current encoder reading.

move_off_limit()

Move the motor off of a CW (forward) or CCW (backward) limit switch.

move_to(pos: int)

Move the motor to a specified location.

Parameters:

pos (int) – Position (in steps) for the motor to move to.

reset_currents()

Reset running and idle currents to their default values.

retrieve_motor_alarm(defer_status_update: bool = False, direct_send: bool = False) Dict[str, Any] | AckFlags

Retrieve [if any] motor alarm codes.

Parameters:
  • defer_status_update (bool) – If True, then do NOT update self._status. (DEFAULT: False)

  • direct_send (bool) – If True, then the motor commands will bypass any active event loop and be directly sent to the motor. If False, then all motor commands will be routed through the send_command() method. (DEFAULT: False)

Returns:

Alarm status.

Return type:

Dict[str, Any]

retrieve_motor_status(direct_send=False)

Retrieve motor status and update self._status.

Parameters:

direct_send (bool) – If True, then the motor commands will bypass any active event loop and be directly sent to the motor. If False, then all motor commands will be routed through the send_command() method. (DEFAULT: False)

run(auto_run=True)

Activate the asyncio event loop. If the event loop is running, then nothing happens. Otherwise, the event loop is placed in a separate thread and set to run_forever.

Parameters:

auto_run (bool, optional) – If False, then do NOT start the event loop. This keyword is only made available to help with subclassing. (DEFAULT: True)

send_command(command: str, *args, thread_id=None)

Send command to the motor, and receive its response. If the event loop is running, then the command will be sent as a threadsafe coroutine in the loop. Otherwise, the command will be sent directly to the motor.

Parameters:
  • command (str) – The desired command to be sent to the motor.

  • *args – Any arguments to the command that will be sent with the motor command.

  • thread_id (int) – ID of the thread the calling functionality is operating in.

set_current(percent: float | int, skip_setting: bool = False) float | None

Set the peak current setting (β€œpeak of sine”) of the stepper drive, also known as the running current. The value given is a fraction of 0-1 of the peak allowable current defined in _motor["DEFAULTS"]["max_current"].

Setting the running current can affect the idle current, since the max idle current is 90% of the running current.

Parameters:
  • percent (float) – A value of 0 - 1 specifying a fraction of the max running current to set the running current to. For example, 0.5 will set the running current to 50% of the max allowable running current (_motor["DEFAULTS"]["max_current"]).

  • skip_setting (bool) – (DEFAULT: False) If True, then do NOT set the currents. Just to the value validation.

Returns:

The set fractional current percent, or None if input percent could not be set.

Return type:

float | None

set_idle_current(percent)

Set the motor’s idle current. The idle current is the current supplied to the stepper motors when the motor is not moving. The value given is a fraction 0 - 0.9 of the running current.

Parameters:

percent (float) – A value of 0 - 0.9 specifying a fraction of the running current to set the idle current to. For example, 0.5 will set the idle current to 50% of the running current.

set_limit_mode(limit_mode: int, skip_setting: bool = False)
set_position(pos)

Set current motor’s absolute and encoder position. pos is the desired absolute position, and the encoder position will be calculated from pos.

Parameters:

pos (int) – An integer in the range of +/- 2,147,483,647 to set the motor’s absolute position.

set_speeds(speed: float | int, skip_setting: bool = False)
setup_event_loop(loop: AbstractEventLoop | None = None)

Set up the asyncio event loop. If the given loop is not an instance of AbstractEventLoop, then a new loop will be created.

Parameters:

loop (asyncio.AbstractEventLoop) – asyncio event loop for the actor’s tasks

sleep(delay)

Sleep for X seconds defined by delay. The routine is smart enough to know if the event loop is running or not. If the event loop is not running the sleep will be issued via time.sleep, otherwise it will leverage asyncio.sleep.

Parameters:

delay (Real) – Number of seconds to sleep.

start_heartbeat()

Start or restart the heartbeat asyncio.Task.

stop(soft=False)

Stop motor movement.

terminate(delay_loop_stop=False)

Stop the actor’s event loop. All actor tasks will be cancelled, the connection to the motor will be shutdown, and the event loop will be stopped.

Parameters:

delay_loop_stop (bool) – If True, then do NOT stop the event loop. In this case it is assumed the calling functionality is managing additional tasks in the event loop, and it is up to that functionality to stop the loop. (DEFAULT: False)

zero()

Define current motor position as zero.