Write Functions
- static HIL.esc_output(protocol, throttle, polarity=1, telemetry=False, command=48)
Generates a PWM output value suitable for an ESC command.
The esc_output function returns an appropriate value to write to a PWM output to perform the given ESC command based on the given protocol and options. The returned value may then be written to the PWM output using a function such as write_pwm.
For ESC protocols like standard PWM, OneShot and Multishot, the throttle value as a percentage (0% to 100% or -100% to 100%) is mapped to a pulse width in seconds. The PWM output mode should be configured as
PWMMode.TIMEin theset_pwm_mode()function when using these protocols. The desired PWM period must also be configured using theset_pwm_frequency()functions.The telemetry and command inputs are ignored unless the protocol is
EscProtocol.DSHOT.For the DSHOT protocol, the polarity, throttle, telemetry and command are all used. The throttle value is a percentage (0% to 100% or -100% to 100% depending on the polarity) and the telemetry is a logical input indicating whether to include a telemetry request in the DSHOT output. The command argument is used for special commands. A command value of 0 means “disarm”, for instance. Command values from 0-47 are for special commands and the throttle value will be ignored in the output. A command value of 48 means “armed”. In this case, the throttle value is included in the output value. See the
DshotCommandenumeration for a full list of the DSHOT commands.For DSHOT, the PWM output should be configured in
PWMMode.RAWin theset_pwm_mode()function and DSHOT should be enabled in the card-specific options e.g.pwm0_dshot=1via theset_card_specific_options()function. The PWM frequency will determine the bit rate for the DSHOT. For example, a PWM frequency of 600e3 will result in DSHOT600 being output from the PWM output.The table below enumerates the typical settings employed for various ESC protocols.
Protocol
Description
PWM Mode
PWM Frequency
ESC Constant
Standard PWM
1 to 2 ms pulse every 20 ms.
PWMMode.TIME
50
EscProtocol.STANDARD_PWM
OneShot125
125 to 250 us pulse every 500us.
PWMMode.TIME
2000
EscProtocol.ONESHOT125
OneShot42
42 to 84 us pulse every 168us.
PWMMode.TIME
1/168e-6
EscProtocol.ONESHOT42
Multishot
5 to 25 us pulse every 50us.
PWMMode.TIME
20000
EscProtocol.MULTISHOT
DShot150
16-bit packet at 150 kbaud.
PWMMode.RAW
150e3
EscProtocol.DSHOT
DShot300
16-bit packet at 300 kbaud.
PWMMode.RAW
300e3
EscProtocol.DSHOT
DShot600
16-bit packet at 600 kbaud.
PWMMode.RAW
600e3
EscProtocol.DSHOT
DShot1200
16-bit packet at 1200 kbaud.
PWMMode.RAW
1200e3
EscProtocol.DSHOT
DShot2400
16-bit packet at 2400 kbaud.
PWMMode.RAW
2400e3
EscProtocol.DSHOT
- Parameters
protocol (EscProtocol) – The ESC protocol for which the PWM output value will be generated.
throttle (double) – A fraction between 0.0 and 1.0 representing the throttle value from 0% to 100% when the polarity is
EscPolarity.UNSIGNED. Otherwise it is a double-precision value in the range -1.0 to 1.0 representing a throttle value from -100% to +100%.polarity (EscPolarity) – The ESC polarity determining whether the throttle is unipolar/unsigned or bipolar/signed, and how signed throttle values map to output values (symmetrically or asymmetrically). Note that DSHOT 3D mode for AM32 firmware uses
EscPolarity.ASYMMETRIC_SIGNEDpolarity. Only the DSHOT protocol supports asymmetric polarity.telemetry (boolean) – When the ESC protocol is set to
EscProtocol.DSHOT, the telemetry parameter determines whether telemetry information is returned from the selected channel (True or False).command (DshotCommand) – When the ESC protocol is set to
EscProtocol.DSHOT, the commmand parameter represents the DSHOT command. UseDshotCommand.ARMEDwhen trying to control the motor throttle.
- Raises
HILError – Raises an exception on an error. A suitable error message may be retrieved using
get_error_message().
Examples
Send a DSHOT command to arm the motors.
Using array:
>>> from array import array >>> from quanser.hardware import HIL, EscProtocol, EscPolarity, DshotCommand >>> card = HIL("qdrone2", "0") >>> try: >>> channels = array('I', [0, 1, 2, 3]) >>> num_channels = len(channels) >>> buffer = array('d', [card.esc_output(EscProtocol.DSHOT, EscPolarity.UNSIGNED, 0.0, False, DShotCommand.ARMED)] * 4) >>> card.write_pwm(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
Using numpy:
>>> import numpy as np >>> from quanser.hardware import HIL, EscProtocol, EscPolarity, DshotCommand >>> card = HIL("qdrone2", "0") >>> try: >>> channels = np.array([0, 1, 2, 3], dtype=np.uint32) >>> num_channels = len(channels) >>> buffer = np.array([card.esc_output(EscProtocol.DSHOT, EscPolarity.UNSIGNED, 0.0, False, DShotCommand.ARMED)] * 4, dtype=np.float64) >>> card.write_pwm(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
- HIL.write_analog(channels, num_channels, buffer)
Writes to analog outputs immediately. The function does not return until the data has been written.
- Parameters
channels (array_like) – An array containing the channel numbers of the analog outputs to be written.
num_channels (int) – The number of channels specified in the channels array.
buffer (array_like) – An array containing the voltage values to write to the analog outputs. The array must contain num_channels elements. Each element in the buffer array corresponds to the same element in the channels array.
- Raises
HILError – On non-zero return code. A suitable error message may be retrieved using
get_error_message().
Examples
Write to the first four analog output channels.
Using array:
>>> from array import array >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = array('I', [0, 1, 2, 3]) >>> num_channels = len(channels) >>> buffer = array('d', [0.5, 1.5, 2.5, 3.5]) >>> card.write_analog(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
Using numpy:
>>> import numpy as np >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = np.array([0, 1, 2, 3], dtype=np.uint32) >>> num_channels = len(channels) >>> buffer = np.array([0.5, 1.5, 2.5, 3.5], dtype=np.float64) >>> card.write_analog(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
- HIL.write_analog_codes(channels, num_channels, buffer)
Writes to the specified analog output channels immediately using raw D/A converter values. The function does not return until the data has been written.
- Parameters
channels (array_like) – An array containing the channel numbers of the analog outputs to be written.
num_channels (int) – The number of channels specified in the channels array.
buffer (array_like) – An array containing the raw D/A converter values to write to the analog outputs. The array must contain num_channels elements. Each element in the buffer array corresponds to the same element in the channels array.
- Raises
HILError – On non-zero return code. A suitable error message may be retrieved using
get_error_message().
Examples
Write to the first four analog output channels using raw D/A converter values.
Using array:
>>> from array import array >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = array('I', [0, 1, 2, 3]) >>> num_channels = len(channels) >>> buffer = array('i', [0x000, 0x3ff, 0x5ff, 0x7ff]) >>> card.write_analog_codes(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
Using numpy:
>>> import numpy as np >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = np.array([0, 1, 2, 3], dtype=np.uint32) >>> num_channels = len(channels) >>> buffer = np.array([0x000, 0x3ff, 0x5ff, 0x7ff], dtype=np.int32) >>> card.write_analog_codes(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
- HIL.write_pwm(channels, num_channels, buffer)
Writes to specified PWM output channels immediately. The function does not return until the data has been written.
- Parameters
channels (array_like) – An array containing the channel numbers of the PWM outputs to be written.
num_channels (int) – The number of channels specified in the channels array.
buffer (array_like) – An array containing the values to write to the PWM outputs. How these values are interpreted depends on the PWM mode. The PWM mode is configured using the hil_set_pwm_mode function. The array must contain num_channels elements. Each element in the buffer array corresponds to the same element in the channels array.
- Raises
HILError – On non-zero return code. A suitable error message may be retrieved using
get_error_message().
Examples
Write to the first four PWM output channels.
Using array:
>>> from array import array >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = array('I', [0, 1, 2, 3]) >>> num_channels = len(channels) >>> buffer = array('d', [0.0, 0.3, 0.7, 1.0]) >>> card.write_pwm(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
Using numpy:
>>> import numpy as np >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = np.array([0, 1, 2, 3], dtype=np.uint32) >>> num_channels = len(channels) >>> buffer = np.array([0.0, 0.3, 0.7, 1.0], dtype=np.float64) >>> card.write_pwm(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
- HIL.write_digital(channels, num_channels, buffer)
Writes to digital outputs immediately. The function does not return until the data has been written.
- Parameters
channels (array_like) – An array containing the channel numbers of the digital outputs to be written.
num_channels (int) – The number of channels specified in the channels array.
buffer (array_like) – An array containing the binary values to write to the digital outputs. The array must contain num_channels elements. Each element in the buffer array corresponds to the same element in the channels array.
- Raises
HILError – On non-zero return code. A suitable error message may be retrieved using
get_error_message().
Examples
Write to the first four PWM output channels.
Using array:
>>> from array import array >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = array('I', [0, 1, 2, 3]) >>> num_channels = len(channels) >>> buffer = array('b', [0, 1, 1, 0]) >>> card.write_digital(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
Using numpy:
>>> import numpy as np >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = np.array([0, 1, 2, 3], dtype=np.uint32) >>> num_channels = len(channels) >>> buffer = np.array([0, 1, 1, 0], dtype=np.int8) >>> card.write_digital(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
- HIL.write_other(channels, num_channels, buffer)
Writes to the specified other output channels immediately. The function does not return until the data has been written.
- Parameters
channels (array_like) – An array containing the channel numbers of the other outputs to be written.
num_channels (int) – The number of channels specified in the channels array.
buffer (array_like) – An array containing the values to write to the other outputs. The array must contain num_channels elements. Each element in the buffer array corresponds to the same element in the channels array.
- Raises
HILError – On non-zero return code. A suitable error message may be retrieved using
get_error_message().
Examples
Write to the first two other output channels.
Using array:
>>> from array import array >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = array('I', [0, 1]) >>> num_channels = len(channels) >>> buffer = array('d', [1.0, 0.0]) >>> card.write_other(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
Using numpy:
>>> import numpy as np >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> channels = np.array([0, 1], dtype=np.uint32) >>> num_channels = len(channels) >>> buffer = np.array([1.0, 0.0], dtype=np.float64) >>> card.write_other(channels, num_channels, buffer) >>> # ... ... >>> finally: >>> card.close()
- HIL.write(analog_channels, num_analog_channels, pwm_channels, num_pwm_channels, digital_channels, num_digital_channels, other_channels, num_other_channels, analog_buffer, pwm_buffer, digital_buffer, other_buffer)
Writes to the specified output channels immediately. The function does not return until the data has been written.
The interpretation of the PWM samples to be written depends upon the PWM mode. Typically, the data is interpreted as a duty cycle, in which a magnitude of 0.0 denotes a 0% duty cycle and magnitude of 1.0 indicates a 100% duty cycle. The sign determines the polarity of the output for those boards supporting bidirectional PWM outputs. However, other PWM modes are possible with some boards. Refer to the set_pwm_mode function for details.
- Parameters
analog_channels (array_like or None) – An array containing the channel numbers of the analog outputs to be written. If no analog channels are required, then this parameter may be
None. In this case, num_analog_channels must be zero.num_analog_channels (int) – The number of channels specified in the analog_channels array. This parameter may be zero.
pwm_channels (array_like or None) – An array containing the channel numbers of the PWM outputs to be written. If no PWM channels are required, then this parameter may be
None. In this case, num_pwm_channels must be zero.num_pwm_channels (int) – The number of channels specified in the pwm_channels array. This parameter may be zero.
digital_channels (array_like or None) – An array containing the channel numbers of the digital outputs to be written. If no digital channels are required, then this parameter may be
None. In this case, num_digital_channels must be zero.num_digital_channels (int) – The number of channels specified in the digital_channels array. This parameter may be zero.
other_channels (array_like or None) – An array containing the channel numbers of the other outputs to be written. If no other channels are required, then this parameter may be
None. In this case, num_other_channels must be zero.num_other_channels (int) – The number of channels specified in the other_channels array. This parameter may be zero.
analog_buffer (array_like or None) – An array containing the voltage values to write to the analog outputs. The array must contain num_analog_channels elements. Each element in the analog_buffer array corresponds to the same element in the analog_channels array. If no analog channels were specified, then this parameter may be
None.pwm_buffer (array_like or None) – An array containing the values to write to the PWM outputs. How these values are interpreted depends on the PWM mode. The PWM mode is configured using the set_pwm_mode function. The array must contain num_pwm_channels elements. Each element in the pwm_buffer array corresponds to the same element in the pwm_channels array. If no PWM channels were specified, then this parameter may be
None.digital_buffer (array_like or None) – An array containing the binary values to write to the digital outputs. The array must contain num_digital_channels elements. Each element in the digital_buffer array corresponds to the same element in the digital_channels array. If no digital channels were specified, then this parameter may be
None.other_buffer (array_like or None) – An array containing the values to write to the other outputs. The array must contain num_other_channels elements. Each element in the other_buffer array corresponds to the same element in the other_channels array. If no other channels were specified, then this parameter may be
None.
- Raises
HILError – On non-zero return code. A suitable error message may be retrieved using
get_error_message().
Warning
Many cards allow the digital I/O lines to be programmed as inputs or outputs. The digital I/O lines are configured as inputs or outputs using the set_digital_directions function. All the channels which will be used as digital outputs must be configured as outputs using this function. Failure to configure the digital I/O may result in the write function failing to write those outputs.
Examples
Write to two analog output channels, two PWM output channels, and four digital output channels.
Using array:
>>> from array import array >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> analog_channels = array('I', [0, 1]) >>> pwm_channels = array('I', [0, 1]) >>> digital_channels = array('I', [0, 1, 2, 3]) >>> num_analog_channels = len(analog_channels) >>> num_pwm_channels = len(pwm_channels) >>> num_digital_channels = len(digital_channels) >>> analog_buffer = array('d', [0.5, -0.5]) >>> pwm_buffer = array('d', [-1000.0, 1000.0]) >>> digital_buffer = array('b', [0, 1, 0, 1]) >>> card.write(analog_channels, num_analog_channels, ... pwm_channels, num_pwm_channels, ... digital_channels, num_digital_channels, ... None, 0, ... analog_buffer, ... pwm_buffer, ... digital_buffer, ... None) >>> # ... ... >>> finally: >>> card.close()
Using numpy:
>>> import numpy as np >>> from quanser.hardware import HIL >>> card = HIL("q8_usb", "0") >>> try: >>> analog_channels = np.array([0, 1], dtype=np.uint32) >>> pwm_channels = np.array([0, 1], dtype=np.uint32) >>> digital_channels = np.array([0, 1, 2, 3], dtype=np.uint32) >>> num_analog_channels = len(analog_channels) >>> num_pwm_channels = len(pwm_channels) >>> num_digital_channels = len(digital_channels) >>> analog_buffer = np.array([0.5, -0.5], dtype=np.float64) >>> pwm_buffer = np.array([-1000.0, 1000.0], dtype=np.float64) >>> digital_buffer = np.array([0, 1, 0, 1], dtype=np.int8) >>> card.write(analog_channels, num_analog_channels, ... pwm_channels, num_pwm_channels, ... digital_channels, num_digital_channels, ... None, 0, ... analog_buffer, ... pwm_buffer, ... digital_buffer, ... None) >>> # ... ... >>> finally: >>> card.close()