-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RT Capabilities Part 1 - robot-log-visualizer #80
Open
nicktrem
wants to merge
81
commits into
ami-iit:main
Choose a base branch
from
nicktrem:rtCapabilitiesP1Visualizer
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
81 commits
Select commit
Hold shift + click to select a range
b46676b
Added the basics of the connect button in the menu
nicktrem 6f1ec87
Added dummy data to test formatting and gui representation
nicktrem cfd0ede
Added a real-time logger button to the GUI
nicktrem f20c655
Added another test data set
nicktrem 5b700c5
initial test of reading form YARP port passed
nicktrem f8153d4
Added more plot support for real-time data
nicktrem a716e59
Fixed small bug in plotting regarding mutiple plots at the same time
nicktrem ff33dc2
Fixed race condition with graphs and bug with plot indexes
nicktrem 2de1dcd
Removed the need to pre-inform the logger about the data coming in
nicktrem 6a3840d
Fixed race condition bug
nicktrem aa331dd
Removed hard-coded value for the length of incoming data
nicktrem 3b86123
Can now stream all data (except mesh data) in real-time
nicktrem 886a45b
Cleaned up the code a bit
nicktrem a1a0799
Added mesh support, cleaned up the code a bit
nicktrem e412bf4
Cleaned up the code, removed hard-coded values
nicktrem e19c626
Cleaned up the code some more
nicktrem 835a17f
Added sliding window feature and icon for connection
nicktrem 0bf0525
Fixed bug with real time logging window
nicktrem 872b364
removed hardcoded value for fixed plot window
nicktrem 36c9f3b
Moved intialization values outside of the conneciton loop
nicktrem 031c401
Fixed blocking when connection closed, changed the YARP port name
nicktrem de5a54a
Added label to rt connection option in GUI
nicktrem be3d77f
Merge branch 'main' into YARP-port-client
nicktrem be1a667
Removed Trailing Whitespace
nicktrem 82eb5e5
Removed whitespace
nicktrem 83dbebc
Removed Whitespace
nicktrem b117936
Fixed issues with merge
nicktrem 228e84f
Fixed freeze when connection stops
nicktrem 4cd3a85
Initial test complete of receiving RT data from Vector Collection Server
nicktrem 6d13f85
Got joint data streaming over the vector collection network
nicktrem 97d2a03
Got mesh updating in realtime, cleaned up the code
nicktrem 56c69ed
Removed unnecessary values from the tree window
nicktrem da33419
plot scaling now updating correctly
nicktrem 27eb858
Flight data streaming
nicktrem 0681e5a
Got naming corrected
nicktrem 1631469
Fixed freezing when server is not running
nicktrem 8d96948
Cleaned up the code a bit
nicktrem a8538d6
Added a grid to the plot
nicktrem 4b203ab
Merge branch 'main' into vectorCollectionClientRT
nicktrem 6c60288
Removed whitespace from signal_provider.py
nicktrem 32a05b7
Changed realtime port name
nicktrem 3604f62
Merge branch 'vectorCollectionClientRT' of https://github.com/nicktre…
nicktrem 336db8e
Changes naming of python functions
nicktrem ad228f1
Edited flag for closing thread properly
nicktrem e10efaa
Moved enable features outside the loop
nicktrem bfce38b
Removed timestamps from RT view
nicktrem 3b7e98e
Removed whitespace
nicktrem cadd9e0
External signals can now be added at any time
nicktrem 0458de2
Cleaned up the code
nicktrem db95f5e
Removed whitespace
nicktrem ac36876
Fixed issue of adding mutiple exogenous signals
nicktrem 82b5353
Removed new metadata flag from being displayed
nicktrem 7b6f231
Cleaned up the code
nicktrem 6056056
Might have fixed element names issue
nicktrem 00c9011
Fixed other issue regarding element_names
nicktrem f633d6d
Removed old comments
nicktrem 0d2408c
Simplified for first part of the PR
nicktrem 4eacfa2
Merge branch 'main' into rtCapabilitiesP1Visualizer
nicktrem 296ee38
Changed to account for python bindings
nicktrem d8b573b
Changed variable name
nicktrem ecdf600
Fixed merge
nicktrem 059c6d6
Changed function names to make more sense
nicktrem a02f24e
Merge branch 'main' into rtCapabilitiesP1Visualizer
nicktrem 621ce36
Rebased for recent changes
nicktrem b98edec
Removed print statements
nicktrem 221711a
Removed whitespace
nicktrem 49880bf
Edited to only clear plot if rt is enabled
nicktrem 8cb0209
Removed prints, moved some prints to integrated console screen
nicktrem 989426c
Removed unused function
nicktrem 40f406b
Removed unused variables/imports
nicktrem fa4282f
Fixed bug with text logging
nicktrem 0b033ba
Converted to snake_case
nicktrem f8b88fa
Added exception for if BLF is not installed
nicktrem 59953ef
Fixed bug regarding naming
nicktrem ad96b95
Fixed small bug with the grid
nicktrem 76b3129
Updated to support latest python binding for vectors collection
nicktrem 767c83c
Fixed bug displaying data offline
nicktrem 2cc7277
Added better exception handling
nicktrem f5b4a65
Removed unused icon
nicktrem be77f98
Added gui changes to the visualizer.ui
nicktrem 5df2f88
updates to autogenerated files from qt creator
nicktrem File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,10 @@ | |
import idyntree.swig as idyn | ||
|
||
|
||
# for real-time logging | ||
import yarp | ||
|
||
|
||
class TextLoggingMsg: | ||
def __init__(self, level, text): | ||
self.level = level | ||
|
@@ -35,6 +39,13 @@ class SignalProvider(QThread): | |
def __init__(self, period: float): | ||
QThread.__init__(self) | ||
|
||
self.blfInstalled = True | ||
try: | ||
import bipedal_locomotion_framework.bindings as blf | ||
self.blf = blf | ||
except ImportError: | ||
self.blfInstalled = False | ||
|
||
# set device state | ||
self._state = PeriodicThreadState.pause | ||
self.state_lock = QMutex() | ||
|
@@ -67,7 +78,16 @@ def __init__(self, period: float): | |
|
||
self._current_time = 0 | ||
|
||
self.realtimeBufferReached = False | ||
nicktrem marked this conversation as resolved.
Show resolved
Hide resolved
|
||
self.initMetadata = False | ||
self.realtime_fixed_plot_window = 20 | ||
|
||
# for networking with the real-time logger | ||
self.realtime_network_init = False | ||
if self.blfInstalled: | ||
self.vector_collections_client = blf.yarp_utilities.VectorsCollectionClient() | ||
self.trajectory_span = 200 | ||
self.rt_metadata_dict = {} | ||
|
||
def __populate_text_logging_data(self, file_object): | ||
data = {} | ||
|
@@ -145,11 +165,103 @@ def __populate_numerical_data(self, file_object): | |
"".join(chr(c[0]) for c in value[ref]) | ||
for ref in elements_names_ref[0] | ||
] | ||
|
||
else: | ||
data[key] = self.__populate_numerical_data(file_object=value) | ||
|
||
return data | ||
|
||
def __populate_realtime_logger_data(self, raw_data, keys, value, recent_timestamp): | ||
if keys[0] not in raw_data: | ||
raw_data[keys[0]] = {} | ||
|
||
if len(keys) == 1: | ||
raw_data[keys[0]]["data"] = np.append(raw_data[keys[0]]["data"], value).reshape(-1, len(value)) | ||
raw_data[keys[0]]["timestamps"] = np.append(raw_data[keys[0]]["timestamps"], recent_timestamp) | ||
|
||
temp_initial_time = raw_data[keys[0]]["timestamps"][0] | ||
temp_end_time = raw_data[keys[0]]["timestamps"][-1] | ||
while temp_end_time - temp_initial_time > self.realtime_fixed_plot_window: | ||
raw_data[keys[0]]["data"] = np.delete(raw_data[keys[0]]["data"], 0, axis=0) | ||
raw_data[keys[0]]["timestamps"] = np.delete(raw_data[keys[0]]["timestamps"], 0) | ||
temp_initial_time = raw_data[keys[0]]["timestamps"][0] | ||
temp_end_time = raw_data[keys[0]]["timestamps"][-1] | ||
|
||
else: | ||
self.__populate_realtime_logger_data(raw_data[keys[0]], keys[1:], value, recent_timestamp) | ||
|
||
def __populate_realtime_logger_metadata(self, raw_data, keys, value): | ||
if keys[0] == "timestamps": | ||
return | ||
if keys[0] not in raw_data: | ||
raw_data[keys[0]] = {} | ||
|
||
if len(keys) == 1: | ||
if len(value) == 0: | ||
del raw_data[keys[0]] | ||
return | ||
if "elements_names" not in raw_data[keys[0]]: | ||
raw_data[keys[0]]["elements_names"] = np.array([]) | ||
raw_data[keys[0]]["data"] = np.array([]) | ||
raw_data[keys[0]]["timestamps"] = np.array([]) | ||
|
||
raw_data[keys[0]]["elements_names"] = np.append(raw_data[keys[0]]["elements_names"], value) | ||
else: | ||
self.__populate_realtime_logger_metadata(raw_data[keys[0]], keys[1:], value) | ||
|
||
|
||
def maintain_connection(self): | ||
if not self.realtime_network_init: | ||
yarp.Network.init() | ||
|
||
param_handler = self.blf.parameters_handler.YarpParametersHandler() | ||
param_handler.set_parameter_string("remote", "/rtLoggingVectorCollections") # you must have some local port as well | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the remote should be set from the gui perhaps this can be the default value |
||
param_handler.set_parameter_string("local", "/visualizerInput") # remote must match the server | ||
param_handler.set_parameter_string("carrier", "udp") | ||
self.vector_collections_client.initialize(param_handler) | ||
|
||
self.vector_collections_client.connect() | ||
try: | ||
self.rt_metadata_dict = self.vector_collections_client.get_metadata().vectors | ||
except ValueError: | ||
print("Error in retreiving the metadata from the logger") | ||
print("Check if the logger is running and configured for realtime connection") | ||
return False | ||
|
||
self.realtime_network_init = True | ||
self.joints_name = self.rt_metadata_dict["robot_realtime::description_list"] | ||
self.robot_name = self.rt_metadata_dict["robot_realtime::yarp_robot_name"][0] | ||
for key_string, value in self.rt_metadata_dict.items(): | ||
keys = key_string.split("::") | ||
self.__populate_realtime_logger_metadata(self.data, keys, value) | ||
del self.data["robot_realtime"]["description_list"] | ||
del self.data["robot_realtime"]["yarp_robot_name"] | ||
|
||
vc_input = self.vector_collections_client.read_data(True).vectors | ||
|
||
if not vc_input: | ||
return False | ||
else: | ||
# Update the timestamps | ||
recent_timestamp = vc_input["robot_realtime::timestamps"][0] | ||
self.timestamps = np.append(self.timestamps, recent_timestamp).reshape(-1) | ||
del vc_input["robot_realtime::timestamps"] | ||
|
||
# Keep the data within the fixed time interval | ||
while recent_timestamp - self.timestamps[0] > self.realtime_fixed_plot_window: | ||
self.initial_time = self.timestamps[0] | ||
self.end_time = self.timestamps[-1] | ||
self.timestamps = np.delete(self.timestamps, 0).reshape(-1) | ||
self.initial_time = self.timestamps[0] | ||
self.end_time = self.timestamps[-1] | ||
|
||
# Store the new data that comes in | ||
for key_string, value in vc_input.items(): | ||
keys = key_string.split("::") | ||
self.__populate_realtime_logger_data(self.data, keys, value, recent_timestamp) | ||
|
||
return True | ||
|
||
def open_mat_file(self, file_name: str): | ||
with h5py.File(file_name, "r") as file: | ||
root_variable = file.get(self.root_name) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ | |
# Released under the terms of the BSD 3-Clause License | ||
|
||
# PyQt | ||
import numpy as np | ||
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas | ||
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar | ||
from matplotlib.figure import Figure | ||
|
@@ -184,30 +185,43 @@ def on_pick(self, event): | |
blit=True, | ||
) | ||
|
||
def update_plots(self, paths, legends): | ||
def update_plots(self, paths, legends, realtime_plot): | ||
self.axes.cla() | ||
nicktrem marked this conversation as resolved.
Show resolved
Hide resolved
|
||
colorIndex = 0 | ||
for path, legend in zip(paths, legends): | ||
path_string = "/".join(path) | ||
legend_string = "/".join(legend[1:]) | ||
|
||
if path_string not in self.active_paths.keys(): | ||
data = self.signal_provider.data | ||
for key in path[:-1]: | ||
data = data[key] | ||
try: | ||
datapoints = data["data"][:, int(path[-1])] | ||
except IndexError: | ||
# This happens in the case the variable is a scalar. | ||
datapoints = data["data"][:] | ||
data = self.signal_provider.data.copy() | ||
for key in path[:-1]: | ||
data = data[key] | ||
try: | ||
datapoints = data["data"][:, int(path[-1])] | ||
except IndexError: | ||
# This happens in the case the variable is a scalar. | ||
datapoints = data["data"][:] | ||
|
||
timestamps = data["timestamps"] - self.signal_provider.initial_time | ||
timestamps = data["timestamps"] - self.signal_provider.initial_time | ||
|
||
if realtime_plot: | ||
(self.active_paths[path_string],) = self.axes.plot( | ||
timestamps, | ||
datapoints, | ||
label=legend_string, | ||
picker=True, | ||
color=next(self.color_palette), | ||
color=self.color_palette.get_color(colorIndex), | ||
) | ||
colorIndex = colorIndex + 1 | ||
else: | ||
(self.active_paths[path_string],) = self.axes.plot( | ||
timestamps, | ||
datapoints, | ||
label=legend_string, | ||
picker=True, | ||
color=self.color_palette.get_color(colorIndex), | ||
) | ||
colorIndex = colorIndex + 1 | ||
|
||
|
||
paths_to_be_canceled = [] | ||
for active_path in self.active_paths.keys(): | ||
|
@@ -220,14 +234,20 @@ def update_plots(self, paths, legends): | |
self.active_paths[path].remove() | ||
self.active_paths.pop(path) | ||
|
||
self.axes.set_xlim( | ||
0, self.signal_provider.end_time - self.signal_provider.initial_time | ||
) | ||
if realtime_plot: | ||
#self.axes.autoscale() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If this is not needed we can remove it. |
||
self.axes.set_xlim(0, self.signal_provider.realtime_fixed_plot_window) | ||
else: | ||
self.axes.set_xlim( | ||
0, self.signal_provider.end_time - self.signal_provider.initial_time | ||
) | ||
|
||
# Since a new plot has been added/removed we delete the old animation and we create a new one | ||
# TODO: this part could be optimized | ||
|
||
self.vertical_line_anim._stop() | ||
self.axes.legend() | ||
self.axes.grid(True) | ||
|
||
if not self.frame_legend: | ||
self.frame_legend = self.axes.legend().get_frame() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@GiulioRomualdi should we lazy load also yarp or we just need to lazy load blf?
fyi @nicktrem