Getting Started with Python

Installation

Information on how to install the iqmotion library can be found on our PyPi page.

Python API Basics

Hardware Setup

Information about required hardware for API communication can be found in the Control Center documentation. The requirements for API communication are the same as those for the IQ Control Center.

Opening a Serial Connection

In order to connect with your USB-to-UART bridge, the Python API provides the SerialCommunicator class.

The SerialCommunicator class is initialized with a serial port name and a baud rate. The name of your serial port is dependent on your operating system. For example, in the hardware example provided in the Control Center documentation linked above, the serial port name is “COM3,” and in Linux, it may be “/dev/ttyUSB0.”

In order to create a new SerialCommunicator object on a Windows operating system where your module is set to 115200 baud, and your FTDI reports on COM9, you would do the following:

import iqmotion as iq
com = iq.SerialCommunicator("COM9", baudrate=115200)

In order to communicate with a Vertiq module through the Python API, you must create a SerialCommunicator object.

Creating a Module Object

Vertiq’s module objects are preconfigured to communicate with all accessible IQUART clients for your module’s firmware. All module objects are created with the same initialization.

  1. A serial communicator object

  2. Optionally, a module ID (module_idn)

  • This represents the module ID of the device you would like to communicate with. If your module has its module ID configured to 26, you must set module_idn to 26 in object instantiation. If no module ID is specified, the module object is created with an ID of 0.

  1. Optionally, a firmware style (firmware)

  • This value is a string, and can be “speed”, “servo”, or “pulsing”. To learn more about what firmware styles are available for your module, please refer to your module’s family page. If no firmware style is specified, the module object is created with a style of speed.

  1. Optionally, a path to additional clients (clients_path)

  • There are two options available for adding extra clients. First, in order to add all client files in a folder, you can pass a path to a folder that contains all additional, client json files. Second, you can pass an array of paths to custom client json files in order to only add those you are interested in rather than an entire folder. In general, you will not need to include additional clients.

Please use the following to create the correct object for your module type:

Module Families and Python Object Names

Module Family

Object Name

Vertiq 23-XX

Vertiq2306

Vertiq 40-XX

Vertiq4006

Vertiq 60-XX

Vertiq6008

Vertiq 81-XX

Vertiq8108

Additionally, there are generic SpeedModule and ServoModule objects with access to the most basic IQUART endpoints for the associated firmware style.

Suppose you want to interact with a Vertiq 40-06 using speed firmware whose module ID is 42, and has extra client files located in a folder with the path “clients.” To do so:

  1. Create a SerialCommunicator object as described above (in this case the USB-to-UART is on port COM3)

  2. Create a variable client_files with the path to your additional client json files

  3. Create a variable module as a Vertiq4006 module with module ID 42, speed firmware, and extra clients path client_files

import iqmotion as iq

# Module Communication
com = iq.SerialCommunicator("COM3", baudrate=115200)

# Clients to Load
client_files = "clients/"

# Using the Vertiq4006 with additional custom client files
module = iq.Vertiq4006(com, module_idn=42, firmware="speed", clients_path=client_files)

At this point, you can communicate with, configure, and control your connected module through its available clients.

Interacting with Clients and Endpoints

As mentioned in Getting Started with Vertiq’s APIs, all Vertiq clients contain endpoints that can accept get, set, and save commands. This section discusses how to perform gets, sets, and saves through the Python API.

Before moving forward, please familiarize yourself with the clients available for your module’s family and firmware style. You can find this information on your module’s family page in the Supported IQUART Clients section. For these examples, we will continue to use the Vertiq4006 object created above.

Note

In all instances, the value of client_entry is a value specified by the Short Name column of the associated IQUART client table.

Get

All Python get commands have the format module.get("client", "client_entry"). The get function returns the value of a single client entry returned by the module through IQUART.

Suppose we want to monitor the voltage read at the module’s input. We can do this through the volts entry of the Power Monitor client.

../_images/volts_entry.png

In order to get and view the value of the volts parameter, we can add the following to our example

print(module.get("power_monitor", "volts"))

You can also treat the returned value as a normal parameter, and store it in a variable.

Get All

All Python get_all commands have the format module.get_all("client”). The get_all function returns the value of all client entries returned by the module through IQUART.

Suppose we want to see the current state of all parameters in the System Control client.

To do so, we can do the following:

print(module.get_all("system_control"))

Again, you can also treat the returned value as a normal parameter, and store it in a variable. In this case the data is stored as an array.

Set

Most Python set commands have the format module.set("client", "client_entry", value). The set function changes the value of the target client_entry to value. A value set and not saved will not be retained after a power cycle.

Suppose we want to change the Propeller Motor Controller’s timeout parameter to 3 seconds.

../_images/timeout_entry.png

To do so:

module.set("propeller_motor_control", "timeout", 3)

Some client entries (such as System Control’s reboot_program) accept sets without a value. Simply calling module.set("client", "client_entry") is enough to trigger the desired behavior. You can tell that an entry does not require a value when its client table entry has no data type. So, to reboot your module’s program:

module.set("system_control", "reboot_program")

Set Verify

Additionally to the standard set, you can use the set_verify function in order to set a new value, and confirm that the value has been set correctly on the module. Set verify calls have the same format as standard set commands, but provide additional optional parameters get_values, time_out, retries, and save.

  • get_values: Specifies values to add in the get message (such as index for some client entries). By default, this is None

  • time_out: A blocking timeout while verifying the set is successful in seconds. By default, this is 0.1s

  • retries: The number of times you would like to retry the set before giving up. By default, this is 5

  • save: Allows you to save the value once the set is confirmed. By default this is False

To set your module’s DroneCAN (UAVCAN) node ID to 5, verify the set, and save it:

module.set_verify("uavcan_node", "uavcan_node_id", 5, time_out=5, retries=10, save=True)

Save

All Python save commands have the format module.save("client", "client_entry"). The save function takes the currently set entry value, and stores it in the module’s persistent memory. Values that are saved are retained on power cycles.

Suppose we want to save the timeout value set above. To do so:

module.save("propeller_motor_control", "timeout")

Next Steps

As the get, set, and save commands are the basis of all IQUART configuration and control, you now posess all of the base knowledge necessary to begin development with the Vertiq Python API.

A very basic example is provided here. It demonstrates the basics of setting up communication and a module object as well as how to set, get, and get_all.

Warning

Please remove all propellers from any module you plan on testing. Failure to do so can result in harm to you or others around you. Further, please ensure that your module is secured to a stationary platform or surface before attempting to spin it.

import iqmotion as iq
import time

# Module Communication
com = iq.SerialCommunicator("COM3", baudrate=115200)

# Using the Vertiq4006 with default settings
module = iq.Vertiq4006(com)

#Check our microcontroller temperature client's status
print(module.get_all("temperature_monitor_uc"))

#Check our current input voltage. Store it in a variable.
voltage_now = module.get("power_monitor", "volts")
print(voltage_now)

#Wait 5 seconds
time.sleep(5)

#Loop forever
while(1):

    #Spin very slowly
    module.set("propeller_motor_control", "ctrl_velocity", 20)

    #Check our velocity
    print(module.get("brushless_drive", "obs_velocity"))

    time.sleep(0.05)

More specific examples of using the Python API exist throughout our Feature Reference Manual, such as a basic example for commanding your module to spin with the Propeller Motor Controller Client.