Merge branch 'master' into feature/streaming-hitl
This commit is contained in:
commit
ef77b035d8
@ -12,7 +12,7 @@ import sys
|
||||
from gmqtt import Client as MqttClient
|
||||
from miniconf import Miniconf
|
||||
|
||||
# The minimum allowably loopback voltage error (difference between output set point and input
|
||||
# The minimum allowable loopback voltage error (difference between output set point and input
|
||||
# measured value).
|
||||
MINIMUM_VOLTAGE_ERROR = 0.010
|
||||
|
||||
@ -52,34 +52,30 @@ class TelemetryReader:
|
||||
""" Helper utility to read Stabilizer telemetry. """
|
||||
|
||||
@classmethod
|
||||
async def create(cls, prefix, broker):
|
||||
async def create(cls, prefix, broker, queue):
|
||||
"""Create a connection to the broker and an MQTT device using it."""
|
||||
client = MqttClient(client_id='')
|
||||
await client.connect(broker)
|
||||
return cls(client, prefix)
|
||||
return cls(client, prefix, queue)
|
||||
|
||||
|
||||
def __init__(self, client, prefix):
|
||||
def __init__(self, client, prefix, queue):
|
||||
""" Constructor. """
|
||||
self.client = client
|
||||
self._telemetry = []
|
||||
self.client.on_message = self.handle_telemetry
|
||||
self._telemetry_topic = f'{prefix}/telemetry'
|
||||
self.client.subscribe(self._telemetry_topic)
|
||||
self.queue = queue
|
||||
|
||||
|
||||
def handle_telemetry(self, _client, topic, payload, _qos, _properties):
|
||||
""" Handle incoming telemetry messages over MQTT. """
|
||||
assert topic == self._telemetry_topic
|
||||
self._telemetry.append(json.loads(payload))
|
||||
self.queue.put_nowait(json.loads(payload))
|
||||
|
||||
|
||||
def get_latest(self):
|
||||
""" Get the latest telemetry message received. """
|
||||
return self._telemetry[-1]
|
||||
|
||||
|
||||
async def test_loopback(miniconf, telemetry, set_point):
|
||||
async def test_loopback(miniconf, telemetry_queue, set_point, gain=1, channel=0):
|
||||
""" Test loopback operation of Stabilizer.
|
||||
|
||||
Note:
|
||||
@ -91,24 +87,27 @@ async def test_loopback(miniconf, telemetry, set_point):
|
||||
miniconf: The miniconf configuration interface.
|
||||
telemetry: a helper utility to read inbound telemetry.
|
||||
set_point: The desired output voltage to test.
|
||||
channel: The loopback channel to test on. Either 0 or 1.
|
||||
gain: The desired AFE gain.
|
||||
"""
|
||||
print(f'Testing loopback for Vout = {set_point:.2f}')
|
||||
print(f'Testing loopback for Vout = {set_point:.2f}, Gain = x{gain}')
|
||||
print('---------------------------------')
|
||||
# Configure the IIRs to output at the set point
|
||||
await miniconf.command('iir_ch/0/0', static_iir_output(set_point), retain=False)
|
||||
await miniconf.command('iir_ch/1/0', static_iir_output(set_point), retain=False)
|
||||
await miniconf.command('telemetry_period', 1, retain=False)
|
||||
# Configure the AFE and IIRs to output at the set point
|
||||
await miniconf.command(f'afe/{channel}', f'G{gain}', retain=False)
|
||||
await miniconf.command(f'iir_ch/{channel}/0', static_iir_output(set_point), retain=False)
|
||||
|
||||
# Wait for telemetry values to update.
|
||||
# Configure signal generators to not affect the test.
|
||||
await miniconf.command('signal_generator/0/amplitude', 0, retain=False)
|
||||
|
||||
# Wait for telemetry to update.
|
||||
await asyncio.sleep(5.0)
|
||||
|
||||
# Verify the ADCs are receiving the setpoint voltage.
|
||||
tolerance = max(0.05 * set_point, MINIMUM_VOLTAGE_ERROR)
|
||||
latest_values = telemetry.get_latest()
|
||||
latest_values = await telemetry_queue.get()
|
||||
print(f'Latest telemtry: {latest_values}')
|
||||
|
||||
assert abs(latest_values['adcs'][0] - set_point) < tolerance
|
||||
assert abs(latest_values['adcs'][1] - set_point) < tolerance
|
||||
assert abs(latest_values['adcs'][channel] - set_point) < tolerance
|
||||
print('PASS')
|
||||
print('')
|
||||
|
||||
@ -123,22 +122,38 @@ def main():
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
telemetry_queue = asyncio.LifoQueue()
|
||||
|
||||
async def telemetry():
|
||||
await TelemetryReader.create(args.prefix, args.broker, telemetry_queue)
|
||||
try:
|
||||
while True:
|
||||
await asyncio.sleep(1)
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
|
||||
|
||||
telemetry_task = asyncio.Task(telemetry())
|
||||
|
||||
async def test():
|
||||
""" The actual testing being completed. """
|
||||
interface = await Miniconf.create(args.prefix, args.broker)
|
||||
telemetry = await TelemetryReader.create(args.prefix, args.broker)
|
||||
|
||||
# Disable IIR holds and configure the telemetry rate.
|
||||
await interface.command('allow_hold', False, retain=False)
|
||||
await interface.command('force_hold', False, retain=False)
|
||||
await interface.command('telemetry_period', 1, retain=False)
|
||||
|
||||
# Test loopback with a static 1V output of the DACs.
|
||||
await test_loopback(interface, telemetry, 1.0)
|
||||
await test_loopback(interface, telemetry_queue, 1.0)
|
||||
|
||||
# Repeat test with AFE = 2x
|
||||
print('Configuring AFEs to 2x input')
|
||||
await interface.command('afe/0', "G2", retain=False)
|
||||
await interface.command('afe/1', "G2", retain=False)
|
||||
await test_loopback(interface, telemetry, 1.0)
|
||||
await test_loopback(interface, telemetry_queue, 1.0, gain=2)
|
||||
|
||||
# Test with 0V output
|
||||
await test_loopback(interface, telemetry, 0.0)
|
||||
await test_loopback(interface, telemetry_queue, 0.0)
|
||||
|
||||
telemetry_task.cancel()
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
sys.exit(loop.run_until_complete(test()))
|
||||
|
@ -15,7 +15,7 @@ python3 -m venv --system-site-packages py
|
||||
. py/bin/activate
|
||||
|
||||
# Install Miniconf utilities for configuring stabilizer.
|
||||
python3 -m pip install git+https://github.com/quartiq/miniconf#subdirectory=miniconf-py
|
||||
python3 -m pip install git+https://github.com/quartiq/miniconf#subdirectory=py/miniconf-mqtt
|
||||
python3 -m pip install gmqtt
|
||||
|
||||
cargo flash --chip STM32H743ZITx --elf target/thumbv7em-none-eabihf/release/dual-iir
|
||||
|
Loading…
Reference in New Issue
Block a user