Skip to content

Releases: juanmf/StepperMotors

v.0.0.20

10 Mar 15:49
Compare
Choose a tag to compare

Release Notes - Version 0.0.20 (Stable)

Overview

This release introduces several new features, enhancements, and bug fixes to improve the overall stability and functionality of the application. As well as several newly tested drivers (see doc/demo & README), and several bug fixes.

Multiprocess implemented for dedicated process driving a set of motors up to 2 child processes should be safely spawned, each driving multiple controllers, max number will depend on max PPS sent, on a RPi 4B 2 controllers can be pulsed at min period of 30uS, if no callables are provided.

New Features (from MVP v0.0.6)

  • BlockingQueueWorker:
    • Formal Job definition.
    • WorkChain (sequenced execution of Jobs). Also available in multiprocess scenario.
  • Controller:
    • signedSteps() to accept signet in number of steps. Proxy for CW vs CCW rotation (-) is CCW, (+) is CW.
    • moveTo() for absolute positioning in steps, from 0 to )SPR.
    • Stepping Event prefixes. See demo files MultiProcessPolarCoordinatesSample.
    • Support for sleep/disable mode after stepping useHoldingTorque constructor param (and inferred too from enableGpioPin & sleepGpioPin parameters).
    • Uses MultiprocessObserver to sync jobs execution to proxy BlockingQueueWorker in MainProcess. (Client code can use Driver proxies transparently and block on proxied jobs as if those were running locally.)
  • Logging:
    • tprint() function to buffer outputs in a Thread Local fashion.
    • flush_streams() function to dump logs from all threads when convenient. (Avoiding using print at critical times!)
    • more handy functions, check ThreadOrderedPrint
  • Exit handlers to kill lingering threads and processes. see atexit_handlers
  • Changed Timing to monotonic_ns
  • EventDispatcher
    • can now reguster multiple events to same handler in one register(eventName=[eName1,...,eNameN], callee) call
    • Event propagation from child process to MainProcess.
  • Multiprocess: sets of Controllers can be initiated in dedicated process. see demo MultiProcessPolarCoordinatesSample
  • StepperMotor:
    • Added Builder to GenericStepper to make it easy to configure custom stepper definitions.

New implementations

Added implementations for best seller motors and drivers. see README and demo files.

v0.0.19-Unstable

20 Feb 04:16
Compare
Choose a tag to compare
v0.0.19-Unstable Pre-release
Pre-release

Major Changes

Published package to https://test.pypi.org/project/stepper-motors-juanmf1/0.0.19/

MultiprocessObserver Leveraged to sync Jobs in multiprocess scenario. Now MainProcess jobs know when they are done. Client code can use Driver proxies transparently and block on proxied jobs as if those were running locally. #3
7ba371e#diff-b6e9e89760eb653174a673ea4af508ea223bfaa459b5af76c558729f877021f0R66-R114

Chained jobs can now be used in multiprocess scenario. #5

Synchronized navigation bug fix. #2

Improved StepperMotor API, adde builder to GenericStepper. Added dummy implementations of best seller motors, need test.

Added doc on multiprocess classes and demo.py with client code examples.

To-do list

Pendings from previous release:

  • micro-stepping modes (always used full step mode) (No changes)
  • Release next Stable release with current set of features. Add to main pypi mirror (Not yet).

Pendings from this release:

  • On Exit, zombi thread prevent returning to prompt. Annoying.
  • micro-stepping modes (always used full step mode)
  • Release next Stable release with current set of features. Add to main pypi mirror (Not yet).
  • add unit tests (no promises)
  • Evaluate migration to https://pypi.org/project/python-periphery/ (replace RPi GPIO lib)
  • JobChain not working on StaticNavigation #6

v0.0.17-Unstable

13 Feb 18:17
Compare
Choose a tag to compare
v0.0.17-Unstable Pre-release
Pre-release

Major Changes

MultiprocessObserver Simplifies synchronization between processes, enabling the user focus on actual handling of shared data. And keeping publisher connection and observer in one place.

Improved documentation, hopefully UML diagrams now better convey architecture and usage.

Bubbling up some method from BipolarStepperMotorDriver to MotorDriver (if the system grows to DC motors there might be some conflicts to look out to)

Added customization of event names on stepping related events, at Driver constriction and step job initiation times.

Improved tprint() logs dumping to avoid rare race conditions.

To-do list

Pendings from previous release:

  • micro-stepping modes (always used full step mode) (No changes)
  • EventDispatcher cross-proccess event propagation from child to parent. Needs testing, probably a few tweaks.
  • Check that update position on child process' Controller is visible on Parent Process' Proxy Controller:

Pendings from previous release:

  • Release next Stable release with current set of features. Add to main pypi mirror (currently in test).
  • micro-stepping modes (always used full step mode)
  • add unit tests (no promises)
  • Evaluate migration to https://pypi.org/project/python-periphery/ (replace RPi GPIO lib)

v0.0.15-Unstable

09 Feb 22:06
Compare
Choose a tag to compare
v0.0.15-Unstable Pre-release
Pre-release

Multiprocessing fixes for values sync from child to parent process

This release fixes EventDispatcher level Event propagation from child (motor drivers) to parent (your app) process.

Pendings from release v0.0.13:

  • micro-stepping modes (always used full step mode) (no change)
  • EventDispatcher cross-proccess event propagation from child to parent. Needs testing, probably a few tweaks.
  • Check that update position on child process' Controller is visible on Parent Process' Proxy Controller:

Pendings from this release:

  • micro-stepping modes (always used full step mode)
  • No known major bug. Todo List:
## Todo List

- **EventDispatcher.py**
  - Should I add eventId to callee parameters?

- **Navigation.py**
  - Find out if -1 works as LOW (normally set to 0) for direction pin.
  - GPIO.LOW is not controller specific. Fix with `controller.setDirection(controller.defaultDirection)` or similar.
  - This will be called from multiple threads, one per driver. Handle synchronization accordingly. Waits to get all Synchronized controllers to go then coordinates their steps so that all sleep and step at once.

- **Benchmark.py**
  - 'u': lambda: self.undoSpeedBoost(controller, speedBoosts)
  - Test after library extraction.

- **Controller.py**
  - Migrate to [python-periphery](https://pypi.org/project/python-periphery/).
  - If `libc.usleep` works, use active wait under 300uS.
  - `libc.usleep` fails on my RPI. See `self.usleep()`.
  - Check that "-s" still applies. Think it was important for `PWM()`, not used now.
  - Client knows targetPosition, would only need currentPosition and realDirection, but not every step. Update sharedMemory.

- **StepperMotor.py**
  - Assess removal. (Remove `self.settingsLock = threading.Lock()`.)
  - Remove this one.

- **BlockingQueueWorker.py**
  - Sync completion. (Return job. Never complete. The child process might end, we don't have visibility. We could use this thread.)

- **AccelerationStrategy.py**
  - Find midpoint when steps < 2 * rampSteps.
  - PendingSteps == 0 and PPS == minPPS we should be able to stop without rampDown.

v0.0.13-Unstable

08 Feb 23:03
Compare
Choose a tag to compare
v0.0.13-Unstable Pre-release
Pre-release

Full Changelog: v0.0.11-Unstable...v0.0.13-Unstable

Huge changes to support real parallelism. Drivers can now run on their own dedicated process, with minimal overhead, while preserving object oriented design, Driver threads remain blocked while Synchronized navigation operates GPIO pulses in a coordinated fashion, transparently, being the only active thread it does not get disturbed by client application and avoid Drivers interfering with each other.

Minor improvements to tprint

Pendings from release v0.0.11:

  • micro-stepping modes (always used full step mode) (No change)
  • How well threads are scheduled with multiple motors running.
    • This release adds 2 complementary features:
      • BasicSynchronizedNavigation
      • multiprocess (not multiprocessing) (see README); makes the frequency much more stable as you add motors to your RPi.

Pendings from this release:

  • micro-stepping modes (always used full step mode)
  • EventDispatcher cross-proccess event propagation from child to parent. Needs testing, probably a few tweaks.
  • Check that update position on child process' Controller is visible on Parent Process' Proxy Controller:
    def setCurrentPosition(self, position):
        self.currentPosition = position
        if self.sharedPosition is not None:
            with self.sharedLock:
                self.sharedPosition.value.position = position
                self.sharedPosition.value.direction = self.currentDirection

v0.0.11-Unstable

02 Feb 22:29
Compare
Choose a tag to compare
v0.0.11-Unstable Pre-release
Pre-release

Full Changelog: v0.0.9-Unstable...v0.0.11-Unstable

This release adds:

  • Change time usages to time.monotonic_ns()
  • Fixes sleep mode logic, tested on HRB8825 Stepper Motor HAT Board for Raspberry Pi Series . Current stable release is only tested with holding torque (never sleeps)
  • Event Dispatcher can now reguster multiple events to same handler in one register(eventName=[eName1,...,eNameN], callee) call.

Main areas still pending test:

  • micro-stepping modes (always used full step mode)
  • How well threads are scheduled with multiple motors running.
    ** tested this one, it sucks. GIL makes thread management horribly, steps frequency splits in half. Will fix it.

v0.0.9-Unstable

18 Jan 21:36
Compare
Choose a tag to compare
v0.0.9-Unstable Pre-release
Pre-release

Full Changelog: v0.0.6-MVP...v0.0.9-Unstable

This release adds:

  • Improvements to BlockingQueueWorker. Better encapsulation of Queue, WorkChain (to sequence jobs in a dynamic navigation scenario, where stacking jobs would interrupt ongoing jobs.)
"""
creates a double-linked list of jobs, starts the 1st when the pipe is set. BlockingQueueWorker's 
consumer will add the chain links to the jobQueue in order as it finishes jobs.
"""
class SomeWorkerClass(BlockingQueueWorker):
...
  def doSomeChainedWork(self):
    self.workChain([your handler fn param list], block=False)
      .then([your handler fn next param list])
      .startChain())

and job concept (to prevent erratic additions to __jobQueue and adds Futures to track job times.)

  • Adds EventDispatched, an implementation of mediator pattern. That enables your app to decouple from events happening at the Motor Driver level. You still need to pass in a callable but that callable can fire events that will be handled by your app. En ecense you add extension points using events to hook your app to, instead of adding the logic directly inside the passed callable. EventDispatcher itself is a BlockingQueueWorker so it has it's own thread to dispatch published events to registered handlers.
  • Simplified client code by adding signedSteps() method to Drivers, so that the driver itself can decide if it's clockwise or counter clockwise (negative steps number is counter clockwise steps).
  • Improved README and docstrings, still more updates missing to catch up with new features.
  • Huge win (90-100x) in performance and sorting of log messages (from print()). multiple thread printing caused a mess in STDOUT, tprint() proxies (not literally) print and stores messages in a map. flush_streams() dumps logs to STDOUT cleaning the in-memory map, each thread's output will be in it's own chunk of output, prefixed by timestamp in microseconds (running RPI must get 10x faster than RPI 4B to start causing timestamp collisions, i.e. two immediate logs are apart by ~10uS).
  • added at exit handlers to ensure tprint dumps the map to STDOUT when your app ends or crashes. Usage: import stepper_motors_juanmf1.atexit_handlers.

This is ready for anyone to test, and could be just the same as next stable, but I didn't have the time to thoroughly test it. As my focus was to add need features from a client perspective and have it work for me.

Main areas still pending test:

  • micro-stepping modes (always used full step mode)
  • How well threads are scheduled with multiple motors running.

v0.0.6-MVP

09 Jan 01:21
831d6bc
Compare
Choose a tag to compare

Fixed all package issues enabling the library to be pip installed and imported into your projects.
Static & Dynamic implementations for following Acceleration strategies & driver combinations implemented, for GenericMotor and PG35S_D48_HHC2(retail&datasheet) motors:

    def getFlatDRV8825With(self, stepperMotor, directionPin, stepPin):

    def getLinearDRV8825With(self, stepperMotor, directionPin, stepPin):

    def getExponentialDRV8825With(self, stepperMotor, directionPin, stepPin):

    def getCustomTorqueCharacteristicsDRV8825With(self, stepperMotor, directionPin, stepPin, transformations=None):

    # Benchmark specific.
    def getInteractiveDRV8825With(self, stepperMotor, directionPin, stepPin, minSpeedDelta, minPps):

Also robust Benchmark module to stress test motors and extract suitable torque characteristics for runtime operation is provided. See README for details.

pip package (currently on test pypi servers):
https://test.pypi.org/project/stepper-motors-juanmf1/#files
Install this release manually:
Download Wheel here

# cd to where you downloaded it 
$ pip install --upgrade stepper_motors_juanmf1-0.0.6-py3-none-any.whl

Install form Index pip install -i https://test.pypi.org/simple/ stepper-motors-juanmf1==0.0.6