Skip to main content

A driver for the CyberGear micromotor

Project description

Python CyberGear Motor Driver

A python driver for the CyberGear motor. This driver uses a CAN bus interface to communicate with and drive the motor.

CyberGear user manual

Getting started

Install the package from pip:

pip install CyberGearDriver

CAN Interface

Since there are so many CAN interfaces, the motor driver does not have built-in CAN drivers but has a couple simple methods to connect external CAN drivers to it.

For example, using a Serial CAN USB adapter with python-can would look something like this:

import can
from CyberGearDriver import CyberGearMotor, RunMode, CyberMotorMessage

# Connect to the bus with python-can
# @see https://python-can.readthedocs.io/en/stable/installation.html
bus = can.interface.Bus(
    interface='slcan',
    channel='/dev/cu.usbmodem101',
    bitrate=1000000,
)

# Create function to pass the messages from CyberGear to the CAN bus
def send_message(message: CyberMotorMessage):
    bus.send(
        can.Message(
            arbitration_id=message.arbitration_id,
            data=message.data,
            is_extended_id=message.is_extended_id,
        )
    )

# Create the motor controller
motor = CyberGearMotor(motor_id=127, send_message=send_message)

# Send the CyberGear driver messages received from the CAN bus
notifier = can.Notifier(bus, [motor.message_received])

Moving the motor

The motor has 4 different drive modes:

  1. Operation control mode (sometimes call MIT control mode)
  2. Position mode
  3. Velocity mode
  4. Torque mode (or current mode)

Operation Control Mode

This is sometimes called MIT mode and combines position, speed, and torque to move the motor in a single function:

motor.enable()
motor.mode(RunMode.OPERATION_CONTROL)

motor.control(position=-6, velocity=0, torque=0, kp=0.1, kd=0.1)

Full example

Position control mode

In this mode the motor will move to the loc_ref parameter value (see section 4.1.12 for a list of parameters).

motor.enable()
motor.mode(RunMode.POSITION)

# Limit the top speed
motor.set_parameter("limit_spd", 10)

# Move to position 8 rad
motor.set_parameter("loc_ref", 8)

Full example

Velocity mode

This mode continuously spins the motor at a particular speed, controlled by the spd_ref, spd_kp, spd_ki, and limit_cur parameter values. (see section 4.1.12 for a full list of parameters).

motor.enable()
motor.mode(RunMode.VELOCITY)

# Turn at 5 rad/s
motor.set_parameter("spd_ref", 5)

Full example

Torque mode (i.e. Current Mode)

This controls how much current is applied to the motor with the iq_ref, cur_kp, cur_ki, and cur_filt_gain parameter values. (see section 4.1.12 for a full list of parameters).

motor.enable()
motor.mode(RunMode.TORQUE)

# Apply 0.5A of maximum torque to the motor
motor.set_parameter("iq_ref", 0.5)

Full example

Current motor state

There's a single command to request the position, torque, velocity, and temperature of the motor. The controller will listen for the response and automatically add it to the state dict.

motor.request_motor_state()
time.sleep(1)
print(motor.state.get("position"))

You can also use an event listener to be notified when the state value has been retrieved

def state_updated():
    print(f"{motor.state}")

motor.on("state_changed", state_updated)
motor.request_motor_state()

Reading and writing motor config and parameters

The motor has two lists of values that you can read and write. Config values are saved between power cycles. Parameter values control motor activity and are reset on power down.

NOTE: CyberGear calls both of these sets of values "parameters". In the driver we differentiate them to "config" and "parameters". This is because they are read and saved slightly differently.

To see the full list of config and parameters, goto the motor docs for a full list of parameters)

  • Config values: section 3.3.3 (CyberGear calls them parameters)
  • Parameter values: section 4.1.12

Read config values

To read a value, you have to request it from the motor. The driver will handle the response reading it and assigning it to it's internal config dict.

motor.request_config("MechOffset")
time.sleep(1)
print(motor.config.get("MechOffset"))

You can also use an event listener to be notified when config values are retrieved

def config_value_received(name: str, value: str):
    print(f"{name}: {value}")

motor.on("config_received", config_value_received)
motor.request_config("MechOffset")

Set config values

Be careful when setting config values. Many of them cannot be written to, and others are core to how the motor works -- you could break your motor if you don't know what you're doing.

motor.set_config("overTempTime", 20001)

Read parameter values

To read a parameter, you have to request it from the motor. The driver will handle reading the response and assigning it to it's internal parameter value dict.

motor.request_parameter("loc_ref")
time.sleep(1)
print(motor.params.get("loc_ref"))

You can also use an event listener to be notified when param values are retrieved

def param_value_received(name: str, value: str):
    print(f"{name}: {value}")

motor.on("param_received", param_value_received)
motor.request_parameter("loc_ref")

Set config values

Be careful when setting config values. Many of them cannot be written to, and others are core to how the motor works -- you could break your motor if you don't know what you're doing.

motor.set_config("overTempTime", 20001)

Motor errors

It's important to know when there is a motor fault. Here's how to request the current fault state of the motor:

motor.request_motor_fault_status()

time.sleep(1)

# All the faults might be defined, but only the ones set to True are actively faulting
active_faults = [motor.fault for fault, is_active in faults.items() if is_active]
print("Active motor faults:", motor.faults)

You can also use an event listeners to be notified when faults happen or are cleared.

def has_fault():
    active_faults = [motor.fault for fault, is_active in faults.items() if is_active]
    print("Active motor faults:", motor.faults)

def faults_clear():
    print("No more faults")

# Define event listeners
motor.on("has_fault", has_fault)
motor.on("fault_cleared", has_fault)

# Check regularly
motor.request_motor_fault_status()

Other useful things

Change the CAN bus ID

If you have multiple motors, you'll need to change their CAN bus IDs so they can all be on the same bus.

motor.change_motor_id(5)

Set zero position

Set the current motor position as the zero position. NOTE: this position is lost on power down.

motor.set_zero_position()

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cybergeardriver-0.1.0.tar.gz (13.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cybergeardriver-0.1.0-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file cybergeardriver-0.1.0.tar.gz.

File metadata

  • Download URL: cybergeardriver-0.1.0.tar.gz
  • Upload date:
  • Size: 13.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.16

File hashes

Hashes for cybergeardriver-0.1.0.tar.gz
Algorithm Hash digest
SHA256 d746ba72eb3f5a9c35fe5d6d413e457e024b2db1aafc18f8cf184d5c31b1dfcd
MD5 4127c548af2784efc76580045a061a4d
BLAKE2b-256 690d2fe8a71a90f57d8e44efb69485f487fa018ff781e93e63cc961727c0c1e3

See more details on using hashes here.

File details

Details for the file cybergeardriver-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for cybergeardriver-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f2189d6e7b52266815dca2ad13555591bbc5e17038eb3b66616bc435f671b11f
MD5 02eaa6848fefc4d59119b85af95f0d8d
BLAKE2b-256 3361bc01c41666fd9b57f4031ba871c73e5e73dbb837bb9691b6069e89723f66

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page