Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix examples #375

Merged
merged 3 commits into from
Dec 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ docs/_build/
*.log
*.state.json
Tinymovr.code-workspace
.aider*
.env
20 changes: 10 additions & 10 deletions docs/features/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Before using the planner, the desired acceleration, deceleration and max velocit
tm1.traj_planner.max_decel = {max_deceleration} # ticks/sec^2
tm1.traj_planner.max_vel = {mac_velocity} # ticks/sec

Once you set the desired acceleration and deceleration parameters, they do not need to be re-set. The parameters can be saved in NVRAM using ``tmx.save_config()``.
Once you set the desired acceleration and deceleration parameters, they do not need to be re-set. The parameters can be saved in NVRAM using ``tm1.save_config()``.

Once the parameters are set, you can execute a plan to a target position:

Expand Down Expand Up @@ -95,14 +95,14 @@ Because the homing planner relies on mechanical resistance of the structure, it

There are six parameters in total that control the homing behavior:

* ``tmx.homing.velocity``: The velocity at which the motor performs homing
* ``tmx.homing.max_homing_t``: The maximum time the motor is allowed to travel before aborting homing
* ``tmx.homing.retract_dist``: The retraction distance the motor travels after the endstop has been found
* ``tmx.homing.stall_detect.velocity``: The velocity below which (and together with ``stall_detect.delta_pos``) stall detection mode is triggered
* ``tmx.homing.stall_detect.delta_pos``: The position error above which (and together with ``stall_detect.velocity``) stall detection mode is triggered
* ``tmx.homing.stall_detect.t``: The time to remain in stall detection mode before the motor is considered stalled
* ``tm1.homing.velocity``: The velocity at which the motor performs homing
* ``tm1.homing.max_homing_t``: The maximum time the motor is allowed to travel before aborting homing
* ``tm1.homing.retract_dist``: The retraction distance the motor travels after the endstop has been found
* ``tm1.homing.stall_detect.velocity``: The velocity below which (and together with ``stall_detect.delta_pos``) stall detection mode is triggered
* ``tm1.homing.stall_detect.delta_pos``: The position error above which (and together with ``stall_detect.velocity``) stall detection mode is triggered
* ``tm1.homing.stall_detect.t``: The time to remain in stall detection mode before the motor is considered stalled

In addition to the above, the phase current while the motor is stopped, until ``stall_detect.t`` time passes is the maximum allowed phase current, as defined in ``tmx.controller.current.Iq_limit``. It is advisable to set this value so that mechanical damage or fatigue is avoided.
In addition to the above, the phase current while the motor is stopped, until ``stall_detect.t`` time passes is the maximum allowed phase current, as defined in ``tm1.controller.current.Iq_limit``. It is advisable to set this value so that mechanical damage or fatigue is avoided.

Operation
*********
Expand All @@ -125,7 +125,7 @@ FOC decouples the torque-producing and magnetizing currents by aligning the stat

Two parameters control flux braking:

1. ``tmx.controller.current.max_Ibus_regen``: The maximum current (in amperes) allowed to be fed back to the power source before flux braking activates. By adjusting this value, you can control the regenerative braking threshold and determine when flux braking should take effect.
1. ``tm1.controller.current.max_Ibus_regen``: The maximum current (in amperes) allowed to be fed back to the power source before flux braking activates. By adjusting this value, you can control the regenerative braking threshold and determine when flux braking should take effect.

2. ``tmx.controller.current.max_Ibrake``: The maximum current (in amperes) allowed to be dumped to the motor windings during flux braking. By setting this value to zero, you can deactivate flux braking. Adjusting this parameter allows you to manage the braking torque and the heat generated during the braking process.
2. ``tm1.controller.current.max_Ibrake``: The maximum current (in amperes) allowed to be dumped to the motor windings during flux braking. By setting this value to zero, you can deactivate flux braking. Adjusting this parameter allows you to manage the braking torque and the heat generated during the braking process.

4 changes: 2 additions & 2 deletions docs/hardware/gimbal.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Example
>>>tm1.motor.L = 2e-3
>>>tm1.motor.I_cal = 0.5

>>>tmx.set_motor_RL(5, 0.002)
>>>tm1.set_motor_RL(5, 0.002)

This specifies a motor with 5 Ohms resistance, 2 Millihenries inductance and 0.5Amps calibration current.
Alternatuvely, using the units interface:
Expand Down Expand Up @@ -99,7 +99,7 @@ Ensure the values above are correct. You can now calibrate the motor:

>>>tm1.controller.calibrate()

Because the motor is set as gimbal, calibration will bypass resistance and inductance measurement, and will only calculate pole pairs, offset and direction. After calibration `tmx.motor.calibrated` should have a value of True:
Because the motor is set as gimbal, calibration will bypass resistance and inductance measurement, and will only calculate pole pairs, offset and direction. After calibration `tm1.motor.calibrated` should have a value of True:

|gui| Calibrate Motor

Expand Down
4 changes: 4 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ Welcome to Tinymovr documentation!
.. note::
This is the documentation for the latest stable version of the Tinymovr Firmware and Studio app. For the legacy 0.x.x documentation, check out the [legacy docs](https://tinymovr.readthedocs.io/en/attic-legacy/).

.. note::
In all examples, the first intance of the found motor controller is used, namely `tm1`. If working with subsequent instances, please replace with the correct index, e.g. instead of `tm1` use `tm2`, `tm3` etc.


.. toctree::
:maxdepth: 2
:caption: Contents:
Expand Down
8 changes: 4 additions & 4 deletions docs/quickstart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,14 @@ The Tinymovr Studio GUI offers an overview of the device internals as a tree str

The Tinymovr Servo Kit motor and encoder are already calibrated. If you have your own setup, or if you experience problems with prior calibration, you'll need to go through the following brief calibration procedure.

In Tinymovr Studio, navigate to `tmx->controller`. Press the button with the arrow next to the `calibrate` label. Note that after pressing this button, the motor will spin. Ensure the rotor is free of obstructions or loads, and the motor is firmly fixed.
In Tinymovr Studio, navigate to `tm1->controller`. Press the button with the arrow next to the `calibrate` label. Note that after pressing this button, the motor will spin. Ensure the rotor is free of obstructions or loads, and the motor is firmly fixed.

Follow the on-screen prompts. The motor will produce an audible beep and rotate in one direction.
Your Tinymovr is now ready for operation. Navigate to `tmx->motor`. This will reveal identified motor parameters, namely: phase resistance (R), phase inductance (L) and number of pole pairs.
Your Tinymovr is now ready for operation. Navigate to `tm1->motor`. This will reveal identified motor parameters, namely: phase resistance (R), phase inductance (L) and number of pole pairs.

Testing Position Control using the Studio GUI
#############################################

Navigate back to `tmx->controller`. Press the button with the arrow next to the `position_mode` label. Note that after pressing the button, the motor will hold position and may spin. The motor should now be actively holding it's position. Try moving it by hand and you should feel resistance.
Navigate back to `tm1->controller`. Press the button with the arrow next to the `position_mode` label. Note that after pressing the button, the motor will hold position and may spin. The motor should now be actively holding it's position. Try moving it by hand and you should feel resistance.

To command a new position, navigate to `tmx->controller->position`, and double-click on the value next to the `setpoint` label. This value is expressed in ticks, a unit that denotes 1/8192 of the circle. Type in a new position followed by Enter. The motor should jump to the commanded position.
To command a new position, navigate to `tm1->controller->position`, and double-click on the value next to the `setpoint` label. This value is expressed in ticks, a unit that denotes 1/8192 of the circle. Type in a new position followed by Enter. The motor should jump to the commanded position.
60 changes: 30 additions & 30 deletions docs/sensors/sensors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ Tinymovr makes use of the XF1 library, which has been developed for this purpose
Sensor Configuration
********************

The sensor configuration consists of two steps. The first step concerns the setup of the individual sensors being used, and the second step concerns sensor selection. The corresponding sections in the device spec are `tmx.sensors.setup`, and `tmx.sensors.select`.
The sensor configuration consists of two steps. The first step concerns the setup of the individual sensors being used, and the second step concerns sensor selection. The corresponding sections in the device spec are `tm1.sensors.setup`, and `tm1.sensors.select`.

Sensor Setup
============
Expand Down Expand Up @@ -220,36 +220,36 @@ Then, configure the external sensor type as follows:

.. code-block:: python

tmx.sensors.setup.external_spi.type = tmx.sensors.setup.external_spi.type.AS5047
tm1.sensors.setup.external_spi.type = tm1.sensors.setup.external_spi.type.AS5047

Then select the `EXTERNAL_SPI` sensor for each of the position and commutation sensors:

.. code-block:: python

tmx.sensors.select.commutation_sensor.connection = tmx.sensors.select.commutation_sensor.connection.EXTERNAL_SPI
tmx.sensors.select.position_sensor.connection = tmx.sensors.select.position_sensor.connection.EXTERNAL_SPI
tm1.sensors.select.commutation_sensor.connection = tm1.sensors.select.commutation_sensor.connection.EXTERNAL_SPI
tm1.sensors.select.position_sensor.connection = tm1.sensors.select.position_sensor.connection.EXTERNAL_SPI

At this point, you are ready to perform motor/sensor calibration. This will measure the R and L values of the motor, derive frame transforms and eccentricity compensation tables.

.. code-block:: python

tmx.controller.calibrate()
tm1.controller.calibrate()

After calibration finishes, you should be able to control the motor:

.. code-block:: python

tmx.controller.velocity_mode()
tmx.controller.velocity.setpoint = 8192 # 60 rpm
tm1.controller.velocity_mode()
tm1.controller.velocity.setpoint = 8192 # 60 rpm

The motor should now move at a constant velocity.

Once you have determined that the motor behaves as expected, set to idle and perform another config save to persist the configuration:

.. code-block:: python

tmx.controller.idle()
tmx.save_config()
tm1.controller.idle()
tm1.save_config()


External AMT22 Sensor for Positioning and Onboard MA702/704 for Commutation
Expand All @@ -264,36 +264,36 @@ Then, configure the external sensor type as follows:

.. code-block:: python

tmx.sensors.setup.external_spi.type = tmx.sensors.setup.external_spi.type.AMT22
tm1.sensors.setup.external_spi.type = tm1.sensors.setup.external_spi.type.AMT22

Then select the `EXTERNAL_SPI` sensor for each of the position and commutation sensors:

.. code-block:: python

tmx.sensors.select.commutation_sensor.connection = tmx.sensors.select.commutation_sensor.connection.ONBOARD
tmx.sensors.select.position_sensor.connection = tmx.sensors.select.position_sensor.connection.EXTERNAL_SPI
tm1.sensors.select.commutation_sensor.connection = tm1.sensors.select.commutation_sensor.connection.ONBOARD
tm1.sensors.select.position_sensor.connection = tm1.sensors.select.position_sensor.connection.EXTERNAL_SPI

At this point, you are ready to perform motor/sensor calibration. This will measure the R and L values of the motor, derive frame transforms and eccentricity compensation tables.

.. code-block:: python

tmx.controller.calibrate()
tm1.controller.calibrate()

After calibration finishes, you should be able to control the motor:

.. code-block:: python

tmx.controller.velocity_mode()
tmx.controller.velocity.setpoint = 8192 # 60 rpm
tm1.controller.velocity_mode()
tm1.controller.velocity.setpoint = 8192 # 60 rpm

The motor should now move at a constant velocity.

Once you have determined that the motor behaves as expected, set to idle and perform another config save to persist the configuration:

.. code-block:: python

tmx.controller.idle()
tmx.save_config()
tm1.controller.idle()
tm1.save_config()


Hall Effect Sensor
Expand All @@ -308,18 +308,18 @@ Then select the `HALL` sensor for each of the position and commutation sensors,

.. code-block:: python

tmx.sensors.select.commutation_sensor.connection = HALL
tmx.sensors.select.position_sensor.connection = HALL
tmx.sensors.select.commutation_sensor.bandwidth = 200
tmx.sensors.select.position_sensor.bandwidth = 20
tm1.sensors.select.commutation_sensor.connection = HALL
tm1.sensors.select.position_sensor.connection = HALL
tm1.sensors.select.commutation_sensor.bandwidth = 200
tm1.sensors.select.position_sensor.bandwidth = 20

This sets the type to Hall effect sensor, and each of the commutation and position observer bandwidths. The commutation observer is set to a higher bandwidth value, in order to ensure that commutation is accurate and a runoff scenario is avoided.

Next, you need to set the motor pole pairs:

.. code-block:: python

tmx.motor.pole_pairs = 15
tm1.motor.pole_pairs = 15

Next comes tuning of gains. Gains are determined on the tick count of a full mechanical turn of the motor. When using the an absolute sensor, the tick count is fixed to 8192 ticks (the resolution can be higher as the tick count is a floating point value).

Expand All @@ -328,38 +328,38 @@ Because of this it is possible that the gains need to be updated. Below we prese

.. code-block:: python

tmx.controller.position.p_gain = 5
tmx.controller.velocity.p_gain = 0.00001
tm1.controller.position.p_gain = 5
tm1.controller.velocity.p_gain = 0.00001

For your own motor, you need to determine these experimentally. Take a look at :ref:`Tuning` for more information.

At this point, you are ready to perform motor/sensor calibration. This will measure the R and L values of the motor, as well as the hall effect sensor sequence.

.. code-block:: python

tmx.controller.calibrate()
tm1.controller.calibrate()

After calibration finishes, you should be able to control the motor. Note that the default reference frame for the hall sensors maps to 8192 ticks per motor electrical cycle. You can change this by modifying the user frame multiplier:

.. code-block:: python

tmx.sensors.user_frame.multiplier = 1
tm1.sensors.user_frame.multiplier = 1

Go ahead and enter velocity control mode, and set a setpoint:

.. code-block:: python

tmx.controller.velocity_mode()
tmx.controller.velocity.setpoint = 80000 # around 60 rpm for a 15 pp motor
tm1.controller.velocity_mode()
tm1.controller.velocity.setpoint = 80000 # around 60 rpm for a 15 pp motor

The motor should now move at a constant velocity.

Once you have determined that the motor behaves as expected, set to idle and perform another config save to persist the configuration:

.. code-block:: python

tmx.controller.idle()
tmx.save_config()
tm1.controller.idle()
tm1.save_config()


Observer Bandwidth
Expand Down
24 changes: 24 additions & 0 deletions docs/studio/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,30 @@ Example:
By default, Tinymovr Studio will use slcan as the interface, and will search for CANAble/CANtact-type devices with slcan firmware. Such is the CANine adapter supplied with Tinymovr Servo Kits.


``--bitrate=<chan>``
====================

Specifies a bitrate in baud.

Example:

|gui|

.. code-block:: console

tinymovr --bus=socketcan --bitrate=1000000

|cli|

.. code-block:: console

tinymovr_cli --bus=socketcan --bitrate=1000000

By default, Tinymovr Studio will use 1000000 as bitrate.
We tested with 1000000, 500000 and 250000 baud.



Units
#####

Expand Down
2 changes: 1 addition & 1 deletion docs/upgrade/upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Flashing the Firmware

.. code-block:: python

tmx.enter_dfu()
tm1.enter_dfu()

Then exit the CLI by typing ``exit``.

Expand Down
5 changes: 5 additions & 0 deletions studio/Python/tests/test_board.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,11 @@ def test_d_position_control(self):
self.check_state(0)
self.tm.controller.current.Iq_limit = 5
self.try_calibrate()
if hw_rev > 20:
self.tm.controller.position.p_gain = 5
self.tm.controller.velocity.p_gain = 2e-5
self.tm.controller.velocity.i_gain = 0

self.tm.controller.position_mode()
self.check_state(2)

Expand Down
3 changes: 2 additions & 1 deletion studio/Python/tinymovr/bus_router.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from enum import Enum
from threading import Thread, Lock
from tinymovr.bus_manager import BusManager
from logging import Logger


bus_router = None
Expand Down Expand Up @@ -86,7 +87,7 @@ def send(self, frame):
self.bus_manager.send(frame)


def init_router(bus_class, bus_params, logger, timeout=0.1):
def init_router(bus_class, bus_params, logger=Logger("tinymovr"), timeout=0.1):
"""
Initializes a bus router using a python-can bus instance
"""
Expand Down
Loading