Skip to content

Commit

Permalink
GUI development continues...
Browse files Browse the repository at this point in the history
  • Loading branch information
samyarsadat committed Sep 19, 2024
1 parent 781fc87 commit 0e2ccaf
Show file tree
Hide file tree
Showing 25 changed files with 9,465 additions and 9,031 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
url = https://github.com/micro-ROS/micro_ros_setup
branch = humble
ignore = all

# THIS IS TEMPORARY! IT WILL BE REMOVED!
[submodule "The ROS Robot Project"]
path = Source Code/ros_robot_project
url = https://github.com/samyarsadat/ROS-Robot
branch = stage-1
ignore = all
3 changes: 2 additions & 1 deletion Source Code/ros_ws_remote/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@
},

"workspaceFolder": "/home/nonroot/ros_ws",
//"mounts": [{"source": "${localWorkspaceFolder}", "target": "/home/nonroot/ros_ws", "type": "bind"}],
"mounts": [{"source": "${localWorkspaceFolder}/../ros_robot_project/Source Code/ros_ws_robot/src/ros_robot_msgs",
"target": "/home/nonroot/ros_ws/src/ros_robot_msgs", "type": "bind"}],

"runArgs": ["--net=host",
"--cap-add=SYS_PTRACE",
Expand Down
2 changes: 1 addition & 1 deletion Source Code/ros_ws_remote/src/ros_remote_gui/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<license>GPL-3.0-only</license>

<exec_depend>rclpy</exec_depend>
<exec_depend>python3-pyside6-pip</exec_depend>
<depend>python3-pyside6</depend>

<test_depend>ament_copyright</test_depend>
<test_depend>ament_flake8</test_depend>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# along with this program. If not, see <https: www.gnu.org/licenses/>.

PROGRAM_VERSION = "2024.8.8"
from rclpy.qos import QoSProfile, ReliabilityPolicy, HistoryPolicy, LivelinessPolicy


# ---- Program Info ----
Expand All @@ -25,15 +26,60 @@ class ProgramInfoConfig:
VERSION_DATE = "2024/08/08 @ 12:15PM UTC"


class ProgramConfig:
THREADS_LIVELINESS_CHECK_INTERVAL_S = 2
UI_DATA_UPDATE_INTERVAL_MS = 100
UI_VIEWPORT_UPDATE_INTERVAL_MS = 50


# ---- ROS Config ----
class RosConfig:
NODE_NAME = "remote_gui_node"
NODE_NAMESPACE = ""
EXECUTOR_DOMAIN_ID = None
EXECUTOR_TIMEOUT = 0.05 # 50ms
EXECUTOR_SHUTDOWN_TIMEOUT = 5 # 5s
QOS_BEST_EFFORT = QoSProfile(reliability=ReliabilityPolicy.BEST_EFFORT, history=HistoryPolicy.KEEP_LAST, depth=1, liveliness=LivelinessPolicy.AUTOMATIC)
QOS_RELIABLE = QoSProfile(reliability=ReliabilityPolicy.RELIABLE, history=HistoryPolicy.KEEP_LAST, depth=1, liveliness=LivelinessPolicy.AUTOMATIC)
THREAD_NAME = "robot_ros_thread"


class RosNames:
# Main tab
SET_CAMERA_LED_SRV_NAME = ""
ROBOT_NAMESPACE = "ros_robot"

DIAGNOSTICS_TOPIC = f"{ROBOT_NAMESPACE}/diagnostics"
ENABLE_RELAY_SRV = f"{ROBOT_NAMESPACE}/enable/set_relay"
BATTERY_INFO_TOPIC = f"{ROBOT_NAMESPACE}/electrical/battery_state"
ENCODER_ODOM_TOPIC = f"{ROBOT_NAMESPACE}/pos_data/encoder_odom"
SET_CAMERA_LEDS_SRV = f"{ROBOT_NAMESPACE}/lights/camera/set"
GET_CAMERA_LEDS_SRV = f"{ROBOT_NAMESPACE}/lights/camera/get"
IMU_SENS_TOPIC = f"{ROBOT_NAMESPACE}/pos_data/imu"
ENV_TEMP_SENS_TOPIC = f"{ROBOT_NAMESPACE}/env_sensors/temp"
ENV_HUMIDITY_SENS_TOPIC = f"{ROBOT_NAMESPACE}/env_sensors/humidity"
EMERGENCY_STOP_TOPIC = f"{ROBOT_NAMESPACE}/emergency_stop"
PICO_A_CPU_TEMP_TOPIC = f"{ROBOT_NAMESPACE}/sys_temps/processor/pico_a"
PICO_B_CPU_TEMP_TOPIC = f"{ROBOT_NAMESPACE}/sys_temps/processor/pico_b"
PICO_A_SELFTEST_SRV = f"{ROBOT_NAMESPACE}/self_test/run_pico_a_routines"
PICO_B_SELFTEST_SRV = f"{ROBOT_NAMESPACE}/self_test/run_pico_b_routines"
PICO_A_CALIBRATE_SRV = f"{ROBOT_NAMESPACE}/calibrate/run_pico_a_routines"
ENABLE_EMITTERS_SRV = f"{ROBOT_NAMESPACE}/enable/set_emitters"
GET_EMITTERS_ENABLED_SRV = f"{ROBOT_NAMESPACE}/enable/get_emitters"
LEFT_MTR_CTRL_TOPIC = f"{ROBOT_NAMESPACE}/motors/controllers/left_state"
RIGHT_MTR_CTRL_TOPIC = f"{ROBOT_NAMESPACE}/motors/controllers/right_state"
MTR_CTRL_ENABLE_SRV = f"{ROBOT_NAMESPACE}/motors/controllers/enable"
MTR_CTRL_SET_PID_SRV = f"{ROBOT_NAMESPACE}/motors/controllers/set_pid"

MICRO_SWITCH_TOPIC_BASE = ROBOT_NAMESPACE + "/range_sens/micro_switch/{}"
MICRO_SWITCH_TOPIC_NAMES = ["front_right", "front_left", "back_right", "back_left"]

ULTRASONIC_SENS_TOPIC_BASE = ROBOT_NAMESPACE + "/range_sens/ultrasonic/{}"
ULTRASONIC_SENS_TOPIC_NAMES = ["front", "back", "right", "left"]

CLIFF_SENS_TOPIC_BASE = ROBOT_NAMESPACE + "/range_base/cliff/{}"
CLIFF_SENS_TOPIC_NAMES = ["front_1", "front_2", "front_3", "front_4", "back_1", "back_2", "back_3", "back_4"]


class RosFrameIds:
CLIFF_SENS_BASE_FRAME_ID = "cliff_sens_{}"
ULTRASONIC_SENS_BASE_FRAME_ID = "ultrasonic_sens_{}"
MICRO_SW_SENS_BASE_FRAME_ID = "micro_switch_{}"
Original file line number Diff line number Diff line change
@@ -1,83 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>493</width>
<height>350</height>
</rect>
</property>
<property name="windowTitle">
<string>About</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_1">
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
li.unchecked::marker { content: &quot;\2610&quot;; }
li.checked::marker { content: &quot;\2612&quot;; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:14pt; font-weight:700; font-style:italic;&quot;&gt;The ROS Remote Project&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:11pt; font-style:italic;&quot;&gt;Created by Samyar Sadat Akhavi, 2024&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:11pt; font-style:italic;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;User interface created using QT and PySide6.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;PySide6 Version: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{pyside_version}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;QT Version: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{qt_version}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;Interface Version: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{version}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;Creation Date: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{date}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;mailto:[email protected]&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; text-decoration: underline; color:#007af4;&quot;&gt;[email protected]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://github.com/samyarsadat/ROS-Remote&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; text-decoration: underline; color:#007af4;&quot;&gt;github.com/samyarsadat/ROS-Remote&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:11pt; text-decoration: underline; color:#007af4;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-style:italic;&quot;&gt;Copyright (c) 2024, Samyar Sadat Akhavi.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-style:italic;&quot;&gt;Licensed under the General Public License V3.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>493</width>
<height>350</height>
</rect>
</property>
<property name="windowTitle">
<string>About</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_1">
<item>
<widget class="QTextBrowser" name="textBrowser">
<property name="frameShape">
<enum>QFrame::Shape::StyledPanel</enum>
</property>
<property name="html">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;meta charset=&quot;utf-8&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
hr { height: 1px; border-width: 0; }
li.unchecked::marker { content: &quot;\2610&quot;; }
li.checked::marker { content: &quot;\2612&quot;; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:14pt; font-weight:700; font-style:italic;&quot;&gt;The ROS Remote Project&lt;/span&gt;&lt;/p&gt;
&lt;p align=&quot;center&quot; style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:11pt; font-style:italic;&quot;&gt;Created by Samyar Sadat Akhavi, 2024&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:11pt; font-style:italic;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:11pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;User interface created using QT and PySide6.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;PySide6 Version: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{pyside_version}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;QT Version: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{qt_version}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;Interface Version: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{version}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-weight:700;&quot;&gt;Creation Date: &lt;/span&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;{date}&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;mailto:[email protected]&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; text-decoration: underline; color:#007af4;&quot;&gt;[email protected]&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;https://github.com/samyarsadat/ROS-Remote&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; text-decoration: underline; color:#007af4;&quot;&gt;github.com/samyarsadat/ROS-Remote&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Ubuntu Sans'; font-size:11pt; text-decoration: underline; color:#007af4;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-style:italic;&quot;&gt;Copyright (c) 2024, Samyar Sadat Akhavi.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Ubuntu Sans'; font-size:10pt; font-style:italic;&quot;&gt;Licensed under the General Public License V3.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Orientation::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::StandardButton::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Loading

0 comments on commit 0e2ccaf

Please sign in to comment.