change folder name of mycobot_pro

This commit is contained in:
wangWking 2022-04-12 15:21:14 +08:00
parent 157ce35542
commit f44f712b7c
6 changed files with 806 additions and 0 deletions

View file

@ -0,0 +1,204 @@
cmake_minimum_required(VERSION 3.0.2)
project(mycobot_600)
## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
mycobot_description
)
## System dependencies are found with CMake's conventions
# find_package(Boost REQUIRED COMPONENTS system)
## Uncomment this if the package has a setup.py. This macro ensures
## modules and global scripts declared therein get installed
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
# catkin_python_setup()
################################################
## Declare ROS messages, services and actions ##
################################################
## To declare and build messages, services or actions from within this
## package, follow these steps:
## * Let MSG_DEP_SET be the set of packages whose message types you use in
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
## * In the file package.xml:
## * add a build_depend tag for "message_generation"
## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET
## * If MSG_DEP_SET isn't empty the following dependency has been pulled in
## but can be declared for certainty nonetheless:
## * add a exec_depend tag for "message_runtime"
## * In this file (CMakeLists.txt):
## * add "message_generation" and every package in MSG_DEP_SET to
## find_package(catkin REQUIRED COMPONENTS ...)
## * add "message_runtime" and every package in MSG_DEP_SET to
## catkin_package(CATKIN_DEPENDS ...)
## * uncomment the add_*_files sections below as needed
## and list every .msg/.srv/.action file to be processed
## * uncomment the generate_messages entry below
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
## Generate messages in the 'msg' folder
# add_message_files(
# FILES
# Message1.msg
# Message2.msg
# )
## Generate services in the 'srv' folder
# add_service_files(
# FILES
# Service1.srv
# Service2.srv
# )
## Generate actions in the 'action' folder
# add_action_files(
# FILES
# Action1.action
# Action2.action
# )
## Generate added messages and services with any dependencies listed here
# generate_messages(
# DEPENDENCIES
# std_msgs # Or other packages containing msgs
# )
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
## To declare and build dynamic reconfigure parameters within this
## package, follow these steps:
## * In the file package.xml:
## * add a build_depend and a exec_depend tag for "dynamic_reconfigure"
## * In this file (CMakeLists.txt):
## * add "dynamic_reconfigure" to
## find_package(catkin REQUIRED COMPONENTS ...)
## * uncomment the "generate_dynamic_reconfigure_options" section below
## and list every .cfg file to be processed
## Generate dynamic reconfigure parameters in the 'cfg' folder
# generate_dynamic_reconfigure_options(
# cfg/DynReconf1.cfg
# cfg/DynReconf2.cfg
# )
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if your package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES mycobot_600
# CATKIN_DEPENDS mycobot_description
# DEPENDS system_lib
)
###########
## Build ##
###########
## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
# add_library(${PROJECT_NAME}
# src/${PROJECT_NAME}/mycobot_600.cpp
# )
## Add cmake target dependencies of the library
## as an example, code may need to be generated before libraries
## either from message generation or dynamic reconfigure
# add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Declare a C++ executable
## With catkin_make all packages are built within a single CMake context
## The recommended prefix ensures that target names across packages don't collide
# add_executable(${PROJECT_NAME}_node src/mycobot_600_node.cpp)
## Rename C++ executable without prefix
## The above recommended prefix causes long target names, the following renames the
## target back to the shorter version for ease of user use
## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node"
# set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "")
## Add cmake target dependencies of the executable
## same as for the library above
# add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})
## Specify libraries to link a library or executable target against
# target_link_libraries(${PROJECT_NAME}_node
# ${catkin_LIBRARIES}
# )
#############
## Install ##
#############
# all install targets should use catkin DESTINATION variables
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
## Mark executable scripts (Python etc.) for installation
## in contrast to setup.py, you can choose the destination
# catkin_install_python(PROGRAMS
# scripts/my_python_script
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark executables for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html
# install(TARGETS ${PROJECT_NAME}_node
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
# )
## Mark libraries for installation
## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html
# install(TARGETS ${PROJECT_NAME}
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
# RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
# )
## Mark cpp header files for installation
# install(DIRECTORY include/${PROJECT_NAME}/
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
# FILES_MATCHING PATTERN "*.h"
# PATTERN ".svn" EXCLUDE
# )
## Mark other files for installation (e.g. launch and bag files, etc.)
# install(FILES
# # myfile1
# # myfile2
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
# )
#############
## Testing ##
#############
## Add gtest based cpp test target and link libraries
# catkin_add_gtest(${PROJECT_NAME}-test test/test_mycobot_600.cpp)
# if(TARGET ${PROJECT_NAME}-test)
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
# endif()
## Add folders to be run by python nosetests
# catkin_add_nosetests(test)

View file

@ -0,0 +1,25 @@
BSD 2-Clause License
Copyright (c) 2020, Elephant Robotics
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -0,0 +1,203 @@
Panels:
- Class: rviz/Displays
Help Height: 78
Name: Displays
Property Tree Widget:
Expanded:
- /Global Options1
- /Status1
- /RobotModel1
- /TF1
Splitter Ratio: 0.5
Tree Height: 775
- Class: rviz/Selection
Name: Selection
- Class: rviz/Tool Properties
Expanded:
- /2D Pose Estimate1
- /2D Nav Goal1
- /Publish Point1
Name: Tool Properties
Splitter Ratio: 0.588679016
- Class: rviz/Views
Expanded:
- /Current View1
Name: Views
Splitter Ratio: 0.5
- Class: rviz/Time
Experimental: false
Name: Time
SyncMode: 0
SyncSource: ""
Toolbars:
toolButtonStyle: 2
Visualization Manager:
Class: ""
Displays:
- Alpha: 0.5
Cell Size: 1
Class: rviz/Grid
Color: 160; 160; 164
Enabled: true
Line Style:
Line Width: 0.0299999993
Value: Lines
Name: Grid
Normal Cell Count: 0
Offset:
X: 0
Y: 0
Z: 0
Plane: XY
Plane Cell Count: 10
Reference Frame: <Fixed Frame>
Value: true
- Alpha: 1
Class: rviz/RobotModel
Collision Enabled: false
Enabled: true
Links:
All Links Enabled: true
Expand Joint Details: false
Expand Link Details: false
Expand Tree: false
Link Tree Style: Links in Alphabetic Order
base:
Alpha: 1
Show Axes: false
Show Trail: false
Value: true
link1:
Alpha: 1
Show Axes: false
Show Trail: false
Value: true
link2:
Alpha: 1
Show Axes: false
Show Trail: false
Value: true
link3:
Alpha: 1
Show Axes: false
Show Trail: false
Value: true
link4:
Alpha: 1
Show Axes: false
Show Trail: false
Value: true
link5:
Alpha: 1
Show Axes: false
Show Trail: false
Value: true
link6:
Alpha: 1
Show Axes: false
Show Trail: false
Value: true
Name: RobotModel
Robot Description: robot_description
TF Prefix: ""
Update Interval: 0
Value: true
Visual Enabled: true
- Class: rviz/TF
Enabled: true
Frame Timeout: 15
Frames:
All Enabled: true
base:
Value: true
link1:
Value: true
link2:
Value: true
link3:
Value: true
link4:
Value: true
link5:
Value: true
link6:
Value: true
Marker Scale: 0.300000012
Name: TF
Show Arrows: true
Show Axes: true
Show Names: true
Tree:
base:
link1:
link2:
link3:
link4:
link5:
link6:
{}
Update Interval: 0
Value: true
Enabled: true
Global Options:
Background Color: 48; 48; 48
Default Light: true
Fixed Frame: base
Frame Rate: 30
Name: root
Tools:
- Class: rviz/Interact
Hide Inactive Objects: true
- Class: rviz/MoveCamera
- Class: rviz/Select
- Class: rviz/FocusCamera
- Class: rviz/Measure
- Class: rviz/SetInitialPose
Topic: /initialpose
- Class: rviz/SetGoal
Topic: /move_base_simple/goal
- Class: rviz/PublishPoint
Single click: true
Topic: /clicked_point
Value: true
Views:
Current:
Class: rviz/Orbit
Distance: 2.0593462
Enable Stereo Rendering:
Stereo Eye Separation: 0.0599999987
Stereo Focal Distance: 1
Swap Stereo Eyes: false
Value: false
Focal Point:
X: -0.0706475973
Y: -0.0814988762
Z: 0.107583851
Focal Shape Fixed Size: true
Focal Shape Size: 0.0500000007
Invert Z Axis: false
Name: Current View
Near Clip Distance: 0.00999999978
Pitch: 0.660398126
Target Frame: <Fixed Frame>
Value: Orbit (rviz)
Yaw: 3.10539246
Saved: ~
Window Geometry:
Displays:
collapsed: false
Height: 1056
Hide Left Dock: false
Hide Right Dock: false
QMainWindow State: 000000ff00000000fd00000004000000000000016a00000396fc0200000008fb0000001200530065006c0065006300740069006f006e00000001e10000009b0000006100fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000002800000396000000d700fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261000000010000022f00000396fc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073010000002800000396000000ad00fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b200000000000000000000000200000490000000a9fc0100000001fb0000000a00560069006500770073030000004e00000080000002e100000197000000030000073f0000003efc0100000002fb0000000800540069006d006501000000000000073f0000030000fffffffb0000000800540069006d006501000000000000045000000000000000000000039a0000039600000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
Selection:
collapsed: false
Time:
collapsed: false
Tool Properties:
collapsed: false
Views:
collapsed: false
Width: 1855
X: 65
Y: 24

View file

@ -0,0 +1,13 @@
<launch>
<!-- Load URDF, rviz, etc. on the parameter server,加载参数服务器上的URDF、rviz等 -->
<arg name="model" default="$(find mycobot_description)/urdf/600_urdf/mycobot_600_urdf.urdf"/>
<arg name="rvizconfig" default="$(find mycobot_600)/config/mycobot_600.rviz" />
<arg name="gui" default="true" />
<!-- Add model control,添加模型控制 -->
<include file="$(find mycobot_280)/launch/slider_control.launch">
<arg name="model" value="$(arg model)" />
<arg name="rvizconfig" value="$(arg rvizconfig)" />
<arg name="gui" value="$(arg gui)" />
</include>
</launch>

View file

@ -0,0 +1,62 @@
<?xml version="1.0"?>
<package format="2">
<name>mycobot_600</name>
<version>0.0.0</version>
<description>The mycobot_600 package</description>
<!-- One maintainer tag required, multiple allowed, one person per tag -->
<!-- Example: -->
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
<maintainer email="ubuntu@todo.todo">ubuntu</maintainer>
<!-- One license tag required, multiple allowed, one license per tag -->
<!-- Commonly used license strings: -->
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
<license>TODO</license>
<!-- Url tags are optional, but multiple are allowed, one per tag -->
<!-- Optional attribute type can be: website, bugtracker, or repository -->
<!-- Example: -->
<!-- <url type="website">http://wiki.ros.org/mycobot_600</url> -->
<!-- Author tags are optional, multiple are allowed, one per tag -->
<!-- Authors do not have to be maintainers, but could be -->
<!-- Example: -->
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
<!-- The *depend tags are used to specify dependencies -->
<!-- Dependencies can be catkin packages or system dependencies -->
<!-- Examples: -->
<!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
<!-- <depend>roscpp</depend> -->
<!-- Note that this is equivalent to the following: -->
<!-- <build_depend>roscpp</build_depend> -->
<!-- <exec_depend>roscpp</exec_depend> -->
<!-- Use build_depend for packages you need at compile time: -->
<!-- <build_depend>message_generation</build_depend> -->
<!-- Use build_export_depend for packages you need in order to build against this package: -->
<!-- <build_export_depend>message_generation</build_export_depend> -->
<!-- Use buildtool_depend for build tool packages: -->
<!-- <buildtool_depend>catkin</buildtool_depend> -->
<!-- Use exec_depend for packages you need at runtime: -->
<!-- <exec_depend>message_runtime</exec_depend> -->
<!-- Use test_depend for packages you need only for testing: -->
<!-- <test_depend>gtest</test_depend> -->
<!-- Use doc_depend for packages you need only for building documentation: -->
<!-- <doc_depend>doxygen</doc_depend> -->
<buildtool_depend>catkin</buildtool_depend>
<build_depend>mycobot_description</build_depend>
<build_export_depend>mycobot_description</build_export_depend>
<exec_depend>mycobot_description</exec_depend>
<!-- The export tag contains other, unspecified, tags -->
<export>
<!-- Other tools can request additional information be placed here -->
</export>
</package>

View file

@ -0,0 +1,299 @@
#!/usr/bin/python
from socket import *
import math
import sys
import time
from multiprocessing import Lock
import rospy
from sensor_msgs.msg import JointState
global mc
mutex = Lock()
class ElephantRobot(object):
def __init__(self, host, port):
# setup connection
# 建立连接
self.BUFFSIZE = 2048
self.ADDR = (host, port)
self.tcp_client = socket(AF_INET, SOCK_STREAM)
def start_client(self):
try:
self.tcp_client.connect(self.ADDR)
return ""
except error, e:
return e
def stop_client(self):
self.tcp_client.close()
def send_command(self, command):
with mutex:
self.tcp_client.send(command.encode())
recv_data = self.tcp_client.recv(self.BUFFSIZE).decode()
res_str = str(recv_data)
print "recv = " + res_str
res_arr = res_str.split(":")
if len(res_arr) == 2:
return res_arr[1]
else:
return ""
def string_to_coords(self, data):
data = data.replace("[", "")
data = data.replace("]", "")
data_arr = data.split(",")
if len(data_arr) == 6:
try:
coords_1 = float(data_arr[0])
coords_2 = float(data_arr[1])
coords_3 = float(data_arr[2])
coords_4 = float(data_arr[3])
coords_5 = float(data_arr[4])
coords_6 = float(data_arr[5])
coords = [coords_1, coords_2, coords_3, coords_4, coords_5, coords_6]
return coords
except:
return invalid_coords()
return invalid_coords()
def string_to_double(self, data):
try:
val = float(data)
return val
except:
return -9999.99
def string_to_int(self, data):
try:
val = int(data)
return val
except:
return -9999
def invalid_coords(self):
coords = [-1, -2, -3, -4, -1, -1]
return coords
def get_angles(self):
command = "get_angles()\n"
res = self.send_command(command)
return self.string_to_coords(res)
def get_coords(self):
command = "get_coords()\n"
res = self.send_command(command)
return self.string_to_coords(res)
def get_speed(self):
command = "get_speed()\n"
res = self.send_command(command)
return self.string_to_double(res)
def power_on(self):
command = "power_on()\n"
res = self.send_command(command)
return True
def power_off(self):
command = "power_off()\n"
res = self.send_command(command)
return True
def check_running(self):
command = "check_running()\n"
res = self.send_command(command)
return res == "1"
def state_check(self):
command = "state_check()\n"
res = self.send_command(command)
return res == "1"
def program_open(self, file_path):
command = "program_open(" + file_path + ")\n"
res = self.send_command(command)
return self.string_to_int(res)
def program_run(self, start_line):
"""run program运行程序"""
command = "program_run(" + str(start_line) + ")\n"
res = self.send_command(command)
return self.string_to_int(res)
def read_next_error(self):
command = "read_next_error()\n"
res = self.send_command(command)
return res
def write_coords(self, coords, speed):
"""set coords,设置坐标"""
command = "set_coords("
for item in coords:
command += str(item) + ","
command += str(speed) + ")\n"
self.send_command(command)
def write_coord(self, axis, value, speed):
coords = self.get_coords()
if coords != self.invalid_coords():
coords[axis] = value
self.write_coords(coords, speed)
def write_angles(self, angles, speed):
"""set angles,设置角度"""
command = "set_angles("
for item in angles:
command += str(item) + ","
command += str(speed) + ")\n"
self.send_command(command)
def write_angle(self, joint, value, speed):
angles = self.get_angles()
if angles != self.invalid_coords():
angles[joint] = value
self.write_angles(angles, speed)
def set_speed(self, percentage):
command = "set_speed(" + str(percentage) + ")\n"
self.send_command(command)
def set_carte_torque_limit(self, axis_str, value):
command = "set_torque_limit(" + axis_str + "," + str(value) + ")\n"
self.send_command(command)
def set_upside_down(self, up_down):
up = "1"
if up_down:
up = "0"
command = "set_upside_down(" + up + ")\n"
self.send_command(command)
def set_payload(self, payload):
command = "set_speed(" + str(payload) + ")\n"
self.send_command(command)
def state_on(self):
command = "state_on()\n"
self.send_command(command)
def state_off(self):
command = "state_off()\n"
self.send_command(command)
def task_stop(self):
command = "task_stop()\n"
self.send_command(command)
def jog_angle(self, joint_str, direction, speed):
command = (
"jog_angle(" + joint_str + "," + str(direction) + "," + str(speed) + ")\n"
)
self.send_command(command)
def jog_coord(self, axis_str, direction, speed):
command = (
"jog_coord(" + axis_str + "," + str(direction) + "," + str(speed) + ")\n"
)
self.send_command(command)
def get_digital_in(self, pin_number):
command = "get_digital_in(" + str(pin_number) + ")\n"
self.send_command(command)
def get_digital_out(self, pin_number):
command = "get_digital_out(" + str(pin_number) + ")\n"
self.send_command(command)
def set_digital_out(self, pin_number, pin_signal):
command = "set_digital_out(" + str(pin_number) + "," + str(pin_signal) + ")\n"
self.send_command(command)
def set_analog_out(self, pin_number, pin_signal):
command = "set_analog_out(" + str(pin_number) + "," + str(pin_signal) + ")\n"
self.send_command(command)
def get_acceleration(self):
command = "get_acceleration()\n"
res = self.send_command(command)
return self.string_to_int(res)
def set_acceleration(self, acceleration):
command = "set_acceleration(" + str(acceleration) + ")\n"
self.send_command(command)
def command_wait_done(self):
command = "wait_command_done()\n"
self.send_command(command)
def wait(self, seconds):
command = "wait(" + str(seconds) + ")\n"
self.send_command(command)
def assign_variable(self, var_name, var_value):
command = 'assign_variable("' + str(var_name) + '",' + str(var_value) + ")\n"
self.send_command(command)
def get_variable(self, var_name):
command = 'get_variable("' + str(var_name) + '")\n'
return self.send_command(command)
old_list = []
def callback(data):
"""callback function,回调函数"""
global old_list
# rospy.loginfo(rospy.get_caller_id() + "%s", data.position)
print ("position", data.position)
data_list = []
for index, value in enumerate(data.position):
value = value * 180 / math.pi
data_list.append(value)
print ("data", data_list)
if not old_list:
old_list = data_list
mc.write_angles(data_list, 1999)
elif old_list != data_list:
old_list = data_list
if mc.check_running():
mc.task_stop()
time.sleep(0.05)
mc.write_angles(data_list, 1999)
def listener():
global mc
rospy.init_node("control_slider", anonymous=True)
ip = rospy.get_param("~ip", "192.168.10.169")
print (ip)
mc = ElephantRobot(ip, 5001)
# START CLIENT,启动客户端
res = mc.start_client()
if res != "":
print res
sys.exit(1)
print ep.wait(5)
print mc.get_angles()
print mc.get_coords()
mc.set_speed(30)
print mc.get_speed()
rospy.Subscriber("joint_states", JointState, callback)
# spin() simply keeps python from exiting until this node is stopped
# spin()只是阻止python退出直到该节点停止
print ("sping ...")
rospy.spin()
if __name__ == "__main__":
listener()