Skip to content
This repository has been archived by the owner on Dec 1, 2020. It is now read-only.

Fix: move rqt software check #30

Merged
merged 3 commits into from
Mar 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ application-package-names =
march_rqt_gait_selection,
march_rqt_input_device,
march_rqt_note_taker,
march_rqt_software_check,
march_shared_classes,
march_shared_resources
import-order-style = appnexus
Expand Down
19 changes: 19 additions & 0 deletions march_rqt_software_check/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
cmake_minimum_required(VERSION 2.8.3)
project(march_rqt_software_check)

find_package(catkin REQUIRED)

catkin_python_setup()
catkin_package()

install(FILES plugin.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

install(DIRECTORY launch resource
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

install(PROGRAMS scripts/march_git_branch_check scripts/${PROJECT_NAME}
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)
5 changes: 5 additions & 0 deletions march_rqt_software_check/launch/checks/git_branch.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<launch>
<machine name="march" address="march" user="march" env-loader="/home/march/march_ws/devel/env.sh"/>

<node name="git_branch_check" pkg="march_rqt_software_check" type="march_git_branch_check" machine="march"/>
</launch>
5 changes: 5 additions & 0 deletions march_rqt_software_check/launch/checks/slave_count.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<launch>
<machine name="march" address="march" user="march" env-loader="/home/march/march_ws/devel/env.sh"/>

<node launch-prefix="ethercat_grant" name="slave_count_check" pkg="march_hardware" type="slave_count_check" machine="march"/>
</launch>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<launch>
<node name="march_rqt_software_check" pkg="march_rqt_software_check" type="march_rqt_software_check" output="screen"/>
</launch>
21 changes: 21 additions & 0 deletions march_rqt_software_check/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0"?>
<package format="2">
<name>march_rqt_software_check</name>
<version>0.0.0</version>
<description>rqt automated software checks for the March exoskeleton</description>

<maintainer email="[email protected]">Project March</maintainer>

<license>TODO</license>

<buildtool_depend>catkin</buildtool_depend>

<exec_depend>python-rospkg</exec_depend>
<exec_depend>rospy</exec_depend>
<exec_depend>rqt_gui</exec_depend>
<exec_depend>rqt_gui_py</exec_depend>

<export>
<rqt_gui plugin="${prefix}/plugin.xml"/>
</export>
</package>
12 changes: 12 additions & 0 deletions march_rqt_software_check/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<library path="src">
<class name="SoftwareCheckPlugin" type="march_rqt_software_check.software_check.SoftwareCheckPlugin" base_class_type="rqt_gui_py::Plugin">
<description>
RQT plugin to perform all software checks.
</description>
<qtgui>
<label>March Software Check</label>
<icon>resource/img/march-walking.png</icon>
<statustip>March Software Check</statustip>
</qtgui>
</class>
</library>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
143 changes: 143 additions & 0 deletions march_rqt_software_check/resource/software_check.ui
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SoftwareCheck</class>
<widget class="QWidget" name="SoftwareCheck">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1109</width>
<height>796</height>
</rect>
</property>
<property name="windowTitle">
<string>March Software Check</string>
</property>
<property name="styleSheet">
<string notr="true">QGroupBox {
border: 1px solid gray;
margin-top: 0.5em;
}

QGroupBox::title {
subcontrol-origin: margin;
left: 10px;
padding: 0 3px 0 3px;
}</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1">
<widget class="QFrame" name="Settings">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="Log">
<property name="enabled">
<bool>false</bool>
</property>
<property name="autoFillBackground">
<bool>false</bool>
</property>
<property name="styleSheet">
<string notr="true">#Log {
background-color: #F2F1F0
}</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="0" column="0">
<widget class="QFrame" name="Checks">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QGroupBox" name="Static">
<property name="title">
<string>Local</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QPushButton" name="GaitFileDirectory">
<property name="minimumSize">
<size>
<width>150</width>
<height>150</height>
</size>
</property>
<property name="text">
<string>Gait File Location</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="URDF">
<property name="minimumSize">
<size>
<width>150</width>
<height>150</height>
</size>
</property>
<property name="text">
<string>March IV
URDF Check</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Exoskeleton</string>
</property>
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QPushButton" name="SlaveCount">
<property name="minimumSize">
<size>
<width>150</width>
<height>150</height>
</size>
</property>
<property name="text">
<string>Slave Count</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="GitBranch">
<property name="minimumSize">
<size>
<width>150</width>
<height>150</height>
</size>
</property>
<property name="text">
<string>Git Branch</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
22 changes: 22 additions & 0 deletions march_rqt_software_check/scripts/march_git_branch_check
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python
import os

from pygit2 import Repository, GitError
import rospkg
import rospy

result = []

march_launch_path = rospkg.RosPack().get_path("march_launch")
head = os.path.split(march_launch_path)[0]
source_path = os.path.split(head)[0]

for repository_name in os.listdir(source_path):
repository_path = os.path.join(source_path, repository_name)
try:
branch_name = Repository(repository_path).head.shorthand
result.append([repository_name, branch_name])
except GitError as e:
pass

rospy.set_param("/checks/git_branch", result)
9 changes: 9 additions & 0 deletions march_rqt_software_check/scripts/march_rqt_software_check
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env python

import sys

from rqt_gui.main import Main

plugin = 'software_check'
main = Main(filename=plugin)
sys.exit(main.main(standalone=plugin))
12 changes: 12 additions & 0 deletions march_rqt_software_check/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/usr/bin/env python
from distutils.core import setup

from catkin_pkg.python_setup import generate_distutils_setup

d = generate_distutils_setup(
packages=['march_rqt_software_check', 'march_rqt_software_check.checks'],
package_dir={'': 'src'},
scripts=['scripts/march_rqt_software_check'],
)

setup(**d)
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from python_qt_binding.QtWidgets import QMessageBox
import rospy

from .checks.gait_file_directory_check import GaitFileDirectoryCheck
from .checks.git_branch_check import GitBranchCheck
from .checks.slave_count_check import SlaveCountCheck
from .checks.urdf_check import URDFCheck
from .color import Color
from .software_check_thread import SoftwareCheckThread


class CheckRunner:
def __init__(self, logger=None):
self.checks = [GitBranchCheck(), GaitFileDirectoryCheck(), URDFCheck(), SlaveCountCheck()]
for check in self.checks:
check.log_signal.connect(lambda msg, color: self.log(msg, color))
self.logger = logger
self.thread = None

def run_check_by_name(self, name):
check = self.get_check(name)
if check is None:
self.log('Check with name ' + name + ' does not exist', Color.Error)

return self.run_check(check)

def run_check(self, check):
self.log('--------------------------------------', Color.Info)

if self.thread is not None:
self.log('Already running another check', Color.Warning)

if check is None:
self.log('Check does not exist', Color.Error)
return

self.log('Starting check ' + str(check.name) + ': ' + str(check.description), Color.Info)

start = rospy.get_rostime()
self.thread = SoftwareCheckThread(check)
self.thread.start()

while not check.done:
if rospy.get_rostime() < start + rospy.Duration.from_sec(check.timeout):
rospy.sleep(0.1)

else:
self.log('Check ' + str(check.name) + ' timed out after ' + str(check.timeout) + 's', Color.Error)
self.thread.exit()
self.thread = None

check.reset()
return False

self.thread.wait()
self.thread = None
result = check.passed
if result and check.manual_confirmation:
result = self.validate_manually()
check.reset()

if result:
self.log('Check ' + str(check.name) + ' was succesful!', Color.Debug)
else:
self.log('Check ' + str(check.name) + ' has failed', Color.Error)

return result

def get_check(self, name):
for check in self.checks:
if check.name == name:
return check
return None

def log(self, msg, level):
if self.logger is not None:
self.logger(msg, level)

@staticmethod
def validate_manually():
reply = QMessageBox.question(None, 'Message', 'Did the test pass?', QMessageBox.Yes, QMessageBox.No)
return reply == QMessageBox.Yes
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import rospkg
import rospy

from march_rqt_software_check.color import Color

from .launch_check import LaunchCheck


class GaitFileDirectoryCheck(LaunchCheck):

def __init__(self):
LaunchCheck.__init__(self, 'GaitFileDirectory', 'Gaits are loaded from the following directory',
'march_gait_selection', 'march_gait_selection.launch', manual_confirmation=True)

def perform(self):
self.launch()

rospy.sleep(rospy.Duration.from_sec(5))
self.stop_launch_process()
package_name = self.get_key_from_parameter_server('/march/gait_file_package')
file_directory = self.get_key_from_parameter_server('/march/gait_file_directory')

try:
rospkg.RosPack().get_path(package_name)
except rospkg.common.ResourceNotFound:
self.log('Package ' + str(package_name) + ' not found on local machine.', Color.Error)
self.fail_check()

self.log('Package name: ' + str(package_name), Color.Info)
self.log('Gait file directory: ' + str(file_directory), Color.Info)

self.passed = package_name is not None and file_directory is not None
self.done = True
Loading