Robotican-LIZI机器人基本操作教程

Robotican-LIZI机器人基本操作教程

1. LIZI的基本参数

Robotican-LIZI机器人基本操作教程
参考LIZI官网

2. LIZI的基础使用

启动顺序:
(1)按电源开关打开电源。
(2)按PC开关,松开后等待3-5s,之后机器人会自检它的系统。作为自检的一部分,LIZI可能会轻微的旋转车轮。
注意,在启动过程中PC按钮会闪烁蓝光。如果发生错误,则会闪烁红光。
(3)连接HDMI显示器及USB外设,通过ctrl+alt+T调出终端,执行此命令 roslaunch lizi lizi.launch
启动后,PC按钮会保持蓝光。
(4)打开一个新的终端,执行此命令 rqt
打开如下可视化控制窗口,即可控制小车速度。
Robotican-LIZI机器人基本操作教程
(5)关闭机器人
为了延长机器人的生命周期,推荐采用如下方式关闭机器人:
先关闭电脑,在PC按钮灯熄灭后关闭电源。
参考官方使用手册

3.LIZI的ROS开发

1 在启动lizi.launch的时候通过配置参数去控制lizi的启动。

gazebo - 在gazebo仿真中启动robot

cam - 启动前方RGB相机

depth_cam - 启动前方RGB-D相机

lidar - 启动激光雷达

diagnos - 发布机器人诊断信息(可以通过 rqt_robot_monitor监控)

move_base - 启动move_base包

map - 加载地图到map server

gmapping - 启动gmapping SLAM . 需要开启 move_base和 lidar

hector_slam - 启动 Hector SLAM . 需要开启 move_base和 lidar

amcl - 启动 AMCL 自适应蒙特卡拉定位. 需要开启 move_base、lidar及map

2.通过修改命名空间启动多个机器人

启动文件参考如下

<?xml version="1.0" encoding="UTF-8"?>

<!-- lizi top-level launch -->

<launch>
    
    <group ns="lizi117"><!-- chang the namespace-->
        <!-- gazebo -->
        <arg name="gazebo" default="false" doc="execute lizi inside gazebo sim"/>
        <arg name="world" default="worlds/empty.world"/> 
        <arg name="x" default="0.0"/>
        <arg name="y" default="0.0"/>
        <arg name="z" default="0.0"/>
        <arg name="Y" default="0.0" />
        
        <!--  hardware    -->
        <arg name="cam" default="false"/>
        <arg name="depth_cam" default="false"/>
        <arg name="lidar" default="true"/>
        <arg name="diagnos" default="true"/>
        <arg name="rviz" default="false"/>
        
        <!--   navigation and mapping   -->
        <arg name="gmapping" default="false"/>
        <arg name="hector_slam" default="false"/>
        <arg name="amcl" default="false"/>
        <arg name="have_map" default="false" doc="set to true to use pre-saved map"/>
        <arg name="map" default="/home/lizi115/catkin_ws/src/lizi/lizi_navigation/maps/2.yaml" doc="pre-saved map path"/>
        <arg name="move_base" default="false"/>
        <arg name="robot_localization" default="false"/>
            
        <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" respawn="false" output="screen"/>
        
        <group if="$(arg diagnos)">
            <include file="$(find lizi_hw)/launch/diagnostics.launch" />
        </group>
        
        <group if="$(arg amcl)">
            <include file="$(find lizi_control)/launch/lizi_controllers.launch" >
                <arg name="enable_mbc_odom_tf" value="false"/>
            </include>
        </group>
        
        <group if="$(arg robot_localization)">
            <include file="$(find lizi_control)/launch/lizi_controllers.launch" >
                <arg name="enable_mbc_odom_tf" value="false"/>
            </include>
        </group>
        
        <group unless="$(arg robot_localization)">
            <group unless="$(arg amcl)">
                <include file="$(find lizi_control)/launch/lizi_controllers.launch" >
                    <arg name="enable_mbc_odom_tf" value="true"/>
                </include>
            </group>
        </group>
            
        
        <include file="$(find espeak_ros)/launch/espeak_ros.launch" />
        
        <group if="$(arg have_map)">
            <node name="map_server" pkg="map_server" type="map_server" args="$(arg map)" />
        </group>

        <!--if no one publish map-odom tf, load static tf-->
        <group unless="$(arg gmapping)">
            <group unless="$(arg hector_slam)">
                <group unless="$(arg amcl)">           
                    <group unless="$(arg robot_localization)">  
                        <node pkg="tf" type="static_transform_publisher" name="map_odom_broadcaster" args="0 0 0 0 0 0 /map /odom 20" /> 
                    </group>   
                </group>   
            </group>    
        </group>
        
        <!--load simulation stuff-->
        <group if="$(arg gazebo)">
            <!-- <env name="GAZEBO_MODEL_PATH" value="$(find lizi_gazebo)/models:$(optenv GAZEBO_MODEL_PATH)"/>-->
            <param name="robot_description" command="$(find xacro)/xacro '$(find lizi_description)/urdf/lizi_gazebo.xacro' --inorder 
                    depth_cam:=$(arg depth_cam)
                    cam:=$(arg cam)
                    urf:=true
                    imu:=true
                    gps:=true
                    lidar:=true" />
            
            <include file="$(find gazebo_ros)/launch/empty_world.launch">	    
                <arg name="world_name" value="$(arg world)"/>
                <arg name="gui" value="true"/>	     
            </include>

            <node name="lizi_spawn" pkg="gazebo_ros" type="spawn_model" output="screen" args="-urdf -param robot_description -model lizi -x $(arg x) -y $(arg y) -z $(arg z) -Y $(arg Y)" />
        </group>
        
        <!--load hardware stuff-->
        <group unless="$(arg gazebo)">
            <param name="robot_description" command="$(find xacro)/xacro '$(find lizi_description)/urdf/lizi.xacro' --inorder" />
            <include file="$(find lizi_hw)/launch/lizi_hw.launch" />
                    
            <group if="$(arg depth_cam)">
                <include file="$(find lizi_hw)/launch/d435_cam.launch" />
            </group>
        
            <group if="$(arg cam)">
                <include file="$(find lizi_hw)/launch/microsoft_cam.launch" />
            </group>
                    
            <group if="$(arg lidar)">
                <include file="$(find lizi_hw)/launch/hokuyu_lidar.launch" />
            </group>
            
        </group>
        
    
        <group if="$(arg gmapping)">
            <include file="$(find lizi_navigation)/launch/gmapping.launch" />
        </group>
        
        <group if="$(arg hector_slam)">
            <include file="$(find lizi_navigation)/launch/hector_slam.launch" />
        </group>

        <group if="$(arg robot_localization)">
            <include file="$(find lizi_navigation)/launch/robot_localization.launch" />
        </group>

        <group if="$(arg amcl)">
            <node pkg="tf" type="static_transform_publisher" name="map_odom_broadcaster" args="0 0 0 0 0 0 /map /odom 20" /> 
            <include file="$(find lizi_navigation)/launch/amcl.launch" >
                <!--arg name="x" value="$(arg x)"/>
                <arg name="y" value="$(arg y)"/>
                <arg name="Y" value="$(arg Y)"/-->
            </include>
        </group>
        
        
        <group if="$(arg move_base)">
            <include file="$(find lizi_navigation)/launch/move_base.launch" />
            <rosparam file="$(find lizi_navigation)/config/move_base_params.yaml" command="load" ns="move_base"/>
            <rosparam file="$(find lizi_navigation)/config/costmap_common_params.yaml" command="load" ns="move_base/global_costmap" />
            <rosparam file="$(find lizi_navigation)/config/costmap_common_params.yaml" command="load" ns="move_base/local_costmap" />
            <rosparam file="$(find lizi_navigation)/config/local_costmap_params.yaml" command="load" ns="move_base/local_costmap" />
            <rosparam file="$(find lizi_navigation)/config/global_costmap_params.yaml" command="load" ns="move_base/global_costmap"/>
        </group>
        
        <group if="$(arg rviz)">
            <node name="rviz" type="rviz" pkg="rviz"/>
        </group>
    
    </group>
    
</launch>

通过此方式启动后各小车的话题名都会在命名空间下。如lizi117/battery。

3.通过调用move_base实现小车自主运动。

move_base提供了动作服务器接口供外部进行调用操作,我们需要建立一个客户端去发送请求。
此处参考动作服务器的调用ros::actionlib动作服务器(action server)在动作客户端(action client)中的调用教程。
通过rostopic list查看动作服务器的接口。move_base客户端代码调用参考如下:
附send_goal.cpp、CMakeLists.txt 、package.xml

/*
 * send_goal.cpp
 *
 *  Created on: 2018.11.15
 *      Author: wxw
 */

#include <ros/ros.h>
#include <move_base_msgs/MoveBaseAction.h>
#include <actionlib/client/simple_action_client.h>
/*move_base_msgs::MoveBaseAction
 move_base在world中的目标
*/ 
typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction>  MoveBaseClient;
int main(int argc, char** argv) {
ros::init(argc, argv, "send_goals_node");

/*
// create the action client
// true causes the client to spin its own thread
//don't need ros::spin()
创建action客户端,参数1:action名,参数2:true,不需要手动调用ros::spin(),会在它的线程中自动调用。
*/
MoveBaseClient ac("move_base", true);
// Wait 60 seconds for the action server to become available
ROS_INFO("Waiting for the move_base action server");
ac.waitForServer(ros::Duration(60));
ROS_INFO("Connected to move base server");
// Send a goal to move_base1
//目标的属性设置
move_base_msgs::MoveBaseGoal goal;
goal.target_pose.header.frame_id = "map";
goal.target_pose.header.stamp = ros::Time::now();
goal.target_pose.pose.position.x = 0.262;
goal.target_pose.pose.position.y = 0.2;
goal.target_pose.pose.orientation.z = -0.78;
goal.target_pose.pose.orientation.w = 0.618;
ROS_INFO("");
ROS_INFO("Sending goal");
ac.sendGoal(goal);
// Wait for the action to return
ac.waitForResult();
if (ac.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
ROS_INFO("You have reached the goal!");
else
ROS_INFO("The base failed for some reason");

// Send a goal to move_base2
//目标的属性设置
move_base_msgs::MoveBaseGoal goal;
goal.target_pose.header.frame_id = "map";
goal.target_pose.header.stamp = ros::Time::now();
goal.target_pose.pose.position.x = 1.18;
goal.target_pose.pose.orientation.z = -0.175;
goal.target_pose.pose.orientation.w = 0.98;
ROS_INFO("");
ROS_INFO("Sending goal");
ac.sendGoal(goal);
// Wait for the action to return
ac.waitForResult();
if (ac.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
ROS_INFO("You have reached the goal!");
else
ROS_INFO("The base failed for some reason");
return 0;
}
#CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(movewanted)

find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  geometry_msgs
  sensor_msgs
  nav_msgs
  tf
  actionlib
  move_base_msgs
)
catkin_package(
  INCLUDE_DIRS 
  CATKIN_DEPENDS roscpp std_msgs sensor_msgs geometry_msgs nav_msgs actionlib  move_base_msgs  
)

include_directories(
   ${catkin_INCLUDE_DIRS} 
)

link_directories(
  
  ${catkin_LIB_DIRS} )

add_executable(send_goal src/send_goal.cpp)
target_link_libraries(send_goal
  ${catkin_LIBRARIES} 
 
)
<!--package.xml-->
<?xml version="1.0"?>
<package>
  <name>movewanted</name>
  <version>1.0.0</version>
  <description>The move point package</description>

 
  <maintainer email="[email protected]">wxw</maintainer>

  <license>BSD</license>


 <buildtool_depend>catkin</buildtool_depend>
  
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>rostime</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_depend>geometry_msgs</build_depend>
  <build_depend>nav_msgs</build_depend>
  <build_depend>move_base_msgs</build_depend>
  <build_depend>actionlib</build_depend>
  <build_depend>tf</build_depend>


  <test_depend>rosbag</test_depend>

 <run_depend>roscpp</run_depend>
 <run_depend>rospy</run_depend>
 <run_depend>rostime</run_depend>
 <run_depend>std_msgs</run_depend>
 <run_depend>sensor_msgs</run_depend>
 <run_depend>geometry_msgs</run_depend>
 <run_depend>nav_msgs</run_depend>
 <run_depend>move_base_msgs</run_depend>
 <run_depend>actionlib</run_depend>
 <run_depend>tf</run_depend>

</package>

4、推荐参考资料

lizi-github

ros_wiki

几本经典教程下载