├── kobuki_qtestsuite ├── .gitignore ├── src │ └── kobuki_qtestsuite │ │ ├── detail │ │ ├── __init__.py │ │ └── .gitignore │ │ ├── __init__.py │ │ ├── ui │ │ ├── .gitignore │ │ ├── configuration_dock.ui │ │ ├── battery_profile_frame.ui │ │ ├── cliff_sensor_frame.ui │ │ ├── gyro_drift_frame.ui │ │ ├── climbing_frame.ui │ │ ├── payload_frame.ui │ │ ├── testsuite.ui │ │ ├── wandering_frame.ui │ │ └── life_frame.ui │ │ ├── resources │ │ ├── .gitignore │ │ ├── common.qrc │ │ ├── images │ │ │ └── kobuki_icon.png │ │ ├── text │ │ │ ├── life.html │ │ │ ├── gyro_drift.html │ │ │ ├── battery_profile.html │ │ │ ├── payload.html │ │ │ ├── cliff_sensor.html │ │ │ └── wandering.html │ │ └── text.qrc │ │ ├── testsuite.py │ │ ├── full_size_data_plot.py │ │ ├── configuration_dock_widget.py │ │ ├── testsuite_widget.py │ │ ├── payload_frame.py │ │ ├── wandering_frame.py │ │ ├── cliff_sensor_frame.py │ │ ├── life_frame.py │ │ ├── gyro_drift_frame.py │ │ └── battery_profile_frame.py ├── plugins │ ├── images │ │ └── kobuki_icon.png │ └── testsuite_plugin.xml ├── .pydevproject ├── setup.py ├── scripts │ └── kobuki_qtestsuite ├── CHANGELOG.rst ├── package.xml ├── LICENSE ├── CMakeLists.txt ├── .project └── .cproject ├── .gitignore ├── kobuki_dashboard ├── src │ └── kobuki_dashboard │ │ ├── __init__.py │ │ ├── battery_widget.py │ │ ├── motor_widget.py │ │ ├── led_widget.py │ │ └── dashboard.py ├── .gitignore ├── scripts │ └── kobuki_dashboard ├── plugins │ ├── images │ │ └── kobuki_icon.png │ └── plugin.xml ├── setup.py ├── .pydevproject ├── README.md ├── CMakeLists.txt ├── CHANGELOG.rst ├── package.xml ├── LICENSE ├── .project └── .cproject ├── README.markdown ├── kobuki_desktop ├── CMakeLists.txt ├── CHANGELOG.rst ├── package.xml ├── .project └── .cproject ├── kobuki_rviz_launchers ├── launch │ └── view_robot.launch ├── CMakeLists.txt ├── package.xml ├── CHANGELOG.rst ├── LICENSE ├── .project ├── .cproject └── rviz │ └── robot.rviz ├── kobuki_gazebo ├── param │ └── random_walker_mux.yaml ├── CMakeLists.txt ├── launch │ ├── kobuki_empty_world.launch │ ├── kobuki_playground.launch │ ├── includes │ │ └── robot.launch.xml │ └── apps │ │ └── safe_random_walker_app.launch ├── worlds │ └── empty.world ├── CHANGELOG.rst ├── package.xml ├── .project └── .cproject ├── kobuki_simulator.rosinstall └── kobuki_gazebo_plugins ├── package.xml ├── CMakeLists.txt ├── CHANGELOG.rst ├── .project ├── src └── gazebo_ros_kobuki.cpp ├── .cproject └── include └── kobuki_gazebo_plugins └── gazebo_ros_kobuki.h /kobuki_qtestsuite/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .settings 2 | bin 3 | build 4 | lib 5 | -------------------------------------------------------------------------------- /kobuki_dashboard/src/kobuki_dashboard/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kobuki_dashboard/.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *.swp 3 | build 4 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/detail/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kobuki_dashboard/scripts/kobuki_dashboard: -------------------------------------------------------------------------------- 1 | rqt -s kobuki_dashboard -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/detail/.gitignore: -------------------------------------------------------------------------------- 1 | *.py 2 | !__init__.py 3 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | # Local imports 3 | #import climbing -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/.gitignore: -------------------------------------------------------------------------------- 1 | /configuration_dock.py 2 | /kobuki_testsuite.py 3 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | kobuki_desktop 2 | ================ 3 | 4 | Visualisation and simulation tools for Kobuki 5 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/.gitignore: -------------------------------------------------------------------------------- 1 | /common.py 2 | /climbing.py 3 | /climbing_rc.py 4 | /common_rc.py 5 | -------------------------------------------------------------------------------- /kobuki_dashboard/plugins/images/kobuki_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yujinrobot/kobuki_desktop/HEAD/kobuki_dashboard/plugins/images/kobuki_icon.png -------------------------------------------------------------------------------- /kobuki_desktop/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(kobuki_desktop) 3 | find_package(catkin REQUIRED) 4 | catkin_metapackage() 5 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/plugins/images/kobuki_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yujinrobot/kobuki_desktop/HEAD/kobuki_qtestsuite/plugins/images/kobuki_icon.png -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/common.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/kobuki_icon.png 4 | 5 | 6 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/images/kobuki_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yujinrobot/kobuki_desktop/HEAD/kobuki_qtestsuite/src/kobuki_qtestsuite/resources/images/kobuki_icon.png -------------------------------------------------------------------------------- /kobuki_dashboard/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup 4 | from catkin_pkg.python_setup import generate_distutils_setup 5 | 6 | d = generate_distutils_setup(packages=['kobuki_dashboard'], 7 | package_dir={'': 'src'}) 8 | 9 | setup(**d) 10 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/launch/view_robot.launch: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | 3 | project(kobuki_rviz_launchers) 4 | 5 | find_package(catkin REQUIRED) 6 | 7 | catkin_package() 8 | 9 | install(DIRECTORY launch DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 10 | install(DIRECTORY rviz DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 11 | -------------------------------------------------------------------------------- /kobuki_dashboard/.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Default 6 | python 2.7 7 | 8 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/.pydevproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | python 2.7 6 | python 7 | 8 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/text/life.html: -------------------------------------------------------------------------------- 1 |

RQ101 - Life

2 | 3 |

Overview

4 | 5 |

Life test for the system.

6 | 7 |

Usage

8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/text.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | text/cliff_sensor.html 4 | text/gyro_drift.html 5 | text/life.html 6 | text/payload.html 7 | text/battery_profile.html 8 | text/wandering.html 9 | 10 | 11 | -------------------------------------------------------------------------------- /kobuki_gazebo/param/random_walker_mux.yaml: -------------------------------------------------------------------------------- 1 | # cmd vel mux config for the random walker app 2 | subscribers: 3 | - name: "Safe reactive controller" 4 | topic: "safety_controller" 5 | timeout: 0.2 6 | priority: 1 7 | - name: "Random Walker" 8 | topic: "random_walker" 9 | timeout: 0.2 10 | priority: 0 11 | publisher: "output/cmd_vel" -------------------------------------------------------------------------------- /kobuki_gazebo/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(kobuki_gazebo) 3 | 4 | find_package(catkin REQUIRED) 5 | 6 | catkin_package() 7 | 8 | install(DIRECTORY launch 9 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 10 | 11 | install(DIRECTORY param 12 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 13 | 14 | install(DIRECTORY worlds 15 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) -------------------------------------------------------------------------------- /kobuki_qtestsuite/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup 4 | from catkin_pkg.python_setup import generate_distutils_setup 5 | 6 | d = generate_distutils_setup( 7 | packages=['kobuki_qtestsuite','kobuki_qtestsuite.detail'], 8 | package_dir={'': 'src'}, 9 | scripts=['scripts/kobuki_qtestsuite'], 10 | requires=['qt_gui_py_common', 'rqt_gui', 'rqt_gui_py', 'rospy', 'rospkg'] 11 | ) 12 | setup(**d) 13 | -------------------------------------------------------------------------------- /kobuki_dashboard/README.md: -------------------------------------------------------------------------------- 1 | Kobuki Dashboard 2 | ==================== 3 | 4 | This is a dashboard for [Kobuki](http://kobuki.yujinrobot.com/). 5 | 6 | It is based on the [rqt_robot_dashboard](https://github.com/ros-visualization/rqt_robot_plugins) framework and runs in [rqt](https://github.com/ros-visualization/rqt). 7 | You can run this dashboard by calling: 8 | 9 | `rosrun kobuki_dashboard kobuki_dashboard` 10 | 11 | or through rqt: 12 | 13 | `rqt -s kobuki_dashboard` 14 | 15 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/text/gyro_drift.html: -------------------------------------------------------------------------------- 1 |

UP5 - Gyro Drift

2 | 3 |

Overview

4 | 5 |

Estimates the gyro drift by checking against a turtlebot mounted kinect 6 | (fake laser) that is pointed at a wall

7 | 8 |

Usage

9 | 10 | 16 | 17 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/text/battery_profile.html: -------------------------------------------------------------------------------- 1 |

UP4 - Battery Profile

2 | 3 |

Overview

4 | 5 |

Robot will continuously rotate while generating a discharging profile for the battery.

6 | 7 |

Usage

8 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /kobuki_dashboard/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(kobuki_dashboard) 3 | 4 | find_package(catkin REQUIRED COMPONENTS rospy 5 | rqt_robot_dashboard 6 | kobuki_msgs) 7 | 8 | catkin_python_setup() 9 | 10 | catkin_package() 11 | 12 | install(PROGRAMS scripts/kobuki_dashboard 13 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) 14 | 15 | install(DIRECTORY plugins 16 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 17 | -------------------------------------------------------------------------------- /kobuki_gazebo/launch/kobuki_empty_world.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /kobuki_gazebo/launch/kobuki_playground.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /kobuki_desktop/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | Changelog 2 | ========= 3 | 4 | 0.4.3 (2016-08-11) 5 | ------------------ 6 | * upgrades for the new gazebo in kinetic 7 | 8 | 0.4.0 (2014-08-11) 9 | ------------------ 10 | * removes email addresses from authors 11 | * adds package for rviz launchers 12 | * Contributors: Marcus Liebhardt 13 | 14 | 0.3.1 (2013-10-14) 15 | ------------------ 16 | 17 | 0.3.0 (2013-08-30) 18 | ------------------ 19 | * adds bugtracker and repo info to package.xml 20 | 21 | 0.2.0 (2013-07-11) 22 | ------------------ 23 | * ROS Hydro beta release. 24 | * Adds catkinized kobuki_qtestsuite 25 | 26 | -------------------------------------------------------------------------------- /kobuki_gazebo/worlds/empty.world: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | model://sun 7 | 8 | 9 | 10 | model://ground_plane 11 | 12 | 13 | 14 | 0.01 15 | 1 16 | 100 17 | 0 0 -9.8 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/text/payload.html: -------------------------------------------------------------------------------- 1 |

SP1 - Payload

2 | 3 |

Overview

4 | 5 |

Test the motion of the base under payload.

6 | 7 |

Usage

8 | 9 | 16 | 17 |

Errata

18 | 19 | This is quite inaccurate - it is just setting 'simple' goals relative to each side or 20 | turn's starting position and ignoring accumulated errors. 21 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/text/cliff_sensor.html: -------------------------------------------------------------------------------- 1 |

SP5 - Cliff Sensors

2 | 3 |

Overview

4 | 5 |

Repeatedly approach and retreat from a cliff, test at various speeds.

6 | 7 |

Usage

8 | 9 | 15 | 16 |

Tips

17 | 18 |

If doing cliff testing, you may need to reduce the speed. The cliff sensor reactive control is not in firmware, so there is some latency.

19 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/resources/text/wandering.html: -------------------------------------------------------------------------------- 1 |

RQ108/RQ109 - Wandering/Bump Test

2 | 3 |

Overview

4 | 5 |

Put the robot in wandering mode and display the bump counter.

6 | 7 |

Usage - Bump Test

8 | 9 | You do not need to start for this test. 10 | 11 | 15 | 16 |

Usage - Safe Wandering

17 | 18 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_rviz_launchers 4 | 0.5.7 5 | The kobuki_rviz_launchers package 6 | Marcus Liebhardt 7 | Marcus Liebhardt 8 | BSD 9 | https://github.com/yujinrobot/kobuki_desktop/issues 10 | https://github.com/yujinrobot/kobuki_desktop 11 | http://ros.org/wiki/kobuki_rviz_launchers 12 | 13 | catkin 14 | 15 | rviz 16 | 17 | -------------------------------------------------------------------------------- /kobuki_simulator.rosinstall: -------------------------------------------------------------------------------- 1 | # Rosinstaller for the Kobuki simulator 2 | 3 | - git: {local-name: yocs_msgs, version: release/0.7-melodic, uri: 'https://github.com/yujinrobot/yocs_msgs.git'} 4 | - git: {local-name: yujin_ocs, version: release/0.8-melodic, uri: 'https://github.com/yujinrobot/yujin_ocs.git'} 5 | - git: {local-name: kobuki, version: melodic, uri: 'https://github.com/yujinrobot/kobuki.git'} 6 | - git: {local-name: kobuki_core, version: melodic, uri: 'https://github.com/yujinrobot/kobuki_core.git'} 7 | - git: {local-name: kobuki_msgs, version: melodic, uri: 'https://github.com/yujinrobot/kobuki_msgs.git'} 8 | - git: {local-name: kobuki_desktop, version: melodic, uri: 'https://github.com/yujinrobot/kobuki_desktop.git'} 9 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/scripts/kobuki_qtestsuite: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/robotics-in-concert/rocon_rqt_plugins/hydro-devel/rocon_gateway_graph/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import sys 11 | from rqt_gui.main import Main 12 | 13 | ############################################################################## 14 | # Main 15 | ############################################################################## 16 | 17 | main = Main() 18 | sys.exit(main.main(sys.argv, standalone='kobuki_qtestsuite')) 19 | 20 | #rqt -s kobuki_qtestsuite -------------------------------------------------------------------------------- /kobuki_gazebo/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package kobuki_dashboard 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.4.2 (2015-03-02) 6 | ------------------ 7 | 8 | 0.4.1 (2014-09-19) 9 | ------------------ 10 | 11 | 0.4.0 (2014-08-11) 12 | ------------------ 13 | * removes email addresses from authors 14 | * Contributors: Marcus Liebhardt 15 | 16 | 0.3.1 (2013-10-14) 17 | ------------------ 18 | * Rename cmd_vel_mux as yocs_cmd_vel_mux. 19 | 20 | 0.3.0 (2013-08-30) 21 | ------------------ 22 | * Add missing install rule for param folder. 23 | * Add random walker app launcher. 24 | * Restructure and updates launchers and worlds. 25 | * Add bugtracker and repo info to package.xml. 26 | 27 | 0.2.0 (2013-07-11) 28 | ------------------ 29 | * ROS Hydro beta release. 30 | 31 | -------------------------------------------------------------------------------- /kobuki_gazebo/launch/includes/robot.launch.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /kobuki_dashboard/plugins/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dashboard for Kobuki 5 | 6 | 7 | 8 | 9 | folder 10 | Plugins related to specific robots. 11 | 12 | 13 | 14 | images/kobuki_icon.png 15 | Plugins related to the Kobuki robot. 16 | 17 | 18 | images/kobuki_icon.png 19 | Check what's going on with Kobuki 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/plugins/testsuite_plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Plugin for the Kobuki testsuite. 5 | 6 | 7 | 8 | 9 | folder 10 | Plugins related to specific robots. 11 | 12 | 13 | 14 | images/kobuki_icon.png 15 | Plugins related to the Kobuki robot. 16 | 17 | 18 | images/kobuki_icon.png 19 | Test suite for Kobuki 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /kobuki_dashboard/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package kobuki_dashboard 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.5.2 (2017-02-23) 6 | ------------------ 7 | * updated for QtGui -> QtWidgets qt api change in xenial 8 | 9 | 0.4.0 (2014-08-11) 10 | ------------------ 11 | * now it uses dataplot class instead of mat dataplot. It still shows weird scaling though.. 12 | * removes email addresses from authors 13 | * add robot groups for rqt plugins 14 | * Contributors: Dirk Thomas, Jihoon Lee, Marcus Liebhardt 15 | 16 | 0.3.1 (2013-10-14) 17 | ------------------ 18 | 19 | 0.3.0 (2013-08-30) 20 | ------------------ 21 | * adds own battery widget to make use of the coloured battery status versions 22 | * adds bugtracker and repo info to package.xml 23 | 24 | 0.2.0 (2013-07-11) 25 | ------------------ 26 | * ROS Hydro beta release. 27 | * Adds catkinized kobuki_qtestsuite 28 | 29 | -------------------------------------------------------------------------------- /kobuki_desktop/package.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_desktop 4 | 0.5.7 5 | Visualisation and simulation tools for Kobuki 6 | Marcus Liebhardt 7 | Marcus Liebhardt 8 | BSD 9 | http://ros.org/wiki/kobuki_desktop 10 | https://github.com/yujinrobot/kobuki_desktop 11 | https://github.com/yujinrobot/kobuki_desktop/issues 12 | 13 | catkin 14 | kobuki_dashboard 15 | kobuki_gazebo 16 | kobuki_gazebo_plugins 17 | kobuki_qtestsuite 18 | kobuki_rviz_launchers 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /kobuki_gazebo/package.xml: -------------------------------------------------------------------------------- 1 | 2 | kobuki_gazebo 3 | 0.5.7 4 | Kobuki simulation for Gazebo 5 | Marcus Liebhardt 6 | Marcus Liebhardt 7 | BSD 8 | http://ros.org/wiki/kobuki_gazebo 9 | https://github.com/yujinrobot/kobuki_desktop 10 | https://github.com/yujinrobot/kobuki_desktop/issues 11 | 12 | catkin 13 | 14 | 15 | yocs_cmd_vel_mux 16 | gazebo_ros 17 | gazebo_plugins 18 | kobuki_description 19 | kobuki_gazebo_plugins 20 | kobuki_random_walker 21 | kobuki_safety_controller 22 | robot_state_publisher 23 | 24 | -------------------------------------------------------------------------------- /kobuki_dashboard/src/kobuki_dashboard/battery_widget.py: -------------------------------------------------------------------------------- 1 | import rospy 2 | from rqt_robot_dashboard.widgets import BatteryDashWidget 3 | from QtWidgets import QToolButton 4 | 5 | class BatteryWidget(BatteryDashWidget): 6 | def __init__(self, name): 7 | icons = [] 8 | charge_icons = [] 9 | icons.append(['ic-battery-0.svg']) 10 | icons.append(['ic-battery-20.svg']) 11 | icons.append(['ic-battery-40.svg']) 12 | icons.append(['ic-battery-60-green.svg']) 13 | icons.append(['ic-battery-80-green.svg']) 14 | icons.append(['ic-battery-100-green.svg']) 15 | charge_icons.append(['ic-battery-charge-0.svg']) 16 | charge_icons.append(['ic-battery-charge-20.svg']) 17 | charge_icons.append(['ic-battery-charge-40.svg']) 18 | charge_icons.append(['ic-battery-charge-60-green.svg']) 19 | charge_icons.append(['ic-battery-charge-80-green.svg']) 20 | charge_icons.append(['ic-battery-charge-100-green.svg']) 21 | super(BatteryWidget, self).__init__(name=name, icons=icons, charge_icons=charge_icons) 22 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package kobuki_dashboard 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.5.7 (2017-05-14) 6 | ------------------ 7 | * bugfix for pyqt4->pyqt5 pyrrc tools rosdep 8 | 9 | 0.5.4 (2017-03-28) 10 | ------------------ 11 | * refactoring for pyqt5 QtGui -> QWidget 12 | * workaround for the multi matplotlib crash bug 13 | 14 | 0.4.0 (2014-08-11) 15 | ------------------ 16 | * now it uses Rqt DataPlot instead our own version 17 | * uses dataplot 18 | * now it uses dataplot class instead of mat dataplot. It still shows weird scaling though.. 19 | * removes email addresses from authors 20 | * add robot groups for rqt plugins 21 | * Contributors: Dirk Thomas, Jihoon Lee, Marcus Liebhardt 22 | 23 | 0.3.1 (2013-10-14) 24 | ------------------ 25 | 26 | 0.3.0 (2013-08-30) 27 | ------------------ 28 | * adds bugtracker and repo info to package.xml 29 | * bugfix new matdataplot api with resizing the plot 30 | 31 | 0.2.0 (2013-07-11) 32 | ------------------ 33 | * ROS Hydro beta release. 34 | * Adds catkinized kobuki_qtestsuite 35 | 36 | -------------------------------------------------------------------------------- /kobuki_dashboard/package.xml: -------------------------------------------------------------------------------- 1 | 2 | kobuki_dashboard 3 | 0.5.7 4 | 5 | The Kobuki dashboard is a RQT-based plug-in for visualising data from Kobuki and giving easy access 6 | to basic functionalities. 7 | 8 | Marcus Liebhardt 9 | BSD 10 | http://ros.org/wiki/kobuki_dashboard 11 | https://github.com/yujinrobot/kobuki_desktop 12 | https://github.com/yujinrobot/kobuki_desktop/issues 13 | 14 | Ze'ev Klapow 15 | Marcus Liebhardt 16 | 17 | catkin 18 | 19 | rospy 20 | rqt_robot_dashboard 21 | kobuki_msgs 22 | 23 | rospy 24 | rqt_robot_dashboard 25 | kobuki_msgs 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 2 | Changelog for package kobuki_rviz_launchers 3 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 4 | 5 | 0.4.2 (2015-03-02) 6 | ------------------ 7 | 8 | 0.4.1 (2014-09-19) 9 | ------------------ 10 | 11 | 0.4.0 (2014-08-11) 12 | ------------------ 13 | * removes email addresses from authors 14 | * adds package for rviz launchers 15 | * Contributors: Marcus Liebhardt 16 | 17 | 0.3.3 (2014-08-05) 18 | ------------------ 19 | * update changelog 20 | * Contributors: Jihoon Lee 21 | 22 | 0.3.2 (2014-04-23) 23 | ------------------ 24 | * update changelog 25 | * update package version 26 | * removes email addresses from authors 27 | * adds package for rviz launchers 28 | * Contributors: Jihoon Lee, Marcus Liebhardt 29 | 30 | 0.3.1 (2013-10-14) 31 | ------------------ 32 | 33 | 0.3.0 (2013-09-11) 34 | ------------------ 35 | 36 | 0.2.0 (2013-08-09) 37 | ------------------ 38 | 39 | 0.1.7 (2013-07-11) 40 | ------------------ 41 | 42 | 0.1.6 (2013-04-16) 43 | ------------------ 44 | 45 | 0.1.5 (2013-02-16) 46 | ------------------ 47 | 48 | 0.1.3 (2013-02-05) 49 | ------------------ 50 | 51 | 0.1.2 (2012-12-24) 52 | ------------------ 53 | 54 | 0.1.1 (2012-12-22 21:20) 55 | ------------------------ 56 | 57 | 0.1.0 (2012-12-22 04:28) 58 | ------------------------ 59 | -------------------------------------------------------------------------------- /kobuki_gazebo_plugins/package.xml: -------------------------------------------------------------------------------- 1 | 2 | kobuki_gazebo_plugins 3 | 0.5.7 4 | Kobuki-specific ROS plugins for Gazebo 5 | Marcus Liebhardt 6 | BSD 7 | http://ros.org/wiki/kobuki_gazebo_plugins 8 | https://github.com/yujinrobot/kobuki_desktop 9 | https://github.com/yujinrobot/kobuki_desktop/issues 10 | Marcus Liebhardt 11 | 12 | catkin 13 | 14 | boost 15 | gazebo_ros 16 | gazebo_plugins 17 | geometry_msgs 18 | kobuki_msgs 19 | nav_msgs 20 | roscpp 21 | sensor_msgs 22 | std_msgs 23 | tf 24 | 25 | boost 26 | gazebo_ros 27 | gazebo_plugins 28 | geometry_msgs 29 | kobuki_msgs 30 | nav_msgs 31 | roscpp 32 | sensor_msgs 33 | std_msgs 34 | tf 35 | 36 | -------------------------------------------------------------------------------- /kobuki_dashboard/src/kobuki_dashboard/motor_widget.py: -------------------------------------------------------------------------------- 1 | import rospy 2 | from functools import partial 3 | 4 | from kobuki_msgs.msg import MotorPower 5 | 6 | from rqt_robot_dashboard.widgets import IconToolButton 7 | from python_qt_binding.QtCore import QSize 8 | 9 | class MotorWidget(IconToolButton): 10 | def __init__(self, topic): 11 | self._pub = rospy.Publisher(topic, MotorPower, queue_size=5) 12 | 13 | self._off_icon = ['bg-red.svg', 'ic-motors.svg'] 14 | self._on_icon = ['bg-green.svg', 'ic-motors.svg'] 15 | self._stale_icon = ['bg-grey.svg', 'ic-motors.svg', 'ol-stale-badge.svg'] 16 | 17 | icons = [self._off_icon, self._on_icon, self._stale_icon] 18 | super(MotorWidget, self).__init__(topic, icons=icons) 19 | self.setFixedSize(QSize(40,40)) 20 | 21 | super(MotorWidget, self).update_state(2) 22 | self.setToolTip("Motors: Stale") 23 | 24 | self.clicked.connect(self.toggle) 25 | 26 | 27 | def update_state(self, state): 28 | if state is not super(MotorWidget, self).state: 29 | super(MotorWidget, self).update_state(state) 30 | if state is 0: 31 | self.setToolTip("Motors: Off") 32 | else: 33 | self.setToolTip("Motors: On") 34 | 35 | def toggle(self): 36 | if super(MotorWidget, self).state is 1: 37 | self._pub.publish(MotorPower(0)) 38 | else: 39 | self._pub.publish(MotorPower(1)) 40 | 41 | def close(self): 42 | self._pub.unregister() 43 | 44 | -------------------------------------------------------------------------------- /kobuki_dashboard/src/kobuki_dashboard/led_widget.py: -------------------------------------------------------------------------------- 1 | import rospy 2 | from functools import partial 3 | 4 | from kobuki_msgs.msg import Led 5 | 6 | from rqt_robot_dashboard.widgets import MenuDashWidget 7 | from python_qt_binding.QtCore import QSize 8 | 9 | class LedWidget(MenuDashWidget): 10 | def __init__(self, topic): 11 | self._pub = rospy.Publisher(topic, Led, queue_size=5) 12 | 13 | self._off_icon = ['bg-grey.svg', 'ic-led.svg'] 14 | self._green_icon = ['bg-green.svg', 'ic-led.svg'] 15 | self._orange_icon = ['bg-orange.svg', 'ic-led.svg'] 16 | self._red_icon = ['bg-red.svg', 'ic-led.svg'] 17 | 18 | icons = [self._off_icon, self._green_icon, self._orange_icon, self._red_icon] 19 | super(LedWidget, self).__init__(topic, icons=icons) 20 | self.setFixedSize(QSize(40,40)) 21 | 22 | self.add_action('Off', partial(self.update_state, 0)) 23 | self.add_action('Green', partial(self.update_state, 1)) 24 | self.add_action('Orange', partial(self.update_state, 2)) 25 | self.add_action('Red', partial(self.update_state, 3)) 26 | 27 | self.setToolTip("LED: Off") 28 | 29 | def update_state(self, state): 30 | super(LedWidget, self).update_state(state) 31 | self._pub.publish(Led(state)) 32 | if state is 1: 33 | self.setToolTip("LED: Green") 34 | elif state is 2: 35 | self.setToolTip("LED: Orange") 36 | elif state is 3: 37 | self.setToolTip("LED: Red") 38 | else: 39 | self.setToolTip("LED: Off") 40 | 41 | def close(self): 42 | self._pub.unregister() 43 | 44 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/package.xml: -------------------------------------------------------------------------------- 1 | 2 | kobuki_qtestsuite 3 | 0.5.7 4 | An rqt plugin that provides a graphical, interactive testsuite for Kobuki. 5 | Daniel Stonier 6 | Daniel Stonier 7 | BSD 8 | http://ros.org/wiki/kobuki_qtestsuite 9 | https://github.com/yujinrobot/kobuki_desktop 10 | https://github.com/yujinrobot/kobuki_desktop/issues 11 | 12 | catkin 13 | 14 | rospy 15 | kobuki_testsuite 16 | qt_gui_py_common 17 | rqt_gui 18 | rqt_gui_py 19 | rqt_py_common 20 | rqt_plot 21 | geometry_msgs 22 | nav_msgs 23 | pyqt5-dev-tools 24 | 25 | rospy 26 | kobuki_testsuite 27 | qt_gui_py_common 28 | rqt_gui 29 | rqt_gui_py 30 | rqt_py_common 31 | rqt_plot 32 | geometry_msgs 33 | nav_msgs 34 | pyqt5-dev-tools 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /kobuki_dashboard/LICENSE: -------------------------------------------------------------------------------- 1 | # Software License Agreement (BSD License) 2 | # 3 | # Copyright (c) 2012 Daniel Stonier, Yujin Robot 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions 8 | # are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following 14 | # disclaimer in the documentation and/or other materials provided 15 | # with the distribution. 16 | # * Neither the name of Yujin Robot nor the names of its 17 | # contributors may be used to endorse or promote products derived 18 | # from this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/LICENSE: -------------------------------------------------------------------------------- 1 | # Software License Agreement (BSD License) 2 | # 3 | # Copyright (c) 2012 Daniel Stonier, Yujin Robot 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions 8 | # are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following 14 | # disclaimer in the documentation and/or other materials provided 15 | # with the distribution. 16 | # * Neither the name of Yujin Robot nor the names of its 17 | # contributors may be used to endorse or promote products derived 18 | # from this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/LICENSE: -------------------------------------------------------------------------------- 1 | # Software License Agreement (BSD License) 2 | # 3 | # Copyright (c) 2013 Yujin Robot, Marcus Liebhardt 4 | # All rights reserved. 5 | # 6 | # Redistribution and use in source and binary forms, with or without 7 | # modification, are permitted provided that the following conditions 8 | # are met: 9 | # 10 | # * Redistributions of source code must retain the above copyright 11 | # notice, this list of conditions and the following disclaimer. 12 | # * Redistributions in binary form must reproduce the above 13 | # copyright notice, this list of conditions and the following 14 | # disclaimer in the documentation and/or other materials provided 15 | # with the distribution. 16 | # * Neither the name of Yujin Robot nor the names of its 17 | # contributors may be used to endorse or promote products derived 18 | # from this software without specific prior written permission. 19 | # 20 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 | # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 | # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 | # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 | # POSSIBILITY OF SUCH DAMAGE. 32 | -------------------------------------------------------------------------------- /kobuki_gazebo_plugins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(kobuki_gazebo_plugins) 3 | 4 | find_package(gazebo REQUIRED) 5 | 6 | 7 | find_package(catkin REQUIRED COMPONENTS gazebo_ros 8 | gazebo_plugins 9 | geometry_msgs 10 | kobuki_msgs 11 | nav_msgs 12 | roscpp 13 | sensor_msgs 14 | std_msgs 15 | tf) 16 | 17 | catkin_package(INCLUDE_DIRS include 18 | LIBRARIES gazebo_ros_kobuki 19 | CATKIN_DEPENDS gazebo_ros 20 | gazebo_plugins 21 | geometry_msgs 22 | kobuki_msgs 23 | nav_msgs 24 | roscpp 25 | sensor_msgs 26 | std_msgs 27 | tf) 28 | 29 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 30 | 31 | link_directories(${GAZEBO_LIBRARY_DIRS}) 32 | include_directories(include 33 | ${catkin_INCLUDE_DIRS} 34 | ${GAZEBO_INCLUDE_DIRS}) 35 | 36 | add_library(gazebo_ros_kobuki src/gazebo_ros_kobuki.cpp 37 | src/gazebo_ros_kobuki_updates.cpp 38 | src/gazebo_ros_kobuki_loads.cpp) 39 | add_dependencies(gazebo_ros_kobuki ${catkin_EXPORTED_TARGETS}) 40 | target_link_libraries(gazebo_ros_kobuki 41 | ${catkin_LIBRARIES} 42 | ${GAZEBO_LIBRARIES}) 43 | 44 | install(TARGETS gazebo_ros_kobuki 45 | DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}) 46 | -------------------------------------------------------------------------------- /kobuki_gazebo_plugins/CHANGELOG.rst: -------------------------------------------------------------------------------- 1 | ========= 2 | Changelog 3 | ========= 4 | 5 | 0.5.6 (2017-04-01) 6 | ------------------ 7 | * update at the end of the event loop so the bumper sensor can be caught 8 | 9 | 0.5.3 (2017-02-23) 10 | ------------------ 11 | * add_dependencies with catkin_EXPORTED_TARGETS, not xyz_gencpp targets which might not be there 12 | 13 | 0.5.1 (2016-09-20) 14 | ------------------ 15 | * bugfix for ros logging. 16 | 17 | 0.4.2 (2015-03-02) 18 | ------------------ 19 | * kobuki_gazebo_plugins: Resolve IMU sensor using fully scoped name 20 | This ensures uniqueness among multiple models in which the sensor has the 21 | same name. In this case, our specific motivation is the Kobuki Gazebo 22 | plugin being spawned multiple times using kobuki_gazebo.urdf.xacro in the 23 | package kobuki_description. 24 | * Contributors: Scott Livingston 25 | 26 | 0.4.1 (2014-09-19) 27 | ------------------ 28 | * kobuki_gazebo_plugins: makes bump detection more reliable 29 | * remove duplicated spinonce 30 | * renamed updater to updates and loader to loads. reorder headers 31 | * tf_prefix added. base_prefix added 32 | * Contributors: Jihoon Lee, Marcus Liebhardt 33 | 34 | 0.4.0 (2014-08-11) 35 | ------------------ 36 | * cherry-picking `#30 `_ 37 | * trivial update. 38 | * removes email addresses from authors 39 | * replace deprecated shared_dynamic_cast (fixes `#25 `_) 40 | * Contributors: Daniel Stonier, Marcus Liebhardt, Nikolaus Demmel, Samir Benmendil 41 | 42 | 0.3.1 (2013-10-14) 43 | ------------------ 44 | * fixes gazebo header paths (refs `#22 `_) 45 | 46 | 0.3.0 (2013-08-30) 47 | ------------------ 48 | * fixes bumper & cliff event publishing 49 | * adds reset odometry and fixes imu and odom data processing 50 | * adds IMU data processing 51 | * adds bugtracker and repo info to package.xml 52 | 53 | 0.2.0 (2013-07-11) 54 | ------------------ 55 | * ROS Hydro beta release. 56 | * Adds catkinized kobuki_qtestsuite 57 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.3) 2 | project(kobuki_qtestsuite) 3 | 4 | find_package(catkin REQUIRED COMPONENTS rospy 5 | kobuki_testsuite 6 | qt_gui_py_common 7 | rqt_gui 8 | rqt_gui_py 9 | rqt_py_common 10 | rqt_plot 11 | geometry_msgs 12 | nav_msgs) 13 | 14 | catkin_python_setup() 15 | 16 | catkin_package() 17 | 18 | set(DIR src/kobuki_qtestsuite/detail) 19 | set(UI_DIR src/kobuki_qtestsuite/ui) 20 | set(RESOURCES_DIR src/kobuki_qtestsuite/resources) 21 | 22 | add_custom_target(${PROJECT_NAME} 23 | ALL 24 | COMMAND pyrcc5 -o ${DIR}/common_rc.py ${RESOURCES_DIR}/common.qrc 25 | COMMAND pyrcc5 -o ${DIR}/common_rc.py ${RESOURCES_DIR}/common.qrc 26 | COMMAND pyrcc5 -o ${DIR}/text_rc.py ${RESOURCES_DIR}/text.qrc 27 | COMMAND pyuic5 -o ${DIR}/testsuite_ui.py ${UI_DIR}/testsuite.ui 28 | COMMAND pyuic5 -o ${DIR}/configuration_dock_ui.py ${UI_DIR}/configuration_dock.ui 29 | COMMAND pyuic5 -o ${DIR}/battery_profile_frame_ui.py ${UI_DIR}/battery_profile_frame.ui 30 | COMMAND pyuic5 -o ${DIR}/gyro_drift_frame_ui.py ${UI_DIR}/gyro_drift_frame.ui 31 | COMMAND pyuic5 -o ${DIR}/payload_frame_ui.py ${UI_DIR}/payload_frame.ui 32 | COMMAND pyuic5 -o ${DIR}/cliff_sensor_frame_ui.py ${UI_DIR}/cliff_sensor_frame.ui 33 | COMMAND pyuic5 -o ${DIR}/life_frame_ui.py ${UI_DIR}/life_frame.ui 34 | COMMAND pyuic5 -o ${DIR}/wandering_frame_ui.py ${UI_DIR}/wandering_frame.ui 35 | COMMAND pyuic5 -o ${DIR}/climbing_frame_ui.py ${UI_DIR}/climbing_frame.ui 36 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) 37 | 38 | install(PROGRAMS scripts/kobuki_qtestsuite 39 | DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}) 40 | 41 | install(DIRECTORY plugins 42 | DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}) 43 | -------------------------------------------------------------------------------- /kobuki_gazebo/launch/apps/safe_random_walker_app.launch: -------------------------------------------------------------------------------- 1 | 11 | 12 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/testsuite.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import os 11 | import roslib 12 | roslib.load_manifest('kobuki_qtestsuite') 13 | import rospy 14 | 15 | from qt_gui.plugin import Plugin 16 | from python_qt_binding import loadUi 17 | try: # indigo 18 | from python_qt_binding.QtGui import QFrame, QWidget 19 | except ImportError: # kinetic+ (pyqt5) 20 | from python_qt_binding.QtWidgets import QFrame, QWidget 21 | from python_qt_binding.QtCore import Signal,Slot 22 | from rqt_py_common.extended_combo_box import ExtendedComboBox 23 | from geometry_msgs.msg import Twist 24 | 25 | # Local resource imports 26 | import detail.common_rc 27 | from .testsuite_widget import TestSuiteWidget 28 | from .configuration_dock_widget import ConfigurationDockWidget 29 | 30 | class KobukiTestSuite(Plugin): 31 | 32 | def __init__(self, context): 33 | super(KobukiTestSuite, self).__init__(context) 34 | # give QObjects reasonable names 35 | self.setObjectName('Kobuki Test Suite') 36 | 37 | # create QWidget 38 | self._widget = TestSuiteWidget() 39 | #self._widget = ConfigurationDockWidget() 40 | 41 | # add widget to the user interface 42 | context.add_widget(self._widget) 43 | 44 | # Custom setup function to make sure promoted widgets all do their setup properly 45 | self._widget.setupUi() 46 | 47 | def shutdown_plugin(self): 48 | self._widget.shutdown() 49 | 50 | def save_settings(self, plugin_settings, instance_settings): 51 | # TODO save intrinsic configuration, usually using: 52 | # instance_settings.set_value(k, v) 53 | pass 54 | 55 | def restore_settings(self, plugin_settings, instance_settings): 56 | # TODO restore intrinsic configuration, usually using: 57 | # v = instance_settings.value(k) 58 | pass 59 | 60 | ########################################################################## 61 | # Slot Callbacks 62 | ########################################################################## 63 | 64 | #def trigger_configuration(self): 65 | # Comment in to signal that the plugin has a way to configure it 66 | # Usually used to open a dialog to offer the user a set of configuration 67 | -------------------------------------------------------------------------------- /kobuki_gazebo/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_gazebo 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.cleanBuildTarget 34 | clean 35 | 36 | 37 | org.eclipse.cdt.make.core.contents 38 | org.eclipse.cdt.make.core.activeConfigSettings 39 | 40 | 41 | org.eclipse.cdt.make.core.enableAutoBuild 42 | false 43 | 44 | 45 | org.eclipse.cdt.make.core.enableCleanBuild 46 | true 47 | 48 | 49 | org.eclipse.cdt.make.core.enableFullBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.fullBuildTarget 54 | all 55 | 56 | 57 | org.eclipse.cdt.make.core.stopOnError 58 | true 59 | 60 | 61 | org.eclipse.cdt.make.core.useDefaultBuildCmd 62 | true 63 | 64 | 65 | 66 | 67 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 68 | full,incremental, 69 | 70 | 71 | 72 | 73 | 74 | org.eclipse.cdt.core.cnature 75 | org.eclipse.cdt.core.ccnature 76 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 77 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 78 | 79 | 80 | -------------------------------------------------------------------------------- /kobuki_desktop/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_desktop 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.cleanBuildTarget 34 | clean 35 | 36 | 37 | org.eclipse.cdt.make.core.contents 38 | org.eclipse.cdt.make.core.activeConfigSettings 39 | 40 | 41 | org.eclipse.cdt.make.core.enableAutoBuild 42 | false 43 | 44 | 45 | org.eclipse.cdt.make.core.enableCleanBuild 46 | true 47 | 48 | 49 | org.eclipse.cdt.make.core.enableFullBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.fullBuildTarget 54 | all 55 | 56 | 57 | org.eclipse.cdt.make.core.stopOnError 58 | true 59 | 60 | 61 | org.eclipse.cdt.make.core.useDefaultBuildCmd 62 | true 63 | 64 | 65 | 66 | 67 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 68 | full,incremental, 69 | 70 | 71 | 72 | 73 | 74 | org.eclipse.cdt.core.cnature 75 | org.eclipse.cdt.core.ccnature 76 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 77 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 78 | 79 | 80 | -------------------------------------------------------------------------------- /kobuki_gazebo_plugins/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_gazebo_plugins 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.cleanBuildTarget 34 | clean 35 | 36 | 37 | org.eclipse.cdt.make.core.contents 38 | org.eclipse.cdt.make.core.activeConfigSettings 39 | 40 | 41 | org.eclipse.cdt.make.core.enableAutoBuild 42 | false 43 | 44 | 45 | org.eclipse.cdt.make.core.enableCleanBuild 46 | true 47 | 48 | 49 | org.eclipse.cdt.make.core.enableFullBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.fullBuildTarget 54 | all 55 | 56 | 57 | org.eclipse.cdt.make.core.stopOnError 58 | true 59 | 60 | 61 | org.eclipse.cdt.make.core.useDefaultBuildCmd 62 | true 63 | 64 | 65 | 66 | 67 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 68 | full,incremental, 69 | 70 | 71 | 72 | 73 | 74 | org.eclipse.cdt.core.cnature 75 | org.eclipse.cdt.core.ccnature 76 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 77 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 78 | 79 | 80 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_rviz_launchers 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 10 | clean,full,incremental, 11 | 12 | 13 | ?name? 14 | 15 | 16 | 17 | org.eclipse.cdt.make.core.append_environment 18 | true 19 | 20 | 21 | org.eclipse.cdt.make.core.autoBuildTarget 22 | all 23 | 24 | 25 | org.eclipse.cdt.make.core.buildArguments 26 | 27 | 28 | 29 | org.eclipse.cdt.make.core.buildCommand 30 | make 31 | 32 | 33 | org.eclipse.cdt.make.core.cleanBuildTarget 34 | clean 35 | 36 | 37 | org.eclipse.cdt.make.core.contents 38 | org.eclipse.cdt.make.core.activeConfigSettings 39 | 40 | 41 | org.eclipse.cdt.make.core.enableAutoBuild 42 | false 43 | 44 | 45 | org.eclipse.cdt.make.core.enableCleanBuild 46 | true 47 | 48 | 49 | org.eclipse.cdt.make.core.enableFullBuild 50 | true 51 | 52 | 53 | org.eclipse.cdt.make.core.fullBuildTarget 54 | all 55 | 56 | 57 | org.eclipse.cdt.make.core.stopOnError 58 | true 59 | 60 | 61 | org.eclipse.cdt.make.core.useDefaultBuildCmd 62 | true 63 | 64 | 65 | 66 | 67 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 68 | full,incremental, 69 | 70 | 71 | 72 | 73 | 74 | org.eclipse.cdt.core.cnature 75 | org.eclipse.cdt.core.ccnature 76 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 77 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 78 | 79 | 80 | -------------------------------------------------------------------------------- /kobuki_dashboard/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_dashboard 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 15 | clean,full,incremental, 16 | 17 | 18 | ?name? 19 | 20 | 21 | 22 | org.eclipse.cdt.make.core.append_environment 23 | true 24 | 25 | 26 | org.eclipse.cdt.make.core.autoBuildTarget 27 | all 28 | 29 | 30 | org.eclipse.cdt.make.core.buildArguments 31 | 32 | 33 | 34 | org.eclipse.cdt.make.core.buildCommand 35 | make 36 | 37 | 38 | org.eclipse.cdt.make.core.cleanBuildTarget 39 | clean 40 | 41 | 42 | org.eclipse.cdt.make.core.contents 43 | org.eclipse.cdt.make.core.activeConfigSettings 44 | 45 | 46 | org.eclipse.cdt.make.core.enableAutoBuild 47 | false 48 | 49 | 50 | org.eclipse.cdt.make.core.enableCleanBuild 51 | true 52 | 53 | 54 | org.eclipse.cdt.make.core.enableFullBuild 55 | true 56 | 57 | 58 | org.eclipse.cdt.make.core.fullBuildTarget 59 | all 60 | 61 | 62 | org.eclipse.cdt.make.core.stopOnError 63 | true 64 | 65 | 66 | org.eclipse.cdt.make.core.useDefaultBuildCmd 67 | true 68 | 69 | 70 | 71 | 72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 73 | full,incremental, 74 | 75 | 76 | 77 | 78 | 79 | org.eclipse.cdt.core.cnature 80 | org.eclipse.cdt.core.ccnature 81 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 82 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 83 | org.python.pydev.pythonNature 84 | 85 | 86 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | kobuki_qtestsuite 4 | 5 | 6 | 7 | 8 | 9 | org.python.pydev.PyDevBuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.cdt.managedbuilder.core.genmakebuilder 15 | clean,full,incremental, 16 | 17 | 18 | ?name? 19 | 20 | 21 | 22 | org.eclipse.cdt.make.core.append_environment 23 | true 24 | 25 | 26 | org.eclipse.cdt.make.core.autoBuildTarget 27 | all 28 | 29 | 30 | org.eclipse.cdt.make.core.buildArguments 31 | 32 | 33 | 34 | org.eclipse.cdt.make.core.buildCommand 35 | make 36 | 37 | 38 | org.eclipse.cdt.make.core.cleanBuildTarget 39 | clean 40 | 41 | 42 | org.eclipse.cdt.make.core.contents 43 | org.eclipse.cdt.make.core.activeConfigSettings 44 | 45 | 46 | org.eclipse.cdt.make.core.enableAutoBuild 47 | false 48 | 49 | 50 | org.eclipse.cdt.make.core.enableCleanBuild 51 | true 52 | 53 | 54 | org.eclipse.cdt.make.core.enableFullBuild 55 | true 56 | 57 | 58 | org.eclipse.cdt.make.core.fullBuildTarget 59 | all 60 | 61 | 62 | org.eclipse.cdt.make.core.stopOnError 63 | true 64 | 65 | 66 | org.eclipse.cdt.make.core.useDefaultBuildCmd 67 | true 68 | 69 | 70 | 71 | 72 | org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder 73 | full,incremental, 74 | 75 | 76 | 77 | 78 | 79 | org.eclipse.cdt.core.cnature 80 | org.eclipse.cdt.core.ccnature 81 | org.eclipse.cdt.managedbuilder.core.managedBuildNature 82 | org.eclipse.cdt.managedbuilder.core.ScannerConfigNature 83 | org.python.pydev.pythonNature 84 | 85 | 86 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/full_size_data_plot.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import operator 11 | import numpy 12 | 13 | #from rqt_plot.qwt_data_plot import QwtDataPlot 14 | from rqt_plot.data_plot import DataPlot 15 | 16 | ############################################################################## 17 | # Classes 18 | ############################################################################## 19 | 20 | class FullSizeDataPlot(DataPlot): 21 | def __init__(self, parent=None): 22 | super(FullSizeDataPlot, self).__init__(parent) 23 | self.max_range = 180 24 | self.min_range = 0 25 | self.dynamic_range = False 26 | self._ymin = 0 27 | self._ymax = 0 28 | 29 | def reset(self): 30 | self._ymin = 0 31 | self._ymax = 0 32 | 33 | ###################################### 34 | # Overrides 35 | ###################################### 36 | def _update_legend(self): 37 | handles, labels = self._canvas.axes.get_legend_handles_labels() 38 | if handles: 39 | hl = sorted(zip(handles, labels), key=operator.itemgetter(1)) 40 | handles, labels = zip(*hl) 41 | self._canvas.axes.legend(handles, labels, loc='lower right') 42 | 43 | def redraw(self): 44 | ''' 45 | We fix the y axis and continually resize the x axis to encapsulate 46 | the entire domain, range of the battery profile. 47 | 48 | @Todo : the domain is simply the data value, we could use 49 | ''' 50 | self._canvas.axes.grid(True, color='gray') 51 | # Set axis bounds 52 | xmax = 0 53 | for curve in self._curves.values(): 54 | data_x, data_y, plot, min_max_y = curve 55 | if len(data_x) == 0: 56 | continue 57 | 58 | xmax = max(xmax, data_x[-1]) 59 | self._ymin = min(self._ymin, min_max_y[0]) 60 | self._ymax = max(self._ymax, min_max_y[1] + 1) 61 | self._canvas.axes.set_xbound(lower=0, upper=xmax) 62 | 63 | if self.dynamic_range: 64 | self._canvas.axes.set_ybound(lower=self._ymin, upper=self._ymax) 65 | else: 66 | self._canvas.axes.set_ybound(self.min_range, upper=self.max_range) 67 | 68 | # Set plot data on current axes 69 | for curve in self._curves.values(): 70 | data_x, data_y, plot, min_max_y = curve 71 | plot.set_data(numpy.array(data_x), numpy.array(data_y)) 72 | 73 | self._canvas.draw() 74 | -------------------------------------------------------------------------------- /kobuki_dashboard/src/kobuki_dashboard/dashboard.py: -------------------------------------------------------------------------------- 1 | import roslib;roslib.load_manifest('kobuki_dashboard') 2 | import rospy 3 | 4 | import diagnostic_msgs 5 | 6 | from rqt_robot_dashboard.dashboard import Dashboard 7 | from rqt_robot_dashboard.widgets import MonitorDashWidget, ConsoleDashWidget, MenuDashWidget, IconToolButton 8 | from QtWidgets import QMessageBox, QAction 9 | from python_qt_binding.QtCore import QSize 10 | 11 | from .battery_widget import BatteryWidget 12 | from .led_widget import LedWidget 13 | from .motor_widget import MotorWidget 14 | 15 | class KobukiDashboard(Dashboard): 16 | def setup(self, context): 17 | self.message = None 18 | 19 | self._dashboard_message = None 20 | self._last_dashboard_message_time = 0.0 21 | 22 | self._motor_widget = MotorWidget('/mobile_base/commands/motor_power') 23 | self._laptop_bat = BatteryWidget("Laptop") 24 | self._kobuki_bat = BatteryWidget("Kobuki") 25 | 26 | self._dashboard_agg_sub = rospy.Subscriber('diagnostics_agg', diagnostic_msgs.msg.DiagnosticArray, self.dashboard_callback) 27 | 28 | def get_widgets(self): 29 | leds = [LedWidget('/mobile_base/commands/led1'), LedWidget('/mobile_base/commands/led2')] 30 | return [[MonitorDashWidget(self.context), ConsoleDashWidget(self.context), self._motor_widget], leds, [self._laptop_bat, self._kobuki_bat]] 31 | 32 | def dashboard_callback(self, msg): 33 | self._dashboard_message = msg 34 | self._last_dashboard_message_time = rospy.get_time() 35 | 36 | laptop_battery_status = {} 37 | for status in msg.status: 38 | if status.name == "/Kobuki/Motor State": 39 | motor_state = int(status.values[0].value) 40 | self._motor_widget.update_state(motor_state) 41 | 42 | elif status.name == "/Power System/Battery": 43 | for value in status.values: 44 | if value.key == 'Percent': 45 | self._kobuki_bat.update_perc(float(value.value)) 46 | # This should be self._last_dashboard_message_time? 47 | # Is it even used graphically by the widget 48 | self._kobuki_bat.update_time(float(value.value)) 49 | elif value.key == "Charging State": 50 | if value.value == "Trickle Charging" or value.value == "Full Charging": 51 | self._kobuki_bat.set_charging(True) 52 | else: 53 | self._kobuki_bat.set_charging(False) 54 | elif status.name == "/Power System/Laptop Battery": 55 | for value in status.values: 56 | laptop_battery_status[value.key]=value.value 57 | 58 | if (laptop_battery_status): 59 | percentage = float(laptop_battery_status['Charge (Ah)'])/float(laptop_battery_status['Capacity (Ah)']) 60 | self._laptop_bat.update_perc(percentage*100) 61 | self._laptop_bat.update_time(percentage*100) 62 | charging_state = True if float(laptop_battery_status['Current (A)']) > 0.0 else False 63 | self._laptop_bat.set_charging(charging_state) 64 | 65 | def shutdown_dashboard(self): 66 | self._dashboard_agg_sub.unregister() 67 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/configuration_dock_widget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import roslib 11 | roslib.load_manifest('kobuki_qtestsuite') 12 | import rospy 13 | 14 | from python_qt_binding.QtCore import Signal,Slot 15 | try: # indigo 16 | from python_qt_binding.QtGui import QDockWidget 17 | except ImportError: # kinetic+ (pyqt5) 18 | from python_qt_binding.QtWidgets import QDockWidget 19 | from rqt_py_common.extended_combo_box import ExtendedComboBox 20 | 21 | # Local resource imports 22 | import detail.common_rc 23 | from detail.configuration_dock_ui import Ui_configuration_dock_widget 24 | 25 | class ConfigurationDockWidget(QDockWidget): 26 | 27 | def __init__(self, parent=None): 28 | super(ConfigurationDockWidget, self).__init__(parent) 29 | 30 | self._ui = Ui_configuration_dock_widget() 31 | #self._ui.setupUi(self) 32 | 33 | 34 | def setupUi(self): 35 | self._ui.setupUi(self) 36 | _, _, topic_types = rospy.get_master().getTopicTypes() 37 | cmd_vel_topics = [ topic[0] for topic in topic_types if topic[1] == 'geometry_msgs/Twist' ] 38 | self._ui.cmd_vel_topic_combo_box.setItems.emit(sorted(cmd_vel_topics)) 39 | #self.cmd_vel_publisher = rospy.Publisher(str(self.cmd_vel_topic_combo_box.currentText()), Twist) 40 | odom_topics = [ topic[0] for topic in topic_types if topic[1] == 'nav_msgs/Odometry' ] 41 | self._ui.odom_topic_combo_box.setItems.emit(sorted(odom_topics)) 42 | #self.odom_subscriber = rospy.Subscriber(str(self.odom_topic_combo_box.currentText()), Odometry, self.odometry_callback) 43 | core_sensor_topics = [ topic[0] for topic in topic_types if topic[1] == 'kobuki_msgs/SensorState' ] 44 | self._ui.core_topic_combo_box.setItems.emit(sorted(core_sensor_topics)) 45 | 46 | def cmd_vel_topic_name(self): 47 | return str(self._ui.cmd_vel_topic_combo_box.currentText()) 48 | 49 | def odom_topic_name(self): 50 | return str(self._ui.odom_topic_combo_box.currentText()) 51 | 52 | def core_sensors_topic_name(self): 53 | return str(self._ui.core_sensor_topic_combo_box.currentText()) 54 | 55 | def battery_topic_name(self): 56 | return str(self._ui.core_sensor_topic_combo_box.currentText() + '/' + battery) 57 | 58 | ########################################################################## 59 | # Slot Callbacks 60 | ########################################################################## 61 | @Slot(str) 62 | def on_cmd_vel_topic_combo_box_currentIndexChanged(self, topic_name): 63 | pass 64 | # This is probably a bit broken, need to test with more than just /cmd_vel so 65 | # there is more than one option. 66 | #self.cmd_vel_publisher = rospy.Publisher(str(self.cmd_vel_topic_combo_box.currentText()), Twist) 67 | 68 | @Slot(str) 69 | def on_odom_topic_combo_box_currentIndexChanged(self, topic_name): 70 | # Need to redo the subscriber here 71 | pass 72 | 73 | @Slot(str) 74 | def on_core_topic_combo_box_currentIndexChanged(self, topic_name): 75 | pass 76 | -------------------------------------------------------------------------------- /kobuki_desktop/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/configuration_dock.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | configuration_dock_widget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 592 10 | 385 11 | 12 | 13 | 14 | Configuration Dock 15 | 16 | 17 | 18 | 19 | 20 | 21 | Topics 22 | 23 | 24 | 25 | 26 | 27 | Cmd Vel 28 | 29 | 30 | 31 | 32 | 33 | 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | Odom 42 | 43 | 44 | 45 | 46 | 47 | 48 | false 49 | 50 | 51 | 52 | 53 | 54 | 55 | Core Sensors 56 | 57 | 58 | 59 | 60 | 61 | 62 | false 63 | 64 | 65 | 66 | 67 | 68 | 69 | Robot State 70 | 71 | 72 | 73 | 74 | 75 | 76 | false 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | Qt::Vertical 87 | 88 | 89 | 90 | 20 91 | 126 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | ExtendedComboBox 102 | QComboBox 103 |
rqt_py_common.extended_combo_box
104 |
105 |
106 | 107 | 108 |
109 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/testsuite_widget.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import roslib 11 | roslib.load_manifest('kobuki_qtestsuite') 12 | import rospy 13 | 14 | from python_qt_binding.QtCore import Signal,Slot 15 | try: # indigo 16 | from python_qt_binding.QtGui import QWidget 17 | except ImportError: # kinetic+ (pyqt5) 18 | from python_qt_binding.QtWidgets import QWidget 19 | #from rqt_py_common.extended_combo_box import ExtendedComboBox 20 | 21 | from geometry_msgs.msg import Twist 22 | from nav_msgs.msg import Odometry 23 | 24 | # Local resource imports 25 | import detail.common_rc 26 | from detail.testsuite_ui import Ui_testsuite_widget 27 | 28 | class TestSuiteWidget(QWidget): 29 | 30 | def __init__(self, parent=None): 31 | super(TestSuiteWidget, self).__init__(parent) 32 | self._ui = Ui_testsuite_widget() 33 | self._tabs = [] 34 | 35 | def setupUi(self): 36 | self._ui.setupUi(self) 37 | self._tabs = [self._ui.battery_profile_frame, 38 | self._ui.gyro_drift_frame, 39 | self._ui.payload_frame, 40 | self._ui.cliff_sensor_frame, 41 | self._ui.life_frame, 42 | self._ui.wandering_frame 43 | ] 44 | self._current_tab = self._tabs[self._ui.testsuite_tab_widget.currentIndex()] 45 | self._ui.configuration_dock.setupUi() 46 | self._ui.battery_profile_frame.setupUi(self._ui.configuration_dock.cmd_vel_topic_name()) 47 | self._ui.gyro_drift_frame.setupUi() 48 | self._ui.payload_frame.setupUi() 49 | self._ui.cliff_sensor_frame.setupUi() 50 | self._ui.life_frame.setupUi() 51 | self._ui.wandering_frame.setupUi() 52 | #self.cmd_vel_publisher = rospy.Publisher(self._ui.configuration_dock.cmd_vel_topic_name(), Twist) 53 | #self.odom_subscriber = rospy.Subscriber(self._ui.configuration_dock.odom_topic_name(), Odometry, self.odometry_callback) 54 | #################### 55 | # Slot Callbacks 56 | #################### 57 | self._ui.configuration_dock._ui.cmd_vel_topic_combo_box.currentIndexChanged[str].connect( 58 | self._ui.battery_profile_frame.on_cmd_vel_topic_combo_box_currentIndexChanged) 59 | 60 | def shutdown(self): 61 | self._ui.battery_profile_frame.shutdown() 62 | self._ui.gyro_drift_frame.shutdown() 63 | self._ui.payload_frame.shutdown() 64 | self._ui.cliff_sensor_frame.shutdown() 65 | self._ui.life_frame.shutdown() 66 | self._ui.wandering_frame.shutdown() 67 | 68 | ########################################################################## 69 | # Slot Callbacks 70 | ########################################################################## 71 | @Slot(str) 72 | def on_cmd_vel_topic_combo_box_currentIndexChanged(self, topic_name): 73 | # This is probably a bit broken, need to test with more than just /cmd_vel so 74 | # there is more than one option. 75 | print("Dude") 76 | self.cmd_vel_publisher = rospy.Publisher(str(self.cmd_vel_topic_combo_box.currentText()), Twist, queue_size=10) 77 | 78 | @Slot(str) 79 | def on_odom_topic_combo_box_currentIndexChanged(self, topic_name): 80 | # Need to redo the subscriber here 81 | pass 82 | 83 | @Slot(int) 84 | def on_testsuite_tab_widget_currentChanged(self, index): 85 | self._current_tab.hibernate() 86 | self._current_tab = self._tabs[self._ui.testsuite_tab_widget.currentIndex()] 87 | self._current_tab.restore() 88 | 89 | -------------------------------------------------------------------------------- /kobuki_gazebo/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /kobuki_dashboard/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/payload_frame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import os 11 | import numpy 12 | import operator 13 | from python_qt_binding.QtCore import Signal, Slot, pyqtSlot 14 | try: # indigo 15 | from python_qt_binding.QtGui import QFrame, QVBoxLayout 16 | except ImportError: # kinetic+ (pyqt5) 17 | from python_qt_binding.QtWidgets import QFrame, QVBoxLayout 18 | import math 19 | 20 | import rospy 21 | from qt_gui_py_common.worker_thread import WorkerThread 22 | from kobuki_testsuite import Square 23 | 24 | # Local resource imports 25 | import detail.common_rc 26 | import detail.text_rc 27 | from detail.payload_frame_ui import Ui_payload_frame 28 | 29 | ############################################################################## 30 | # Classes 31 | ############################################################################## 32 | 33 | class PayloadFrame(QFrame): 34 | def __init__(self, parent=None): 35 | super(PayloadFrame, self).__init__(parent) 36 | self._gyro_topic_name = '/mobile_base/sensors/imu_data' 37 | self._ui = Ui_payload_frame() 38 | self._motion = None 39 | self._motion_thread = None 40 | 41 | def setupUi(self): 42 | self._ui.setupUi(self) 43 | self._ui.start_button.setEnabled(True) 44 | self._ui.stop_button.setEnabled(False) 45 | 46 | def shutdown(self): 47 | ''' 48 | Used to terminate the plugin 49 | ''' 50 | rospy.loginfo("Kobuki TestSuite: payload frame shutdown") 51 | self._stop() 52 | 53 | ########################################################################## 54 | # Widget Management 55 | ########################################################################## 56 | 57 | def hibernate(self): 58 | ''' 59 | This gets called when the frame goes out of focus (tab switch). 60 | Disable everything to avoid running N tabs in parallel when in 61 | reality we are only running one. 62 | ''' 63 | self._stop() 64 | 65 | def restore(self): 66 | ''' 67 | Restore the frame after a hibernate. 68 | ''' 69 | pass 70 | 71 | ########################################################################## 72 | # Motion Callbacks 73 | ########################################################################## 74 | 75 | def _run_finished(self): 76 | self._motion_thread = None 77 | self._motion = None 78 | self._ui.start_button.setEnabled(True) 79 | self._ui.stop_button.setEnabled(False) 80 | 81 | ########################################################################## 82 | # Qt Callbacks 83 | ########################################################################## 84 | @Slot() 85 | def on_start_button_clicked(self): 86 | self._ui.start_button.setEnabled(False) 87 | self._ui.stop_button.setEnabled(True) 88 | self._motion = Square('/mobile_base/commands/velocity', '/odom', self._gyro_topic_name) 89 | self._motion.init(self._ui.speed_spinbox.value(), self._ui.distance_spinbox.value()) 90 | self._motion_thread = WorkerThread(self._motion.execute, self._run_finished) 91 | self._motion_thread.start() 92 | 93 | @Slot() 94 | def on_stop_button_clicked(self): 95 | self._stop() 96 | 97 | def _stop(self): 98 | if self._motion: 99 | self._motion.stop() 100 | if self._motion_thread: 101 | self._motion_thread.wait() 102 | self._motion_thread = None 103 | if self._motion: 104 | self._motion = None 105 | self._ui.start_button.setEnabled(True) 106 | self._ui.stop_button.setEnabled(False) 107 | 108 | @pyqtSlot(float) 109 | def on_speed_spinbox_valueChanged(self, value): 110 | if self._motion: 111 | self._motion.init(self._ui.speed_spinbox.value(), self._ui.distance_spinbox.value()) 112 | 113 | @pyqtSlot(float) 114 | def on_distance_spinbox_valueChanged(self, value): 115 | if self._motion: 116 | self._motion.init(self._ui.speed_spinbox.value(), self._ui.distance_spinbox.value()) 117 | 118 | ########################################################################## 119 | # Ros Callbacks 120 | ########################################################################## 121 | 122 | #def robot_state_callback(self, data): 123 | # if data.state == RobotStateEvent.OFFLINE: 124 | # self.stop() 125 | 126 | # 127 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/battery_profile_frame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | battery_profile_frame 4 | 5 | 6 | 7 | 0 8 | 0 9 | 791 10 | 414 11 | 12 | 13 | 14 | Frame 15 | 16 | 17 | QFrame::StyledPanel 18 | 19 | 20 | QFrame::Raised 21 | 22 | 23 | 24 | 25 | 26 | QTextEdit::AutoAll 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | qrc:/text/battery_profile.html 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | Battery Profile 48 | 49 | 50 | 51 | 52 | 53 | 54 | Controls 55 | 56 | 57 | 58 | 59 | 60 | Qt::Horizontal 61 | 62 | 63 | 64 | 96 65 | 17 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 74 | 75 | 76 | 77 | 78 | 79 | rad/s 80 | 81 | 82 | 3.140000000000000 83 | 84 | 85 | 0.100000000000000 86 | 87 | 88 | 1.200000000000000 89 | 90 | 91 | 92 | 93 | 94 | 95 | Qt::Horizontal 96 | 97 | 98 | 99 | 96 100 | 20 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | Qt::Horizontal 109 | 110 | 111 | 112 | 181 113 | 20 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | Start 122 | 123 | 124 | 125 | 126 | 127 | 128 | Stop 129 | 130 | 131 | 132 | 133 | 134 | 135 | Qt::Horizontal 136 | 137 | 138 | 139 | 167 140 | 20 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/cliff_sensor_frame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | cliff_sensor_frame 4 | 5 | 6 | 7 | 0 8 | 0 9 | 791 10 | 414 11 | 12 | 13 | 14 | Frame 15 | 16 | 17 | QFrame::StyledPanel 18 | 19 | 20 | QFrame::Raised 21 | 22 | 23 | 24 | 25 | 26 | QTextEdit::AutoAll 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | qrc:/text/cliff_sensor.html 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | Controls 48 | 49 | 50 | 51 | 52 | 53 | Qt::Horizontal 54 | 55 | 56 | 57 | 96 58 | 17 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Speed 67 | 68 | 69 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 70 | 71 | 72 | 73 | 74 | 75 | 76 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 77 | 78 | 79 | 80 | 81 | 82 | m/s 83 | 84 | 85 | 0.700000000000000 86 | 87 | 88 | 0.100000000000000 89 | 90 | 91 | 0.200000000000000 92 | 93 | 94 | 95 | 96 | 97 | 98 | Qt::Horizontal 99 | 100 | 101 | 102 | 96 103 | 20 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | Qt::Horizontal 112 | 113 | 114 | 115 | 181 116 | 20 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | Start 125 | 126 | 127 | 128 | 129 | 130 | 131 | Stop 132 | 133 | 134 | 135 | 136 | 137 | 138 | Qt::Horizontal 139 | 140 | 141 | 142 | 167 143 | 20 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/wandering_frame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import os 11 | from python_qt_binding.QtCore import Signal, Slot, pyqtSlot 12 | try: # indigo 13 | from python_qt_binding.QtGui import QFrame 14 | except ImportError: # kinetic+ (pyqt5) 15 | from python_qt_binding.QtWidgets import QFrame 16 | import math 17 | 18 | import rospy 19 | from kobuki_testsuite import SafeWandering 20 | from kobuki_msgs.msg import BumperEvent 21 | 22 | # Local resource imports 23 | import detail.common_rc 24 | import detail.text_rc 25 | from detail.wandering_frame_ui import Ui_wandering_frame 26 | from qt_gui_py_common.worker_thread import WorkerThread 27 | 28 | ############################################################################## 29 | # Classes 30 | ############################################################################## 31 | 32 | class WanderingFrame(QFrame): 33 | def __init__(self, parent=None): 34 | super(WanderingFrame, self).__init__(parent) 35 | self._ui = Ui_wandering_frame() 36 | self.bump_subscriber = rospy.Subscriber('/mobile_base/events/bumper', BumperEvent, self.bumper_event_callback) 37 | self._motion = SafeWandering('/mobile_base/commands/velocity','/odom', '/mobile_base/events/bumper', '/mobile_base/events/cliff') 38 | self._motion_thread = None 39 | self._is_alive = False # Used to indicate whether the frame is alive or not (see hibernate/restore methods) 40 | 41 | def setupUi(self): 42 | self._ui.setupUi(self) 43 | self._ui.start_button.setEnabled(True) 44 | self._ui.stop_button.setEnabled(False) 45 | self._motion.init(self._ui.speed_spinbox.value(), -0.1, self._ui.angular_speed_spinbox.value()) 46 | 47 | def shutdown(self): 48 | ''' 49 | Used to terminate the plugin 50 | ''' 51 | rospy.loginfo("Kobuki TestSuite: wandering test shutdown") 52 | self._motion.shutdown() 53 | self.bump_subscriber.unregister() 54 | 55 | ########################################################################## 56 | # Widget Management 57 | ########################################################################## 58 | 59 | def hibernate(self): 60 | ''' 61 | This gets called when the frame goes out of focus (tab switch). 62 | Disable everything to avoid running N tabs in parallel when in 63 | reality we are only running one. 64 | ''' 65 | pass 66 | 67 | def restore(self): 68 | ''' 69 | Restore the frame after a hibernate. 70 | ''' 71 | pass 72 | 73 | ########################################################################## 74 | # Motion Callbacks 75 | ########################################################################## 76 | 77 | 78 | def stop(self): 79 | self._motion.stop() 80 | self._ui.start_button.setEnabled(True) 81 | self._ui.stop_button.setEnabled(False) 82 | 83 | def _run_finished(self): 84 | self._ui.start_button.setEnabled(True) 85 | self._ui.stop_button.setEnabled(False) 86 | 87 | ########################################################################## 88 | # Qt Callbacks 89 | ########################################################################## 90 | @Slot() 91 | def on_start_button_clicked(self): 92 | self._ui.start_button.setEnabled(False) 93 | self._ui.stop_button.setEnabled(True) 94 | self._motion_thread = WorkerThread(self._motion.execute, self._run_finished) 95 | self._motion_thread.start() 96 | 97 | @Slot() 98 | def on_stop_button_clicked(self): 99 | self.stop() 100 | 101 | @pyqtSlot(float) 102 | def on_speed_spinbox_valueChanged(self, value): 103 | # could use value, but easy to set like this 104 | self._motion.init(self._ui.speed_spinbox.value(), -0.1, self._ui.angular_speed_spinbox.value()) 105 | 106 | @pyqtSlot(float) 107 | def on_angular_speed_spinbox_valueChanged(self, value): 108 | # could use value, but easy to set like this 109 | self._motion.init(self._ui.speed_spinbox.value(), -0.1, self._ui.angular_speed_spinbox.value()) 110 | 111 | ########################################################################## 112 | # Ros Callbacks 113 | ########################################################################## 114 | def bumper_event_callback(self, msg): 115 | if msg.state == BumperEvent.PRESSED: 116 | if msg.bumper == BumperEvent.LEFT: 117 | self._ui.left_bump_counter_lcd.display(self._ui.left_bump_counter_lcd.intValue()+1) 118 | elif msg.bumper == BumperEvent.RIGHT: 119 | self._ui.right_bump_counter_lcd.display(self._ui.right_bump_counter_lcd.intValue()+1) 120 | else: 121 | self._ui.centre_bump_counter_lcd.display(self._ui.centre_bump_counter_lcd.intValue()+1) 122 | 123 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/gyro_drift_frame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | gyro_drift_frame 4 | 5 | 6 | 7 | 0 8 | 0 9 | 791 10 | 414 11 | 12 | 13 | 14 | Frame 15 | 16 | 17 | QFrame::StyledPanel 18 | 19 | 20 | QFrame::Raised 21 | 22 | 23 | 24 | 25 | 26 | QTextEdit::AutoAll 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | qrc:/text/gyro_drift.html 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | Gyro vs Laser 48 | 49 | 50 | 51 | 52 | 53 | 54 | Controls 55 | 56 | 57 | 58 | 59 | 60 | Qt::Horizontal 61 | 62 | 63 | 64 | 96 65 | 17 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | Angular Speed 74 | 75 | 76 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 77 | 78 | 79 | 80 | 81 | 82 | 83 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 84 | 85 | 86 | 87 | 88 | 89 | rad/s 90 | 91 | 92 | 3.140000000000000 93 | 94 | 95 | 0.100000000000000 96 | 97 | 98 | 0.400000000000000 99 | 100 | 101 | 102 | 103 | 104 | 105 | Qt::Horizontal 106 | 107 | 108 | 109 | 96 110 | 20 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | Qt::Horizontal 119 | 120 | 121 | 122 | 181 123 | 20 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | Start 132 | 133 | 134 | 135 | 136 | 137 | 138 | Stop 139 | 140 | 141 | 142 | 143 | 144 | 145 | Qt::Horizontal 146 | 147 | 148 | 149 | 167 150 | 20 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/cliff_sensor_frame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import os 11 | import numpy 12 | import operator 13 | from python_qt_binding.QtCore import Signal, Slot, pyqtSlot 14 | try: # indigo 15 | from python_qt_binding.QtGui import QFrame, QVBoxLayout 16 | except ImportError: # kinetic+ (pyqt5) 17 | from python_qt_binding.QtWidgets import QFrame, QVBoxLayout 18 | import math 19 | 20 | import roslib 21 | roslib.load_manifest('kobuki_qtestsuite') 22 | import rospy 23 | from qt_gui_py_common.worker_thread import WorkerThread 24 | from kobuki_testsuite import TravelForward 25 | 26 | # Local resource imports 27 | import detail.common_rc 28 | import detail.text_rc 29 | from detail.cliff_sensor_frame_ui import Ui_cliff_sensor_frame 30 | 31 | ############################################################################## 32 | # Classes 33 | ############################################################################## 34 | 35 | class CliffSensorFrame(QFrame): 36 | STATE_FORWARD = "forward" 37 | STATE_BACKWARD = "backward" 38 | STATE_STOPPED = "stopped" 39 | 40 | def __init__(self, parent=None): 41 | super(CliffSensorFrame, self).__init__(parent) 42 | self._ui = Ui_cliff_sensor_frame() 43 | self._motion = TravelForward('/mobile_base/commands/velocity','/odom', '/mobile_base/events/cliff') 44 | self._motion_thread = None 45 | self._distance = 1.2 46 | self._state = CliffSensorFrame.STATE_FORWARD 47 | self._is_alive = False # Used to indicate whether the frame is alive or not (see hibernate/restore methods) 48 | 49 | 50 | def setupUi(self): 51 | self._ui.setupUi(self) 52 | self._ui.start_button.setEnabled(True) 53 | self._ui.stop_button.setEnabled(False) 54 | self._motion.init(self._ui.speed_spinbox.value(), self._distance) 55 | 56 | def shutdown(self): 57 | ''' 58 | Used to terminate the plugin 59 | ''' 60 | rospy.loginfo("Kobuki TestSuite: cliff sensor shutdown") 61 | self._motion.shutdown() 62 | 63 | ########################################################################## 64 | # Widget Management 65 | ########################################################################## 66 | 67 | def hibernate(self): 68 | ''' 69 | This gets called when the frame goes out of focus (tab switch). 70 | Disable everything to avoid running N tabs in parallel when in 71 | reality we are only running one. 72 | ''' 73 | pass 74 | 75 | def restore(self): 76 | ''' 77 | Restore the frame after a hibernate. 78 | ''' 79 | pass 80 | 81 | 82 | ########################################################################## 83 | # Motion Callbacks 84 | ########################################################################## 85 | 86 | def _run_finished(self): 87 | if self._state == CliffSensorFrame.STATE_STOPPED: 88 | return 89 | elif self._state == CliffSensorFrame.STATE_FORWARD: 90 | self._state = CliffSensorFrame.STATE_BACKWARD 91 | self._motion.init(-self._motion.speed, 0.2) 92 | self._motion_thread = WorkerThread(self._motion.execute, self._run_finished) 93 | self._motion_thread.start() 94 | else: 95 | self._state = CliffSensorFrame.STATE_FORWARD 96 | self._motion.init(-self._motion.speed, self._distance) 97 | self._motion_thread = WorkerThread(self._motion.execute, self._run_finished) 98 | self._motion_thread.start() 99 | 100 | ########################################################################## 101 | # Qt Callbacks 102 | ########################################################################## 103 | @Slot() 104 | def on_start_button_clicked(self): 105 | self._ui.start_button.setEnabled(False) 106 | self._ui.stop_button.setEnabled(True) 107 | self._state = CliffSensorFrame.STATE_FORWARD 108 | self._motion_thread = WorkerThread(self._motion.execute, self._run_finished) 109 | self._motion_thread.start() 110 | 111 | @Slot() 112 | def on_stop_button_clicked(self): 113 | self._state = CliffSensorFrame.STATE_STOPPED 114 | self.stop() 115 | 116 | def stop(self): 117 | self._motion.stop() 118 | if self._motion_thread: 119 | self._motion_thread.wait() 120 | self._ui.start_button.setEnabled(True) 121 | self._ui.stop_button.setEnabled(False) 122 | 123 | @pyqtSlot(float) 124 | def on_speed_spinbox_valueChanged(self, value): 125 | self._motion.init(self._ui.speed_spinbox.value(), self._distance) 126 | 127 | ########################################################################## 128 | # Ros Callbacks 129 | ########################################################################## 130 | 131 | #def robot_state_callback(self, data): 132 | # if data.state == RobotStateEvent.OFFLINE: 133 | # self.stop() 134 | 135 | # 136 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/life_frame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import os 11 | import numpy 12 | import operator 13 | #import python_qt_binding.QtCore 14 | from python_qt_binding.QtCore import QObject, Signal, Slot, pyqtSlot, QTimer 15 | try: # indigo 16 | from python_qt_binding.QtGui import QFrame, QVBoxLayout 17 | except ImportError: # kinetic+ (pyqt5) 18 | from python_qt_binding.QtWidgets import QFrame, QVBoxLayout 19 | import math 20 | 21 | import rospy 22 | from qt_gui_py_common.worker_thread import WorkerThread 23 | from kobuki_testsuite import Rotate 24 | 25 | # Local resource imports 26 | import detail.common_rc 27 | import detail.text_rc 28 | from detail.life_frame_ui import Ui_life_frame 29 | 30 | ############################################################################## 31 | # Classes 32 | ############################################################################## 33 | 34 | class LifeFrame(QFrame): 35 | STATE_STOPPED = "stopped" 36 | STATE_RUN = "running" 37 | STATE_IDLE = "idle" 38 | 39 | def __init__(self, parent=None): 40 | super(LifeFrame, self).__init__(parent) 41 | self._ui = Ui_life_frame() 42 | self._motion = Rotate('/mobile_base/commands/velocity') 43 | self._motion_thread = None 44 | self._timer = QTimer() 45 | #self._timer.setInterval(60000) #60s 46 | self._timer.setInterval(250) #60s 47 | self._timer.timeout.connect(self.update_progress_callback) 48 | self._state = LifeFrame.STATE_STOPPED 49 | self._is_alive = False # Used to indicate whether the frame is alive or not (see hibernate/restore methods) 50 | 51 | def setupUi(self): 52 | self._ui.setupUi(self) 53 | self._ui.start_button.setEnabled(True) 54 | self._ui.stop_button.setEnabled(False) 55 | self._motion.init(self._ui.angular_speed_spinbox.value()) 56 | 57 | def shutdown(self): 58 | ''' 59 | Used to terminate the plugin 60 | ''' 61 | rospy.loginfo("Kobuki TestSuite: life frame shutdown") 62 | self._motion.shutdown() 63 | 64 | ########################################################################## 65 | # Widget Management 66 | ########################################################################## 67 | 68 | def hibernate(self): 69 | ''' 70 | This gets called when the frame goes out of focus (tab switch). 71 | Disable everything to avoid running N tabs in parallel when in 72 | reality we are only running one. 73 | ''' 74 | pass 75 | 76 | def restore(self): 77 | ''' 78 | Restore the frame after a hibernate. 79 | ''' 80 | pass 81 | 82 | 83 | ########################################################################## 84 | # Motion Callbacks 85 | ########################################################################## 86 | 87 | def start(self): 88 | self._state = LifeFrame.STATE_RUN 89 | self._ui.run_progress.reset() 90 | self._ui.idle_progress.reset() 91 | self._motion_thread = WorkerThread(self._motion.execute, None) 92 | self._motion_thread.start() 93 | 94 | def stop(self): 95 | self._state = LifeFrame.STATE_STOPPED 96 | self._motion.stop() 97 | if self._motion_thread: 98 | self._motion_thread.wait() 99 | 100 | ########################################################################## 101 | # Qt Callbacks 102 | ########################################################################## 103 | @Slot() 104 | def on_start_button_clicked(self): 105 | self._ui.start_button.setEnabled(False) 106 | self._ui.stop_button.setEnabled(True) 107 | self._timer.start() 108 | self.start() 109 | 110 | @Slot() 111 | def on_stop_button_clicked(self): 112 | self.stop() 113 | self._timer.stop() 114 | self._ui.start_button.setEnabled(True) 115 | self._ui.stop_button.setEnabled(False) 116 | 117 | @pyqtSlot(float) 118 | def on_angular_speed_spinbox_valueChanged(self, value): 119 | self._motion.init(self._ui.angular_speed_spinbox.value()) 120 | 121 | ########################################################################## 122 | # Timer Callbacks 123 | ########################################################################## 124 | 125 | @Slot() 126 | def update_progress_callback(self): 127 | if self._state == LifeFrame.STATE_RUN: 128 | new_value = self._ui.run_progress.value()+1 129 | if new_value == self._ui.run_progress.maximum(): 130 | print(" Switching to idle") 131 | self._motion.stop() 132 | self._state = LifeFrame.STATE_IDLE 133 | else: 134 | self._ui.run_progress.setValue(new_value) 135 | if self._state == LifeFrame.STATE_IDLE: 136 | new_value = self._ui.idle_progress.value()+1 137 | if new_value == self._ui.idle_progress.maximum(): 138 | print(" Switching to run") 139 | self.start() 140 | else: 141 | self._ui.idle_progress.setValue(new_value) 142 | 143 | 144 | # 145 | -------------------------------------------------------------------------------- /kobuki_gazebo_plugins/src/gazebo_ros_kobuki.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "kobuki_gazebo_plugins/gazebo_ros_kobuki.h" 8 | #if GAZEBO_MAJOR_VERSION >= 9 9 | // #include 10 | #include 11 | #include 12 | #else 13 | #include 14 | #endif 15 | 16 | namespace gazebo 17 | { 18 | 19 | 20 | GazeboRosKobuki::GazeboRosKobuki() : shutdown_requested_(false) 21 | { 22 | // Initialise variables 23 | wheel_speed_cmd_[LEFT] = 0.0; 24 | wheel_speed_cmd_[RIGHT] = 0.0; 25 | cliff_detected_left_ = false; 26 | cliff_detected_center_ = false; 27 | cliff_detected_right_ = false; 28 | } 29 | 30 | GazeboRosKobuki::~GazeboRosKobuki() 31 | { 32 | // rosnode_->shutdown(); 33 | shutdown_requested_ = true; 34 | // Wait for spinner thread to end 35 | // ros_spinner_thread_->join(); 36 | 37 | // delete spinner_thread_; 38 | // delete rosnode_; 39 | } 40 | 41 | void GazeboRosKobuki::Load(physics::ModelPtr parent, sdf::ElementPtr sdf) 42 | { 43 | model_ = parent; 44 | if (!model_) 45 | { 46 | ROS_ERROR_STREAM("Invalid model pointer! [" << node_name_ << "]"); 47 | return; 48 | } 49 | 50 | gazebo_ros_ = GazeboRosPtr(new GazeboRos(model_, sdf, "Kobuki")); 51 | sdf_ = sdf; 52 | gazebo_ros_->getParameter(this->update_rate_, "update_rate", 0.0); 53 | 54 | // Make sure the ROS node for Gazebo has already been initialized 55 | if (!ros::isInitialized()) 56 | { 57 | ROS_FATAL_STREAM("A ROS node for Gazebo has not been initialized, unable to load plugin. " 58 | << "Load the Gazebo system plugin 'libgazebo_ros_api_plugin.so' in the gazebo_ros package)"); 59 | return; 60 | } 61 | 62 | // Get then name of the parent model and use it as node name 63 | std::string model_name = sdf->GetParent()->Get("name"); 64 | gzdbg << "Plugin model name: " << model_name << "\n"; 65 | node_name_ = model_name; 66 | world_ = parent->GetWorld(); 67 | 68 | prepareMotorPower(); 69 | preparePublishTf(); 70 | 71 | if(prepareJointState() == false) 72 | return; 73 | if(prepareWheelAndTorque() == false) 74 | return; 75 | 76 | prepareOdom(); 77 | 78 | if(prepareVelocityCommand() == false) 79 | return; 80 | if(prepareCliffSensor() == false) 81 | return; 82 | if(prepareBumper() == false) 83 | return; 84 | if(prepareWheelDrop() == false) 85 | return; 86 | if(prepareIMU() == false) 87 | return; 88 | 89 | setupRosApi(model_name); 90 | 91 | #if GAZEBO_MAJOR_VERSION >= 9 92 | prev_update_time_ = world_->SimTime(); 93 | #else 94 | prev_update_time_ = world_->GetSimTime(); 95 | #endif 96 | 97 | ROS_INFO_STREAM("GazeboRosKobuki plugin ready to go! [" << node_name_ << "]"); 98 | update_connection_ = event::Events::ConnectWorldUpdateEnd(boost::bind(&GazeboRosKobuki::OnUpdate, this)); 99 | 100 | } 101 | 102 | 103 | void GazeboRosKobuki::OnUpdate() 104 | { 105 | /* 106 | * First process ROS callbacks 107 | */ 108 | ros::spinOnce(); 109 | 110 | /* 111 | * Update current time and time step 112 | */ 113 | common::Time time_now; 114 | #if GAZEBO_MAJOR_VERSION >= 9 115 | time_now = world_->SimTime(); 116 | #else 117 | time_now = world_->GetSimTime(); 118 | #endif 119 | 120 | if (time_now < prev_update_time_) { 121 | ROS_WARN_NAMED("gazebo_ros_kobuki", "Negative update time difference detected."); 122 | prev_update_time_ = time_now; 123 | } 124 | 125 | common::Time step_time = time_now - prev_update_time_; 126 | 127 | // propagate wheel velocity commands at the full simulation rate 128 | propagateVelocityCommands(); 129 | 130 | // publish rate control 131 | if (this->update_rate_ > 0 && step_time.Double() < (1.0 / this->update_rate_)) { 132 | return; 133 | } 134 | 135 | prev_update_time_ = time_now; 136 | 137 | updateJointState(); 138 | updateOdometry(step_time); 139 | updateIMU(); 140 | updateCliffSensor(); 141 | updateBumper(); 142 | updateWheelDrop(); 143 | pubSensorState(); 144 | } 145 | 146 | void GazeboRosKobuki::spin() 147 | { 148 | ros::Rate r(10); 149 | while(ros::ok() && !shutdown_requested_) 150 | { 151 | r.sleep(); 152 | } 153 | } 154 | 155 | void GazeboRosKobuki::motorPowerCB(const kobuki_msgs::MotorPowerPtr &msg) 156 | { 157 | if ((msg->state == kobuki_msgs::MotorPower::ON) && (!motors_enabled_)) 158 | { 159 | motors_enabled_ = true; 160 | ROS_INFO_STREAM("Motors fired up. [" << node_name_ << "]"); 161 | } 162 | else if ((msg->state == kobuki_msgs::MotorPower::OFF) && (motors_enabled_)) 163 | { 164 | motors_enabled_ = false; 165 | ROS_INFO_STREAM("Motors taking a rest. [" << node_name_ << "]"); 166 | } 167 | } 168 | 169 | void GazeboRosKobuki::cmdVelCB(const geometry_msgs::TwistConstPtr &msg) 170 | { 171 | #if GAZEBO_MAJOR_VERSION >= 9 172 | last_cmd_vel_time_ = world_->SimTime(); 173 | #else 174 | last_cmd_vel_time_ = world_->GetSimTime(); 175 | #endif 176 | 177 | wheel_speed_cmd_[LEFT] = msg->linear.x - msg->angular.z * (wheel_sep_) / 2; 178 | wheel_speed_cmd_[RIGHT] = msg->linear.x + msg->angular.z * (wheel_sep_) / 2; 179 | } 180 | 181 | void GazeboRosKobuki::resetOdomCB(const std_msgs::EmptyConstPtr &msg) 182 | { 183 | odom_pose_[0] = 0.0; 184 | odom_pose_[1] = 0.0; 185 | odom_pose_[2] = 0.0; 186 | } 187 | 188 | // Register this plugin with the simulator 189 | GZ_REGISTER_MODEL_PLUGIN(GazeboRosKobuki); 190 | 191 | } // namespace gazebo 192 | -------------------------------------------------------------------------------- /kobuki_gazebo_plugins/.cproject: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /kobuki_rviz_launchers/rviz/robot.rviz: -------------------------------------------------------------------------------- 1 | Panels: 2 | - Class: rviz/Displays 3 | Help Height: 78 4 | Name: Displays 5 | Property Tree Widget: 6 | Expanded: 7 | - /Global Options1 8 | - /Status1 9 | Splitter Ratio: 0.5 10 | Tree Height: 565 11 | - Class: rviz/Selection 12 | Name: Selection 13 | - Class: rviz/Tool Properties 14 | Expanded: 15 | - /2D Pose Estimate1 16 | - /2D Nav Goal1 17 | - /Publish Point1 18 | Name: Tool Properties 19 | Splitter Ratio: 0.588679 20 | - Class: rviz/Views 21 | Expanded: 22 | - /Current View1 23 | Name: Views 24 | Splitter Ratio: 0.5 25 | - Class: rviz/Time 26 | Experimental: false 27 | Name: Time 28 | SyncMode: 0 29 | SyncSource: "" 30 | Visualization Manager: 31 | Class: "" 32 | Displays: 33 | - Alpha: 0.5 34 | Cell Size: 1 35 | Class: rviz/Grid 36 | Color: 160; 160; 164 37 | Enabled: true 38 | Line Style: 39 | Line Width: 0.03 40 | Value: Lines 41 | Name: Grid 42 | Normal Cell Count: 0 43 | Offset: 44 | X: 0 45 | Y: 0 46 | Z: 0 47 | Plane: XY 48 | Plane Cell Count: 10 49 | Reference Frame: 50 | Value: true 51 | - Alpha: 1 52 | Class: rviz/RobotModel 53 | Collision Enabled: false 54 | Enabled: true 55 | Links: 56 | All Links Enabled: true 57 | Expand Joint Details: false 58 | Expand Link Details: false 59 | Expand Tree: false 60 | Link Tree Style: Links in Alphabetic Order 61 | base_footprint: 62 | Alpha: 1 63 | Show Axes: false 64 | Show Trail: false 65 | base_link: 66 | Alpha: 1 67 | Show Axes: false 68 | Show Trail: false 69 | Value: true 70 | caster_back_link: 71 | Alpha: 1 72 | Show Axes: false 73 | Show Trail: false 74 | Value: true 75 | caster_front_link: 76 | Alpha: 1 77 | Show Axes: false 78 | Show Trail: false 79 | Value: true 80 | cliff_sensor_front_link: 81 | Alpha: 1 82 | Show Axes: false 83 | Show Trail: false 84 | cliff_sensor_left_link: 85 | Alpha: 1 86 | Show Axes: false 87 | Show Trail: false 88 | cliff_sensor_right_link: 89 | Alpha: 1 90 | Show Axes: false 91 | Show Trail: false 92 | gyro_link: 93 | Alpha: 1 94 | Show Axes: false 95 | Show Trail: false 96 | wheel_left_link: 97 | Alpha: 1 98 | Show Axes: false 99 | Show Trail: false 100 | Value: true 101 | wheel_right_link: 102 | Alpha: 1 103 | Show Axes: false 104 | Show Trail: false 105 | Value: true 106 | Name: RobotModel 107 | Robot Description: robot_description 108 | TF Prefix: "" 109 | Update Interval: 0 110 | Value: true 111 | Visual Enabled: true 112 | Enabled: true 113 | Global Options: 114 | Background Color: 48; 48; 48 115 | Fixed Frame: odom 116 | Frame Rate: 30 117 | Name: root 118 | Tools: 119 | - Class: rviz/Interact 120 | Hide Inactive Objects: true 121 | - Class: rviz/MoveCamera 122 | - Class: rviz/Select 123 | - Class: rviz/FocusCamera 124 | - Class: rviz/Measure 125 | - Class: rviz/SetInitialPose 126 | Topic: /initialpose 127 | - Class: rviz/SetGoal 128 | Topic: /move_base_simple/goal 129 | - Class: rviz/PublishPoint 130 | Single click: true 131 | Topic: /clicked_point 132 | Value: true 133 | Views: 134 | Current: 135 | Class: rviz/Orbit 136 | Distance: 1.29337 137 | Focal Point: 138 | X: 0 139 | Y: 0 140 | Z: 0 141 | Name: Current View 142 | Near Clip Distance: 0.01 143 | Pitch: 0.785398 144 | Target Frame: 145 | Value: Orbit (rviz) 146 | Yaw: 0.785398 147 | Saved: ~ 148 | Window Geometry: 149 | Displays: 150 | collapsed: false 151 | Height: 846 152 | Hide Left Dock: false 153 | Hide Right Dock: false 154 | QMainWindow State: 000000ff00000000fd00000004000000000000013c000002bffc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000006901000005fb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c0061007900730100000032000002bf000000d701000005fb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000010f000002bffc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a005600690065007700730100000032000002bf000000a901000005fb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e10000019700000003000004b00000003efc0100000002fb0000000800540069006d00650100000000000004b00000024c01000005fb0000000800540069006d006501000000000000045000000000000000000000025f000002bf00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000 155 | Selection: 156 | collapsed: false 157 | Time: 158 | collapsed: false 159 | Tool Properties: 160 | collapsed: false 161 | Views: 162 | collapsed: false 163 | Width: 1200 164 | X: 405 165 | Y: 50 166 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/climbing_frame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | climbing_frame 4 | 5 | 6 | 7 | 0 8 | 0 9 | 791 10 | 414 11 | 12 | 13 | 14 | Frame 15 | 16 | 17 | QFrame::StyledPanel 18 | 19 | 20 | QFrame::Raised 21 | 22 | 23 | 24 | 25 | 26 | QTextEdit::AutoAll 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | qrc:/text/climbing.html 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | Controls 48 | 49 | 50 | 51 | 52 | 53 | Qt::Horizontal 54 | 55 | 56 | 57 | 96 58 | 17 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Speed 67 | 68 | 69 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 70 | 71 | 72 | 73 | 74 | 75 | 76 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 77 | 78 | 79 | 80 | 81 | 82 | m/s 83 | 84 | 85 | 0.700000000000000 86 | 87 | 88 | 0.100000000000000 89 | 90 | 91 | 0.200000000000000 92 | 93 | 94 | 95 | 96 | 97 | 98 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 99 | 100 | 101 | 102 | 103 | 104 | m 105 | 106 | 107 | 2.000000000000000 108 | 109 | 110 | 0.100000000000000 111 | 112 | 113 | 1.000000000000000 114 | 115 | 116 | 117 | 118 | 119 | 120 | Distance 121 | 122 | 123 | 124 | 125 | 126 | 127 | Qt::Horizontal 128 | 129 | 130 | 131 | 96 132 | 20 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | Qt::Horizontal 141 | 142 | 143 | 144 | 181 145 | 20 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | Start 154 | 155 | 156 | 157 | 158 | 159 | 160 | Stop 161 | 162 | 163 | 164 | 165 | 166 | 167 | Qt::Horizontal 168 | 169 | 170 | 171 | 167 172 | 20 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/payload_frame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | payload_frame 4 | 5 | 6 | 7 | 0 8 | 0 9 | 791 10 | 414 11 | 12 | 13 | 14 | Frame 15 | 16 | 17 | QFrame::StyledPanel 18 | 19 | 20 | QFrame::Raised 21 | 22 | 23 | 24 | 25 | 26 | QTextEdit::AutoAll 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | qrc:/text/payload.html 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | Controls 48 | 49 | 50 | 51 | 52 | 53 | Qt::Horizontal 54 | 55 | 56 | 57 | 96 58 | 17 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Speed 67 | 68 | 69 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 70 | 71 | 72 | 73 | 74 | 75 | 76 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 77 | 78 | 79 | 80 | 81 | 82 | m/s 83 | 84 | 85 | 0.700000000000000 86 | 87 | 88 | 0.100000000000000 89 | 90 | 91 | 0.300000000000000 92 | 93 | 94 | 95 | 96 | 97 | 98 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 99 | 100 | 101 | 102 | 103 | 104 | m 105 | 106 | 107 | 2.000000000000000 108 | 109 | 110 | 0.100000000000000 111 | 112 | 113 | 1.000000000000000 114 | 115 | 116 | 117 | 118 | 119 | 120 | Side Length 121 | 122 | 123 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 124 | 125 | 126 | 127 | 128 | 129 | 130 | Qt::Horizontal 131 | 132 | 133 | 134 | 96 135 | 20 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | Stop 144 | 145 | 146 | 147 | 148 | 149 | 150 | Qt::Horizontal 151 | 152 | 153 | 154 | 181 155 | 20 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | Start 164 | 165 | 166 | 167 | 168 | 169 | 170 | Qt::Horizontal 171 | 172 | 173 | 174 | 167 175 | 20 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/testsuite.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | testsuite_widget 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1021 10 | 562 11 | 12 | 13 | 14 | Kobuki Test Suite 15 | 16 | 17 | 18 | :/images/kobuki_icon.png:/images/kobuki_icon.png 19 | 20 | 21 | 22 | 23 | 24 | true 25 | 26 | 27 | 0 28 | 29 | 30 | 31 | Battery Profile 32 | 33 | 34 | 35 | 36 | 37 | QFrame::NoFrame 38 | 39 | 40 | QFrame::Raised 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Gyro Drift 49 | 50 | 51 | 52 | 53 | 54 | QFrame::NoFrame 55 | 56 | 57 | QFrame::Raised 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | Payload 66 | 67 | 68 | 69 | 70 | 71 | QFrame::NoFrame 72 | 73 | 74 | QFrame::Raised 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Cliff 83 | 84 | 85 | 86 | 87 | 88 | QFrame::NoFrame 89 | 90 | 91 | QFrame::Raised 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | Life 100 | 101 | 102 | 103 | 104 | 105 | QFrame::NoFrame 106 | 107 | 108 | QFrame::Raised 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | Wander 117 | 118 | 119 | 120 | 121 | 122 | QFrame::NoFrame 123 | 124 | 125 | QFrame::Raised 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | ConfigurationDockWidget 143 | QDockWidget 144 |
kobuki_qtestsuite.configuration_dock_widget
145 | 1 146 |
147 | 148 | WanderingFrame 149 | QFrame 150 |
kobuki_qtestsuite.wandering_frame
151 | 1 152 |
153 | 154 | BatteryProfileFrame 155 | QFrame 156 |
kobuki_qtestsuite.battery_profile_frame
157 | 1 158 |
159 | 160 | GyroDriftFrame 161 | QFrame 162 |
kobuki_qtestsuite.gyro_drift_frame
163 | 1 164 |
165 | 166 | CliffSensorFrame 167 | QFrame 168 |
kobuki_qtestsuite.cliff_sensor_frame
169 | 1 170 |
171 | 172 | PayloadFrame 173 | QFrame 174 |
kobuki_qtestsuite.payload_frame
175 | 1 176 |
177 | 178 | LifeFrame 179 | QFrame 180 |
kobuki_qtestsuite.life_frame
181 | 1 182 |
183 |
184 | 185 | 186 | 187 | 188 | 189 |
190 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/gyro_drift_frame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import os 11 | import numpy 12 | import operator 13 | from python_qt_binding.QtCore import Signal, Slot, pyqtSlot 14 | try: # indigo 15 | from python_qt_binding.QtGui import QFrame, QVBoxLayout 16 | except ImportError: # kinetic+ (pyqt5) 17 | from python_qt_binding.QtWidgets import QFrame, QVBoxLayout 18 | import math 19 | 20 | import roslib 21 | roslib.load_manifest('kobuki_qtestsuite') 22 | import rospy 23 | from qt_gui_py_common.worker_thread import WorkerThread 24 | from kobuki_testsuite import ScanToAngle, DriftEstimation 25 | from rqt_plot.plot_widget import PlotWidget 26 | 27 | # Local resource imports 28 | import detail.common_rc 29 | import detail.text_rc 30 | from detail.gyro_drift_frame_ui import Ui_gyro_drift_frame 31 | from rqt_plot.data_plot import DataPlot 32 | 33 | ############################################################################## 34 | # Classes 35 | ############################################################################## 36 | 37 | class GyroDriftFrame(QFrame): 38 | def __init__(self, parent=None): 39 | super(GyroDriftFrame, self).__init__(parent) 40 | self._ui = Ui_gyro_drift_frame() 41 | self._laser_scan_angle_topic_name = '/laser_scan_angle' 42 | self._gyro_scan_angle_topic_name = '/gyro_scan_angle' 43 | self._error_scan_angle_topic_name = '/error_scan_angle' 44 | self._cmd_vel_topic_name = '/mobile_base/commands/velocity' 45 | self._gyro_topic_name = '/mobile_base/sensors/imu_data' 46 | self._motion = None 47 | self._scan_to_angle = None 48 | self._motion_thread = None 49 | self._plot_widget = None 50 | self._plot_widget_live = None 51 | 52 | def setupUi(self): 53 | self._ui.setupUi(self) 54 | self._plot_layout = QVBoxLayout(self._ui.scan_angle_group_box) 55 | self._ui.start_button.setEnabled(True) 56 | self._ui.stop_button.setEnabled(False) 57 | 58 | def shutdown(self): 59 | ''' 60 | Used to terminate the plugin 61 | ''' 62 | rospy.loginfo("Kobuki TestSuite: gyro drift shutdown") 63 | self._stop() 64 | 65 | ########################################################################## 66 | # Widget Management 67 | ########################################################################## 68 | 69 | def _pause_plots(self): 70 | ''' 71 | Pause plots, more importantly, pause greedy plot rendering 72 | ''' 73 | if self._plot_widget: 74 | self._plot_widget.enable_timer(False) 75 | if self._plot_widget_live: 76 | self._plot_widget_live.enable_timer(False) 77 | 78 | def hibernate(self): 79 | ''' 80 | This gets called when the frame goes out of focus (tab switch). 81 | Disable everything to avoid running N tabs in parallel when in 82 | reality we are only running one. 83 | ''' 84 | self._stop() 85 | self._plot_layout.removeWidget(self._plot_widget) 86 | self._plot_layout.removeWidget(self._plot_widget_live) 87 | self._plot_widget = None 88 | self._plot_widget_live = None 89 | 90 | def restore(self): 91 | ''' 92 | Restore the frame after a hibernate. 93 | ''' 94 | self._plot_widget = PlotWidget() 95 | self._plot_widget.setWindowTitle("Error") 96 | self._plot_layout.addWidget(self._plot_widget) 97 | self._plot_widget.switch_data_plot_widget(DataPlot(self._plot_widget)) 98 | self._plot_widget.data_plot.dynamic_range = True 99 | self._plot_widget_live = PlotWidget() 100 | self._plot_widget_live.setWindowTitle("Live Graphs") 101 | self._plot_widget_live.switch_data_plot_widget(DataPlot(self._plot_widget_live)) 102 | self._plot_layout.addWidget(self._plot_widget_live) 103 | 104 | ########################################################################## 105 | # Qt Callbacks 106 | ########################################################################## 107 | @Slot() 108 | def on_start_button_clicked(self): 109 | self._ui.start_button.setEnabled(False) 110 | self._ui.stop_button.setEnabled(True) 111 | if not self._scan_to_angle: 112 | self._scan_to_angle = ScanToAngle('/scan',self._laser_scan_angle_topic_name) 113 | if not self._motion: 114 | self._motion = DriftEstimation(self._laser_scan_angle_topic_name, self._gyro_scan_angle_topic_name, self._error_scan_angle_topic_name, self._cmd_vel_topic_name,self._gyro_topic_name) 115 | self._motion.init(self._ui.angular_speed_spinbox.value()) 116 | rospy.sleep(0.5) 117 | self._plot_widget._start_time = rospy.get_time() 118 | self._plot_widget.enable_timer(True) 119 | try: 120 | self._plot_widget.remove_topic(self._error_scan_angle_topic_name+'/scan_angle') 121 | self._plot_widget_live.remove_topic(self._laser_scan_angle_topic_name+'/scan_angle') 122 | self._plot_widget_live.remove_topic(self._gyro_scan_angle_topic_name+'/scan_angle') 123 | self._plot_widget_live.remove_topic(self._cmd_vel_topic_name+'/angular/z') 124 | except KeyError: 125 | pass 126 | self._plot_widget_live.add_topic(self._cmd_vel_topic_name+'/angular/z') 127 | self._plot_widget_live.add_topic(self._laser_scan_angle_topic_name+'/scan_angle') 128 | self._plot_widget_live.add_topic(self._gyro_scan_angle_topic_name+'/scan_angle') 129 | self._plot_widget.add_topic(self._error_scan_angle_topic_name+'/scan_angle') 130 | self._motion_thread = WorkerThread(self._motion.execute, None) 131 | self._motion_thread.start() 132 | 133 | @Slot() 134 | def on_stop_button_clicked(self): 135 | self._stop() 136 | 137 | def _stop(self): 138 | self._pause_plots() 139 | if self._scan_to_angle: 140 | self._scan_to_angle.shutdown() 141 | self._scan_to_angle = None 142 | if self._motion: 143 | self._motion.stop() 144 | if self._motion_thread: 145 | self._motion_thread.wait() 146 | self._motion_thread = None 147 | if self._motion: 148 | self._motion.shutdown() 149 | self._motion = None 150 | self._ui.start_button.setEnabled(True) 151 | self._ui.stop_button.setEnabled(False) 152 | 153 | @pyqtSlot(float) 154 | def on_angular_speed_spinbox_valueChanged(self, value): 155 | if self._motion: 156 | self._motion.init(self._ui.angular_speed_spinbox.value()) 157 | 158 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/battery_profile_frame.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # License: BSD 4 | # https://raw.github.com/yujinrobot/kobuki_desktop/master/kobuki_qtestsuite/LICENSE 5 | # 6 | ############################################################################## 7 | # Imports 8 | ############################################################################## 9 | 10 | import os 11 | from python_qt_binding.QtCore import Signal, Slot, pyqtSlot 12 | try: # indigo 13 | from python_qt_binding.QtGui import QFrame, QVBoxLayout 14 | except ImportError: # kinetic+ (pyqt5) 15 | from python_qt_binding.QtWidgets import QFrame, QVBoxLayout 16 | import math 17 | 18 | import rospy 19 | from qt_gui_py_common.worker_thread import WorkerThread 20 | from rqt_plot.plot_widget import PlotWidget 21 | from kobuki_testsuite import Rotate 22 | from kobuki_msgs.msg import RobotStateEvent 23 | 24 | # Local resource imports 25 | import detail.common_rc 26 | import detail.text_rc 27 | from detail.battery_profile_frame_ui import Ui_battery_profile_frame 28 | from full_size_data_plot import FullSizeDataPlot 29 | from rqt_plot.data_plot import DataPlot 30 | 31 | ############################################################################## 32 | # Classes 33 | ############################################################################## 34 | 35 | class BatteryProfileFrame(QFrame): 36 | def __init__(self, parent=None): 37 | super(BatteryProfileFrame, self).__init__(parent) 38 | self._cmd_vel_topic_name = '/mobile_base/commands/velocity' 39 | self._battery_topic_name = "/mobile_base/sensors/core/battery" 40 | self._ui = Ui_battery_profile_frame() 41 | self._motion = None 42 | self.robot_state_subscriber = None 43 | self._motion_thread = None 44 | self._plot_widget = None 45 | 46 | def setupUi(self, cmd_vel_topic_name): 47 | self._ui.setupUi(self) 48 | self._cmd_vel_topic_name = cmd_vel_topic_name 49 | self._plot_layout = QVBoxLayout(self._ui.battery_profile_group_box) 50 | self._ui.start_button.setEnabled(True) 51 | self._ui.stop_button.setEnabled(False) 52 | self.restore() 53 | 54 | def shutdown(self): 55 | ''' 56 | Used to terminate the plugin 57 | ''' 58 | rospy.loginfo("Kobuki TestSuite: battery test shutdown") 59 | self._stop() 60 | 61 | ########################################################################## 62 | # Widget Management 63 | ########################################################################## 64 | 65 | def hibernate(self): 66 | ''' 67 | This gets called when the frame goes out of focus (tab switch). 68 | Disable everything to avoid running N tabs in parallel when in 69 | reality we are only running one. 70 | ''' 71 | self._stop() 72 | self._plot_layout.removeWidget(self._plot_widget) 73 | self._plot_widget = None 74 | 75 | def restore(self): 76 | ''' 77 | Restore the frame after a hibernate. 78 | ''' 79 | self._plot_widget = PlotWidget() 80 | self._plot_widget.setWindowTitle("Battery Profile") 81 | self._plot_widget.topic_edit.setText(self._battery_topic_name) 82 | self._plot_layout.addWidget(self._plot_widget) 83 | 84 | self._data_plot = DataPlot(self._plot_widget) 85 | self._data_plot.set_autoscale(y=False) 86 | self._data_plot.set_ylim([0, 180]) 87 | self._plot_widget.switch_data_plot_widget(self._data_plot) 88 | 89 | 90 | ########################################################################## 91 | # Motion Callbacks 92 | ########################################################################## 93 | 94 | def _run_finished(self): 95 | self._ui.start_button.setEnabled(True) 96 | self._ui.stop_button.setEnabled(False) 97 | 98 | ########################################################################## 99 | # Qt Callbacks 100 | ########################################################################## 101 | @Slot() 102 | def on_start_button_clicked(self): 103 | self._ui.start_button.setEnabled(False) 104 | self._ui.stop_button.setEnabled(True) 105 | if not self._motion: 106 | self._motion = Rotate(self._cmd_vel_topic_name) 107 | self._motion.init(self._ui.angular_speed_spinbox.value()) 108 | if not self.robot_state_subscriber: 109 | self.robot_state_subscriber = rospy.Subscriber("/mobile_base/events/robot_state", RobotStateEvent, self.robot_state_callback) 110 | rospy.sleep(0.5) 111 | self._plot_widget._start_time = rospy.get_time() 112 | self._plot_widget.enable_timer(True) 113 | try: 114 | self._plot_widget.remove_topic(self._battery_topic_name) 115 | except KeyError: 116 | pass 117 | self._plot_widget.add_topic(self._battery_topic_name) 118 | self._motion_thread = WorkerThread(self._motion.execute, self._run_finished) 119 | self._motion_thread.start() 120 | 121 | @Slot() 122 | def on_stop_button_clicked(self): 123 | ''' 124 | Hardcore stoppage - straight to zero. 125 | ''' 126 | self._stop() 127 | 128 | def _stop(self): 129 | if self._plot_widget: 130 | self._plot_widget.enable_timer(False) # pause plot rendering 131 | if self._motion_thread: 132 | self._motion.stop() 133 | self._motion_thread.wait() 134 | self._motion_thread = None 135 | if self._motion: 136 | self._motion.shutdown() 137 | self._motion = None 138 | if self.robot_state_subscriber: 139 | self.robot_state_subscriber.unregister() 140 | self.robot_state_subscriber = None 141 | self._ui.start_button.setEnabled(True) 142 | self._ui.stop_button.setEnabled(False) 143 | 144 | @pyqtSlot(float) 145 | def on_angular_speed_spinbox_valueChanged(self, value): 146 | if self._motion: 147 | self._motion.init(self._ui.angular_speed_spinbox.value()) 148 | 149 | ########################################################################## 150 | # External Slot Callbacks 151 | ########################################################################## 152 | @Slot(str) 153 | def on_cmd_vel_topic_combo_box_currentIndexChanged(self, topic_name): 154 | ''' 155 | To be connected to the configuration dock combo box (via the main testsuite frame) 156 | ''' 157 | self._cmd_vel_topic_name = topic_name 158 | print("DudetteBattery %s" % topic_name) 159 | 160 | ########################################################################## 161 | # Ros Callbacks 162 | ########################################################################## 163 | 164 | def robot_state_callback(self, data): 165 | if data.state == RobotStateEvent.OFFLINE: 166 | self.stop() 167 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/wandering_frame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | wandering_frame 4 | 5 | 6 | 7 | 0 8 | 0 9 | 791 10 | 414 11 | 12 | 13 | 14 | Frame 15 | 16 | 17 | QFrame::StyledPanel 18 | 19 | 20 | QFrame::Raised 21 | 22 | 23 | 24 | 25 | 26 | QTextEdit::AutoAll 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | qrc:/text/wandering.html 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | Bump Counter 48 | 49 | 50 | 51 | 52 | 53 | Qt::Vertical 54 | 55 | 56 | 57 | 20 58 | 65 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | Qt::Vertical 76 | 77 | 78 | 79 | 20 80 | 119 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | Controls 92 | 93 | 94 | 95 | 96 | 97 | Qt::Horizontal 98 | 99 | 100 | 101 | 96 102 | 17 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | Speed 111 | 112 | 113 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 114 | 115 | 116 | 117 | 118 | 119 | 120 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 121 | 122 | 123 | 124 | 125 | 126 | m/s 127 | 128 | 129 | 0.700000000000000 130 | 131 | 132 | 0.100000000000000 133 | 134 | 135 | 0.300000000000000 136 | 137 | 138 | 139 | 140 | 141 | 142 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 143 | 144 | 145 | 146 | 147 | 148 | rad/s 149 | 150 | 151 | 3.140000000000000 152 | 153 | 154 | 0.100000000000000 155 | 156 | 157 | 0.800000000000000 158 | 159 | 160 | 161 | 162 | 163 | 164 | Angular Speed 165 | 166 | 167 | 168 | 169 | 170 | 171 | Qt::Horizontal 172 | 173 | 174 | 175 | 96 176 | 20 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | Qt::Horizontal 185 | 186 | 187 | 188 | 181 189 | 20 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | Start 198 | 199 | 200 | 201 | 202 | 203 | 204 | Stop 205 | 206 | 207 | 208 | 209 | 210 | 211 | Qt::Horizontal 212 | 213 | 214 | 215 | 167 216 | 20 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | -------------------------------------------------------------------------------- /kobuki_qtestsuite/src/kobuki_qtestsuite/ui/life_frame.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | life_frame 4 | 5 | 6 | 7 | 0 8 | 0 9 | 791 10 | 414 11 | 12 | 13 | 14 | Frame 15 | 16 | 17 | QFrame::StyledPanel 18 | 19 | 20 | QFrame::Raised 21 | 22 | 23 | 24 | 25 | 26 | QTextEdit::AutoAll 27 | 28 | 29 | true 30 | 31 | 32 | 33 | 34 | 35 | 36 | qrc:/text/life.html 37 | 38 | 39 | 40 | false 41 | 42 | 43 | 44 | 45 | 46 | 47 | Life Meters 48 | 49 | 50 | 51 | 52 | 53 | Qt::Vertical 54 | 55 | 56 | 57 | 20 58 | 89 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | Run Status 67 | 68 | 69 | Qt::AlignCenter 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 0 78 | 0 79 | 80 | 81 | 82 | 60 83 | 84 | 85 | 0 86 | 87 | 88 | 89 | 90 | 91 | 92 | Idle Status 93 | 94 | 95 | Qt::AlignCenter 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 0 104 | 0 105 | 106 | 107 | 108 | 15 109 | 110 | 111 | 0 112 | 113 | 114 | false 115 | 116 | 117 | 118 | 119 | 120 | 121 | Qt::Vertical 122 | 123 | 124 | 125 | 20 126 | 88 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | Controls 138 | 139 | 140 | 141 | 142 | 143 | Qt::Horizontal 144 | 145 | 146 | 147 | 96 148 | 17 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | Angular Speed 157 | 158 | 159 | 160 | 161 | 162 | 163 | Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter 164 | 165 | 166 | 167 | 168 | 169 | rad/s 170 | 171 | 172 | 3.140000000000000 173 | 174 | 175 | 0.100000000000000 176 | 177 | 178 | 0.800000000000000 179 | 180 | 181 | 182 | 183 | 184 | 185 | Qt::Horizontal 186 | 187 | 188 | 189 | 96 190 | 20 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | Qt::Horizontal 199 | 200 | 201 | 202 | 181 203 | 20 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | Start 212 | 213 | 214 | 215 | 216 | 217 | 218 | Stop 219 | 220 | 221 | 222 | 223 | 224 | 225 | Qt::Horizontal 226 | 227 | 228 | 229 | 167 230 | 20 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | -------------------------------------------------------------------------------- /kobuki_gazebo_plugins/include/kobuki_gazebo_plugins/gazebo_ros_kobuki.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013, Yujin Robot. 3 | * All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions are met: 7 | * 8 | * * Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * * Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * * Neither the name of Yujin Robot nor the names of its 14 | * contributors may be used to endorse or promote products derived from 15 | * this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 | * POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | 30 | /** 31 | * @author Marcus Liebhardt 32 | * 33 | * This work has been inspired by Nate Koenig's Gazebo plugin for the iRobot Create. 34 | */ 35 | 36 | #ifndef GAZEBO_ROS_KOBUKI_H 37 | #define GAZEBO_ROS_KOBUKI_H 38 | 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | #include 48 | #if GAZEBO_MAJOR_VERSION >= 9 49 | // #include 50 | #include 51 | #include 52 | #else 53 | #include 54 | #endif 55 | #include 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | #include 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | #include 73 | 74 | namespace gazebo 75 | { 76 | 77 | enum {LEFT= 0, RIGHT=1}; 78 | 79 | class GazeboRosKobuki : public ModelPlugin 80 | { 81 | public: 82 | /// Constructor 83 | GazeboRosKobuki(); 84 | /// Destructor 85 | ~GazeboRosKobuki(); 86 | /// Called when plugin is loaded 87 | void Load(physics::ModelPtr parent, sdf::ElementPtr sdf); 88 | /// Called by the world update start event 89 | void OnUpdate(); 90 | 91 | private: 92 | /* 93 | * Methods 94 | */ 95 | /// Callback for incoming velocity commands 96 | void cmdVelCB(const geometry_msgs::TwistConstPtr &msg); 97 | /// Callback for incoming velocity commands 98 | void motorPowerCB(const kobuki_msgs::MotorPowerPtr &msg); 99 | /// Callback for resetting the odometry data 100 | void resetOdomCB(const std_msgs::EmptyConstPtr &msg); 101 | /// Spin method for the spinner thread 102 | void spin(); 103 | // void OnContact(const std::string &name, const physics::Contact &contact); necessary? 104 | 105 | 106 | // internal functions for load 107 | void prepareMotorPower(); 108 | bool prepareJointState(); 109 | void preparePublishTf(); 110 | bool prepareWheelAndTorque(); 111 | void prepareOdom(); 112 | bool prepareVelocityCommand(); 113 | bool prepareCliffSensor(); 114 | bool prepareBumper(); 115 | bool prepareWheelDrop(); 116 | bool prepareIMU(); 117 | void setupRosApi(std::string& model_name); 118 | 119 | // internal functions for update 120 | void updateJointState(); 121 | void updateOdometry(common::Time& step_time); 122 | void updateIMU(); 123 | void propagateVelocityCommands(); 124 | void updateCliffSensor(); 125 | void updateBumper(); 126 | void updateWheelDrop(); 127 | void pubSensorState(); 128 | 129 | /* 130 | * Parameters 131 | */ 132 | /// ROS node handles (relative & private) 133 | ros::NodeHandle nh_, nh_priv_; 134 | /// node name 135 | std::string node_name_; 136 | 137 | /// TF Prefix 138 | std::string tf_prefix_; 139 | /// extra thread for triggering ROS callbacks 140 | // boost::shared_ptr ros_spinner_thread_; necessary? 141 | /// flag for shutting down the spinner thread 142 | bool shutdown_requested_; 143 | /// pointer to the model 144 | physics::ModelPtr model_; 145 | /// pointer to the gazebo ros node 146 | GazeboRosPtr gazebo_ros_; 147 | sdf::ElementPtr sdf_; 148 | /// pointer to simulated world 149 | physics::WorldPtr world_; 150 | /// pointer to the update event connection (triggers the OnUpdate callback when event update event is received) 151 | event::ConnectionPtr update_connection_; 152 | /// rate control 153 | double update_rate_; 154 | /// Simulation time on previous update 155 | common::Time prev_update_time_; 156 | /// ROS subscriber for motor power commands 157 | ros::Subscriber motor_power_sub_; 158 | /// Flag indicating if the motors are turned on or not 159 | bool motors_enabled_; 160 | /// Pointers to Gazebo's joints 161 | physics::JointPtr joints_[2]; 162 | /// Left wheel's joint name 163 | std::string left_wheel_joint_name_; 164 | /// Right wheel's joint name 165 | std::string right_wheel_joint_name_; 166 | /// ROS publisher for joint state messages 167 | ros::Publisher joint_state_pub_; 168 | /// ROS message for joint sates 169 | sensor_msgs::JointState joint_state_; 170 | /// ROS subscriber for velocity commands 171 | ros::Subscriber cmd_vel_sub_; 172 | /// Simulation time of the last velocity command (used for time out) 173 | common::Time last_cmd_vel_time_; 174 | /// Time out for velocity commands in seconds 175 | double cmd_vel_timeout_; 176 | /// Speeds of the wheels 177 | double wheel_speed_cmd_[2]; 178 | /// Max. torque applied to the wheels 179 | double torque_; 180 | /// Separation between the wheels 181 | double wheel_sep_; 182 | /// Diameter of the wheels 183 | double wheel_diam_; 184 | /// Vector for pose 185 | double odom_pose_[3]; 186 | /// Vector for velocity 187 | double odom_vel_[3]; 188 | /// Pointer to pose covariance matrix 189 | double *pose_cov_[36]; 190 | /// Pointer to twist covariance matrix 191 | double *twist_cov_[36]; 192 | /// ROS publisher for odometry messages 193 | ros::Publisher odom_pub_; 194 | /// ROS message for odometry data 195 | nav_msgs::Odometry odom_; 196 | /// Flag for (not) publish tf transform for odom -> robot 197 | bool publish_tf_; 198 | /// TF transform publisher for the odom frame 199 | tf::TransformBroadcaster tf_broadcaster_; 200 | /// TF transform for the odom frame 201 | geometry_msgs::TransformStamped odom_tf_; 202 | /// Pointer to left cliff sensor 203 | sensors::RaySensorPtr cliff_sensor_left_; 204 | /// Pointer to frontal cliff sensor 205 | sensors::RaySensorPtr cliff_sensor_center_; 206 | /// Pointer to left right sensor 207 | sensors::RaySensorPtr cliff_sensor_right_; 208 | /// ROS publisher for cliff detection events 209 | ros::Publisher cliff_event_pub_; 210 | /// Kobuki ROS message for cliff event 211 | kobuki_msgs::CliffEvent cliff_event_; 212 | /// Cliff flag for the left sensor 213 | bool cliff_detected_left_; 214 | /// Cliff flag for the center sensor 215 | bool cliff_detected_center_; 216 | /// Cliff flag for the right sensor 217 | bool cliff_detected_right_; 218 | /// measured distance in meter for detecting a cliff 219 | float cliff_detection_threshold_; 220 | /// Maximum distance to floor 221 | int floot_dist_; 222 | /// Pointer to bumper sensor simulating Kobuki's left, centre and right bumper sensors 223 | sensors::ContactSensorPtr bumper_; 224 | /// ROS publisher for bumper events 225 | ros::Publisher bumper_event_pub_; 226 | /// Kobuki ROS message for bumper events 227 | kobuki_msgs::BumperEvent bumper_event_; 228 | /// Flag for left bumper's last state 229 | bool bumper_left_was_pressed_; 230 | /// Flag for center bumper's last state 231 | bool bumper_center_was_pressed_; 232 | /// Flag for right bumper's last state 233 | bool bumper_right_was_pressed_; 234 | /// Flag for left bumper's current state 235 | bool bumper_left_is_pressed_; 236 | /// Flag for left bumper's current state 237 | bool bumper_center_is_pressed_; 238 | /// Flag for left bumper's current state 239 | bool bumper_right_is_pressed_; 240 | /// Pointers to wheel contact sensors used to simulate Kobuki's wheel drop sensors 241 | sensors::ContactSensorPtr wheel_drop_left_; 242 | sensors::ContactSensorPtr wheel_drop_right_; 243 | /// ROS publisher for wheel drop events 244 | ros::Publisher wheel_drop_main_pub_; 245 | /// Kobuki ROS message for wheel drop events 246 | kobuki_msgs::WheelDropEvent wheel_drop_event_; 247 | /// Wheel drop sensor flags 248 | bool wheel_left_dropped_flag_ = false; 249 | bool wheel_right_dropped_flag_ = false; 250 | /// Pointer to IMU sensor model 251 | sensors::ImuSensorPtr imu_; 252 | /// Storage for the angular velocity reported by the IMU 253 | 254 | #if GAZEBO_MAJOR_VERSION >= 9 255 | ignition::math::Vector3d vel_angular_; 256 | #else 257 | math::Vector3 vel_angular_; 258 | #endif 259 | 260 | /// ROS publisher for IMU data 261 | ros::Publisher imu_pub_; 262 | /// ROS message for publishing IMU data 263 | sensor_msgs::Imu imu_msg_; 264 | /// ROS subscriber for reseting the odometry data 265 | ros::Subscriber odom_reset_sub_; 266 | 267 | /// ROS publisher for Kobuki sensor state 268 | ros::Publisher sensor_state_pub_; 269 | }; 270 | 271 | } // namespace gazebo 272 | 273 | #endif /* GAZEBO_ROS_KOBUKI_H */ 274 | --------------------------------------------------------------------------------