QLabs Core Library

Description

The QLabs Core library is the base library that manages all communications to the Quanser Interactive Labs software. Only the open and close methods are typically used. The remaining methods are for advanced usage.

QLabs Core Library

class qvl.qlabs.QuanserInteractiveLabs[source]

This class establishes a server connection with QLabs and manages the communications.

Constants

This library has no user constants.

Basic Methods

QuanserInteractiveLabs.open(address, timeout=10)[source]

Open a connection to QLabs.

Parameters
  • address (string) – The machine name or IP address of a local or remote copy of QLabs such as “localhost”, or “192.168.1.123”.

  • timeout (float) – (Optional) Period to attempt the connection for before aborting. Default 10s.

Returns

True if successful, False otherwise

Return type

boolean

QuanserInteractiveLabs.close()[source]

Shutdown and close a connection to QLabs. Always close a connection when communications are finished.

Returns

No return. If an existing connection cannot be found, the function will fail silently.

Return type

none

QuanserInteractiveLabs.set_wait_for_container_timeout(timeout)[source]

By default, a method using the wait_for_container method (typically represented with the waitForComfirmation flag) will abort waiting for an acknowledgment after 5 seconds at which time the method will return a failed response. This time period can be adjusted with this function. Values less than or equal to zero will cause the methods to wait indefinitely until the expected acknowledgment is received.

Parameters

timeout (float) – Timeout period in seconds

QuanserInteractiveLabs.destroy_all_spawned_actors()[source]

Find and destroy all spawned actors and widgets. This is a blocking operation.

Returns

The number of actors deleted. -1 if failed.

Return type

int32

Advanced Methods

To help manage the volume of data in the communications channel and help maintain real-time performance, the system is built on a request/response system. In a typical control system, a request for information about the state of the system is made from which a new output can be calculated. This in turn is sent back to the simulation which in turn responds with a new set of data.

Most of the library methods implemented follow this approach where the method call will package a single container into a packet, send the request and wait for the response before proceeding. All requests are processed once each frame so the communications rate is directly related to the frame rate. The exception to this is when the wait_for_container (typically represented with the waitForConfirmation flag) is used. Once again a single container is packaged into a packet and sent, but if the waitForConfirmation is set to False then the method immediately returns allowing the user code to call more non-blocking methods. If done in quick succession, then multiple packets will be received by QLabs and all containers received during that frame will have a return container that will be packed into a single packet.

Using non-blocking methods can significantly improve the data rate as you can now process multiple containers per animation frame instead of just one. The approach is simple, but the disadvantage is that high volumes of data can exceeds the communication buffers resulting lost requests and unreliable communications. This can work well when spawning hundreds of actors on setup, but you may find a a few actors missing when trying to spawn thousands.

A better method to improve the communication efficiency as well as ensure all communication requests are processed during a single animation frame is to use the queue methods. Rather than sending container immediately, the container is queued. Once all the containers have been added, the queue_send is used to package the containers into a single packet ensuring that all containers will be processed during a single animation frame. To construct a container for a given function, refer to the library source code. See QLabs Communication Container for details of the container class.

After the data is sent, poll the receive_new_data method to wait for the response packet. If the data exceeds the size of a TCP/IP frame, this method may need to be called multiple times to collect the entire packet. Once receive_new_data returns True, use the get_next_container method to extract the next container from the packet until no more containers remain. To decode the contents of the container, again refer to the source code of the respective libraries the responses. Note that containers may not return in the same order in which they were sent.

Using these low-level communications functions adds more complexity to the communication process, but it provides a higher level of control and optimizes the transaction process to improve the data throughput.

QuanserInteractiveLabs.send_container(container)[source]

Package a single container into a packet and transmit immediately

Parameters

container (CommModularContainer object) – CommModularContainer populated with the actor information.

Returns

True if successful, False otherwise

Return type

boolean

QuanserInteractiveLabs.queue_add_container(container)[source]

Queue a single container into a buffer for future transmission

Parameters

container (CommModularContainer object) – CommModularContainer populated with the actor information.

QuanserInteractiveLabs.queue_send()[source]

Package the containers in the queue and transmit immediately

Parameters

container (CommModularContainer object) – CommModularContainer populated with the actor information.

Returns

True if successful and the queue will be emptied, False otherwise and the queue will remain intact.

Return type

boolean

QuanserInteractiveLabs.queue_destroy()[source]

The container queue is emptied of all data.

QuanserInteractiveLabs.receive_new_data()[source]

Poll for new data received from QLabs through the communications framework. If you are expecting large amounts of data such as video, this should be executed frequently to avoid overflowing internal buffers. Data split over multiple packets will be automatically reassembled before returning true. This method is non-blocking.

Returns

True if at least one complete container has been received, False otherwise

Return type

boolean

QuanserInteractiveLabs.get_next_container()[source]

If receive_new_data has returned true, use this method to receive the next container in the queue.

Returns

The data will be returned in a CommModularContainer object along with a flag to indicate if additional complete containers remain in the queue for extraction. If this method was used without checking for new data first and the queue is empty, the container will contain the default values with a class ID of ID_UNKNOWN.

Return type

CommModularContainer object, boolean

QuanserInteractiveLabs.wait_for_container(classID, actorNumber, functionNumber)[source]

Continually poll and parse incoming containers until a response from specific actor with a specific function response is received. Containers that do not match the class, actor number, and function number are discarded. This function blocks until the appropriate packet is received or the timeout is reached.

Returns

The data will be returned in a CommModularContainer object.

Return type

CommModularContainer object

QuanserInteractiveLabs.flush_receive()[source]

Flush receive buffers removing all unread data. This can be used to clear receive buffers after fault conditions to ensure it contains only new data.

Returns

None

Return type

None

QuanserInteractiveLabs.ping()[source]

QLabs will automatically disconnect a non-responsive client connection. The ping method can be used to keep the connection alive if operations are infrequent.

Returns

True if successful, False otherwise

Return type

boolean