Skip to content
This repository has been archived by the owner on Jul 24, 2018. It is now read-only.

Commit

Permalink
Added diagnostics GUI
Browse files Browse the repository at this point in the history
  • Loading branch information
rbtying committed Jan 20, 2012
1 parent f705e46 commit 6bb6c5e
Show file tree
Hide file tree
Showing 12 changed files with 221 additions and 20 deletions.
6 changes: 3 additions & 3 deletions rover/build/CMakeCache.txt
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ CMAKE_SKIP_RPATH:BOOL=NO
//Path to a program.
CMAKE_STRIP:FILEPATH=/usr/bin/strip

//The CMake toolchain file
CMAKE_TOOLCHAIN_FILE:FILEPATH=/opt/ros/electric/ros/core/rosbuild/rostoolchain.cmake
//No help, variable specified on the command line.
CMAKE_TOOLCHAIN_FILE:UNINITIALIZED=/opt/ros/electric/ros/core/rosbuild/rostoolchain.cmake

//If true, cmake will use relative paths in makefiles and projects.
CMAKE_USE_RELATIVE_PATHS:BOOL=OFF
Expand Down Expand Up @@ -322,7 +322,7 @@ CMAKE_USE_RELATIVE_PATHS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
_rosbuild_EXPORTS:INTERNAL=
_rosbuild_cached_flag_time:INTERNAL=1326853074.76
_rosbuild_cached_flag_time:INTERNAL=1327043082.26
_roslang_LANGS:INTERNAL=roslisp;rospy;roscpp
_rospack_deps_manifests_invoke_result:INTERNAL=/opt/ros/electric/ros/core/rosbuild/manifest.xml;/opt/ros/electric/ros/core/roslang/manifest.xml;/opt/ros/electric/stacks/ros_comm/utilities/cpp_common/manifest.xml;/opt/ros/electric/stacks/ros_comm/clients/cpp/roscpp_traits/manifest.xml;/opt/ros/electric/stacks/ros_comm/utilities/rostime/manifest.xml;/opt/ros/electric/stacks/ros_comm/clients/cpp/roscpp_serialization/manifest.xml;/opt/ros/electric/ros/tools/rospack/manifest.xml;/opt/ros/electric/ros/core/roslib/manifest.xml;/opt/ros/electric/stacks/ros_comm/utilities/xmlrpcpp/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosconsole/manifest.xml;/opt/ros/electric/stacks/ros_comm/messages/std_msgs/manifest.xml;/opt/ros/electric/stacks/ros_comm/messages/rosgraph_msgs/manifest.xml;/opt/ros/electric/stacks/ros_comm/clients/cpp/roscpp/manifest.xml;/opt/ros/electric/stacks/ros_comm/clients/rospy/manifest.xml;/opt/ros/electric/ros/tools/rosclean/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosgraph/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosparam/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosmaster/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosout/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/roslaunch/manifest.xml;/opt/ros/electric/ros/tools/rosunit/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rostest/manifest.xml;/opt/ros/electric/stacks/common_msgs/actionlib_msgs/manifest.xml;/opt/ros/electric/stacks/common/actionlib/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/topic_tools/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosbag/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosbagmigration/manifest.xml;/opt/ros/electric/stacks/common_msgs/geometry_msgs/manifest.xml;/opt/ros/electric/stacks/common_msgs/sensor_msgs/manifest.xml;/opt/ros/electric/stacks/bullet/manifest.xml;/opt/ros/electric/stacks/geometry/angles/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosnode/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosmsg/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rostopic/manifest.xml;/opt/ros/electric/stacks/ros_comm/tools/rosservice/manifest.xml;/opt/ros/electric/stacks/ros_comm/utilities/roswtf/manifest.xml;/opt/ros/electric/stacks/ros_comm/utilities/message_filters/manifest.xml;/opt/ros/electric/stacks/geometry/tf/manifest.xml;/opt/ros/electric/stacks/common_msgs/nav_msgs/manifest.xml;/home/rbtying/robot/cereal_port/manifest.xml;/opt/ros/electric/stacks/joystick_drivers/ps3joy/manifest.xml
_rospack_msgsrv_gen_invoke_result:INTERNAL=/opt/ros/electric/stacks/ros_comm/messages/std_msgs/msg_gen/generated;/opt/ros/electric/stacks/ros_comm/messages/rosgraph_msgs/msg_gen/generated;/opt/ros/electric/stacks/ros_comm/clients/cpp/roscpp/msg_gen/generated;/opt/ros/electric/stacks/ros_comm/clients/cpp/roscpp/srv_gen/generated;/opt/ros/electric/stacks/common_msgs/actionlib_msgs/msg_gen/generated;/opt/ros/electric/stacks/common/actionlib/msg_gen/generated;/opt/ros/electric/stacks/ros_comm/tools/topic_tools/srv_gen/generated;/opt/ros/electric/stacks/common_msgs/geometry_msgs/msg_gen/generated;/opt/ros/electric/stacks/common_msgs/sensor_msgs/msg_gen/generated;/opt/ros/electric/stacks/common_msgs/sensor_msgs/srv_gen/generated;/opt/ros/electric/stacks/geometry/tf/msg_gen/generated;/opt/ros/electric/stacks/geometry/tf/srv_gen/generated;/opt/ros/electric/stacks/common_msgs/nav_msgs/msg_gen/generated;/opt/ros/electric/stacks/common_msgs/nav_msgs/srv_gen/generated
Expand Down
16 changes: 0 additions & 16 deletions rover/build/CMakeFiles/Makefile.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,11 @@ SET(CMAKE_MAKEFILE_DEPENDS
"/opt/ros/electric/stacks/ros_comm/clients/roslisp/cmake/roslisp.cmake"
"/opt/ros/electric/stacks/ros_comm/clients/rospy/cmake/rospy.cmake"
"/usr/share/cmake-2.8/Modules/AddFileDependencies.cmake"
"/usr/share/cmake-2.8/Modules/CMakeCCompiler.cmake.in"
"/usr/share/cmake-2.8/Modules/CMakeCCompilerABI.c"
"/usr/share/cmake-2.8/Modules/CMakeCInformation.cmake"
"/usr/share/cmake-2.8/Modules/CMakeCXXCompiler.cmake.in"
"/usr/share/cmake-2.8/Modules/CMakeCXXCompilerABI.cpp"
"/usr/share/cmake-2.8/Modules/CMakeCXXInformation.cmake"
"/usr/share/cmake-2.8/Modules/CMakeCommonLanguageInclude.cmake"
"/usr/share/cmake-2.8/Modules/CMakeDetermineCCompiler.cmake"
"/usr/share/cmake-2.8/Modules/CMakeDetermineCXXCompiler.cmake"
"/usr/share/cmake-2.8/Modules/CMakeDetermineCompilerABI.cmake"
"/usr/share/cmake-2.8/Modules/CMakeDetermineCompilerId.cmake"
"/usr/share/cmake-2.8/Modules/CMakeDetermineSystem.cmake"
"/usr/share/cmake-2.8/Modules/CMakeFindBinUtils.cmake"
"/usr/share/cmake-2.8/Modules/CMakeGenericSystem.cmake"
"/usr/share/cmake-2.8/Modules/CMakeParseImplicitLinkInfo.cmake"
"/usr/share/cmake-2.8/Modules/CMakeSystem.cmake.in"
"/usr/share/cmake-2.8/Modules/CMakeSystemSpecificInformation.cmake"
"/usr/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake"
"/usr/share/cmake-2.8/Modules/CMakeTestCXXCompiler.cmake"
"/usr/share/cmake-2.8/Modules/CMakeTestCompilerCommon.cmake"
"/usr/share/cmake-2.8/Modules/CMakeUnixFindMake.cmake"
"/usr/share/cmake-2.8/Modules/CheckCXXCompilerFlag.cmake"
"/usr/share/cmake-2.8/Modules/CheckCXXSourceCompiles.cmake"
"/usr/share/cmake-2.8/Modules/CheckFunctionExists.cmake"
Expand Down
3 changes: 2 additions & 1 deletion rover/manifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
Movement and odometry for a rover-bot.

</description>
<author></author>
<author>Robert Ying</author>
<license>GPL</license>
<review status="unreviewed" notes=""/>
<url></url>
<export>
<cpp cflags="-I${prefix}/include" lflags="-L${prefix}/lib -Wl,-rpath,${prefix}/lib"/>
</export>
<depend package="roscpp"/>
<depend package="rospy"/>
<depend package="actionlib"/>
<depend package="actionlib_msgs"/>
<depend package="tf"/>
Expand Down
Binary file modified rover/src/rover/__init__.pyc
Binary file not shown.
Binary file modified rover/src/rover/msg/_Battery.pyc
Binary file not shown.
Binary file modified rover/src/rover/msg/_Enabled.pyc
Binary file not shown.
Binary file modified rover/src/rover/msg/_Encoder.pyc
Binary file not shown.
Binary file modified rover/src/rover/msg/_Gyro.pyc
Binary file not shown.
Binary file modified rover/src/rover/msg/_Motors.pyc
Binary file not shown.
Binary file modified rover/src/rover/msg/_Settings.pyc
Binary file not shown.
Binary file modified rover/src/rover/msg/__init__.pyc
Binary file not shown.
216 changes: 216 additions & 0 deletions rover/src/rover_gui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#!/usr/bin/env python

# import wxpython GUI libraries
import wx

# import system utilities module
import psutil

# import general utilities
import re

# import ROS
import roslib; roslib.load_manifest('rover')
import rospy
from rover.msg import Enabled, Battery, Encoder

class GUIWindow(wx.Frame):
ID_ROS_TIMER = 1
ID_SYS_TIMER = 2
leftvel = 0.0
rightvel = 0.0
leftcount = 0.0
rightcount = 0.0
voltage = 0.0
current = 0.0
isenabled = False

def __init__(self, *args, **kwargs):
super(GUIWindow, self).__init__(*args, **kwargs)
rospy.init_node('rover_gui', anonymous = True)
rospy.Subscriber('enabled', Enabled, self.enablecb)
rospy.Subscriber('encoders', Encoder, self.enccb)
rospy.Subscriber('battery/motor', Battery, self.battcb)
self.enablepub = rospy.Publisher('enable', Enabled, latch = True)
self.initUI()
self.initTimerLoop()

def initTimerLoop(self):
self.rostimer = wx.Timer(self, GUIWindow.ID_ROS_TIMER)
self.rostimer.Start(1000/30) # 30 Hz
self.Bind(wx.EVT_TIMER, self.onROSTimerFire, id = GUIWindow.ID_ROS_TIMER)
self.systemtimer = wx.Timer(self, GUIWindow.ID_SYS_TIMER)
self.systemtimer.Start(1000/4) # 4 Hz
self.Bind(wx.EVT_TIMER, self.onSystemTimerFire, id = GUIWindow.ID_SYS_TIMER)

def onROSTimerFire(self, e):
self.encoder_speed_label.SetLabel("Encoder Velocities: [ %.04f m/s, %.04f m/s ]" % (self.leftvel, self.rightvel))
self.encoder_count_label.SetLabel("Encoder Counts: [ %d, %d ]" % (self.leftcount, self.rightcount))
self.motor_battery_label.SetLabel("Motor Battery: %.02f volts, %.02f amperes" % (self.voltage, self.current))

self.enable_toggle.SetValue(self.isenabled)

if self.enable_toggle.GetValue():
self.enable_toggle.SetLabel('Disable')
else:
self.enable_toggle.SetLabel('Enable')


def enablecb(self, msg):
self.isenabled = msg.motorsEnabled

def enccb(self, msg):
self.leftvel = msg.left
self.rightvel = msg.right
self.leftcount = msg.leftCount
self.rightcount = msg.rightCount

def battcb(self, msg):
self.voltage = msg.voltage
self.current = msg.current

def onSystemTimerFire(self, e):
# update CPU
self.cpu_usage = psutil.cpu_percent()
self.cpu_gauge.SetValue(self.cpu_usage)
self.cpu_label.SetLabel("CPU Usage: %d%%" % self.cpu_usage)

# update RAM
self.ram_usage = psutil.phymem_usage().percent
self.ram_gauge.SetValue(self.ram_usage)
self.ram_label.SetLabel("RAM Usage: %d%%" % self.ram_usage)

# update battery
remaining_capacity_re = re.compile(r'^remaining capacity:\W+(\d+) mAh')
full_capacity_re = re.compile(r'^design capacity:\W+(\d+) mAh')

b_state_file = open('/proc/acpi/battery/BAT0/state', 'r')
b_state = b_state_file.readlines()
b_state_file.close()

for line in b_state:
m = remaining_capacity_re.match(line)
if m:
self.main_battery_remaining_capacity = float(m.group(1))


b_info_file = open('/proc/acpi/battery/BAT0/info', 'r')
b_info = b_info_file.readlines()
b_info_file.close()

for line in b_info:
m = full_capacity_re.match(line)
if m:
self.main_battery_full_capacity = float(m.group(1))
self.main_battery_remaining = (100 * self.main_battery_remaining_capacity/self.main_battery_full_capacity)
self.main_battery_label.SetLabel("Main Battery Remaining: %d%%" % self.main_battery_remaining)

def initUI(self):
self.initMenus()
self.initSizers()
self.SetSize((400, 300))
self.SetMinSize((400, 390))
self.SetMaxSize((400, 390))
self.SetTitle('Rover Status')
self.Centre()
self.Show(True)

def initSizers(self):
panel = wx.Panel(self)
font = wx.SystemSettings_GetFont(wx.SYS_SYSTEM_FONT)

vbox = wx.BoxSizer(wx.VERTICAL)
hbox1 = wx.BoxSizer(wx.HORIZONTAL)

# system runtime information
systembox = wx.BoxSizer(wx.VERTICAL)

sbox = wx.StaticBox(panel, -1, 'System Information', (10, 10), size=(380, 185))
self.cpu_label = wx.StaticText(panel, label = "CPU Usage: 0%")
self.cpu_gauge = wx.Gauge(panel, -1, 100, (-1, -1), (360, 10), wx.GA_HORIZONTAL | wx.GA_SMOOTH)

self.ram_label = wx.StaticText(panel, label = "RAM Usage: 0%")
self.ram_gauge = wx.Gauge(panel, -1, 100, (-1, -1), (360, 10), wx.GA_HORIZONTAL | wx.GA_SMOOTH)

self.motor_battery_label = wx.StaticText(panel, label = "Motor Battery: 0 volts, 0 amperes")
self.main_battery_label = wx.StaticText(panel, label = "Main Battery Remaining: 0%")

systembox.Add(self.cpu_label, 1, wx.ALIGN_TOP | wx.ALIGN_LEFT | wx.BOTTOM, 5)
systembox.Add(self.cpu_gauge, 1, wx.ALIGN_TOP | wx.BOTTOM, 5)
systembox.Add(self.ram_label, 1, wx.ALIGN_LEFT | wx.BOTTOM, 5)
systembox.Add(self.ram_gauge, 1, wx.BOTTOM, 5)
systembox.Add(wx.StaticLine(panel, -1, (-1, -1), (360, 2)), 1, wx.TOP | wx.BOTTOM)
systembox.Add(self.motor_battery_label, 1)
systembox.Add(self.main_battery_label, 1)
hbox1.Add(systembox, 1, wx.ALIGN_LEFT)

vbox.Add((0, 35), 0)
vbox.Add(hbox1, 0, wx.ALIGN_CENTRE)

# rover-specific information
sbox2 = wx.StaticBox(panel, -1, 'Robot Information', (10, 200), size=(380, 160))
enabled_label = wx.StaticText(panel, label = "Robot state:")
self.enable_toggle = wx.ToggleButton(panel, 1, 'Enable', (-1, -1))
self.Bind(wx.EVT_TOGGLEBUTTON, self.onToggleEnable, id = 1)

vbox2 = wx.BoxSizer(wx.VERTICAL)
vbox2.Add(enabled_label, 1)
vbox2.Add(self.enable_toggle, 1)
vbox2.Add((0, 15), 0)

self.encoder_speed_label = wx.StaticText(panel, label = "Encoder Velocities: [ 0.00 m/s, 0.00 m/s ]")
self.encoder_count_label = wx.StaticText(panel, label = "Encoder Counts: [ 0, 0 ]")
vbox2.Add(self.encoder_speed_label)
vbox2.Add((0, 15), 0)
vbox2.Add(self.encoder_count_label)
vbox2.Add((0, 15), 0)

hbox2 = wx.BoxSizer(wx.HORIZONTAL)
hbox2.Add((20, 0), 0)
hbox2.Add(vbox2, wx.LEFT | wx.RIGHT, 20)

vbox.Add((0, 35), 0)
vbox.Add(hbox2, wx.ALIGN_TOP)

# set the sizer
panel.SetSizer(vbox)

def initMenus(self):
menubar = wx.MenuBar()

# file menu
fileMenu = wx.Menu()
closeItem = fileMenu.Append(wx.ID_EXIT, 'Quit', 'Quit application', kind = wx.ITEM_NORMAL)
self.Bind(wx.EVT_MENU, self.onQuit, closeItem)
menubar.Append(fileMenu, '&File')

# about menu
aboutMenu = wx.Menu()
aboutItem = aboutMenu.Append(wx.ID_ABOUT, 'About', 'About this program', kind = wx.ITEM_NORMAL)
self.Bind(wx.EVT_MENU, self.onAbout, aboutItem)
menubar.Append(aboutMenu, '&Help')

self.SetMenuBar(menubar)

def onToggleEnable(self, e):
msg = Enabled()
msg.motorsEnabled = self.enable_toggle.GetValue()
msg.settingsDumpEnabled = False
self.enablepub.publish(msg)

def onAbout(self, e):
aboutText = "Rover status indicator by Robert Ying"
dlg = wx.MessageDialog(self, aboutText, "", wx.OK)
dlg.ShowModal()
dlg.Destroy()

def onQuit(self, e):
self.Close()

if __name__ == '__main__':
try:
app = wx.App() # create a new app
GUIWindow(None) # create a GUIWindow
app.MainLoop() # run the main event loop
except rospy.ROSInterruptException:
pass

0 comments on commit 6bb6c5e

Please sign in to comment.