Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
Haoran-Zhao committed Mar 24, 2018
1 parent d82bf3b commit bc809b4
Show file tree
Hide file tree
Showing 19 changed files with 899 additions and 32 deletions.
27 changes: 27 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# What version of CMake is needed?
cmake_minimum_required(VERSION 2.8.3)

# The name of this package.
project(ur5_notebook)

# Find the catkin build system, and any other packages on which we depend.
find_package(catkin REQUIRED COMPONENTS gazebo_msgs roscpp geometry_msgs turtlesim std_srvs std_msgs message_generation message_runtime)
# Declare our catkin package.

#add_message files
add_message_files(FILES blocks_poses.msg)

generate_messages(DEPENDENCIES std_msgs)

catkin_package()

# Specify locations of header files.
include_directories(include ${catkin_INCLUDE_DIRS})

# Declare the executable, along with its source files.
add_executable(blocks_spawner blocks_spawner.cpp)
add_executable(blocks_poses_publisher blocks_poses_publisher.cpp)

# Specify libraries against which to link.
target_link_libraries(blocks_spawner ${catkin_LIBRARIES})
target_link_libraries(blocks_poses_publisher ${catkin_LIBRARIES})
98 changes: 66 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#### 0. References
- [__`GitHub: utecrobotics/ur5`__](https://github.com/utecrobotics/ur5) testing ur5 motion
- [__`GitHub: utecrobotics/ur5`__](https://github.com/utecrobotics/ur5) testing ur5 motion
- [__`Very useful ROS blog`__](http://www.guyuehome.com/column/ros-explore) ROS探索
- [__`ROS下如何使用moveit驱动UR5机械臂`__](http://blog.csdn.net/jayandchuxu/article/details/54693870)

#### 1. Universal Robot 5 Installation
[`Official installation tutorial`](http://wiki.ros.org/universal_robot)

The following command lines are for ur5 installation in ros-kinetic
The following command lines are for ur5 installation in ros-kinetic
```angularjs
mkdir -p ur5_ws/src
cd ur5_ws/src
# retrieve the sources
git clone -b kinetic-devel https://github.com/ros-industrial/universal_robot.git
cd ~/ur5_ws
# checking dependencies
# checking dependencies
rosdep install --from-paths src --ignore-src --rosdistro kinetic
# buildin,
# buildin,
catkin_make
# if there is any error, try
# if there is any error, try
# pip uninstall em
# pip install empy
# pip install empy
# source this workspace (careful when also sourcing others)
cd ~/ur5_ws
source devel/setup.bash
Expand All @@ -43,7 +43,7 @@ Look into this link for [`straight line motion`](http://answers.gazebosim.org/qu

#### 2. Moveit
[`Official tutorial`](http://docs.ros.org/kinetic/api/moveit_tutorials/html/)
##### 2.0 Install Moveit
##### 2.0 Install Moveit
```
sudo apt-get install ros-kinetic-moveit
```
Expand All @@ -58,7 +58,7 @@ PATH: /src/universal_robot/ur_description/urdf/ur5.urdf.xacro
3. move to the "Virtual Joints" tab. Here, you will define a virtual joint for the base of the robot. Click the "Add Virtual Joint" button, and set the name of this joint to FixedBase, and the parent to world.
4. open the "Planning Groups" tab and click the "Add Group" button. Now, you will create a new group called manipulator, which uses the KDLKinematicsPlugin.
4. open the "Planning Groups" tab and click the "Add Group" button. Now, you will create a new group called manipulator, which uses the KDLKinematicsPlugin.
3. Move Group Python InterFace Tutorial[`Official tutorial`](http://docs.ros.org/indigo/api/moveit_tutorials/html/doc/pr2_tutorials/planning/scripts/doc/move_group_python_interface_tutorial.html)
Expand Down Expand Up @@ -89,7 +89,7 @@ __References__ \
[2] [homesick-nick UR5CubicInterpolation](https://github.com/nick-pestell/UR5CubicInterpolation/blob/master/cubic_interpolation.py)\
[3] [Move Group Python Interface Tutorial
](http://docs.ros.org/kinetic/api/moveit_tutorials/html/doc/pr2_tutorials/planning/scripts/doc/move_group_python_interface_tutorial.html) \
[4] [ur_modern_driver](https://github.com/ThomasTimm/ur_modern_driver)
[4] [ur_modern_driver](https://github.com/ThomasTimm/ur_modern_driver)

#### 3 USB Camera Installation in ROS
[`Reference link`](https://answers.ros.org/question/197651/how-to-install-a-driver-like-usb_cam/)
Expand All @@ -115,27 +115,27 @@ $ roscd usb_cam
# run `roscore` in a new terminal
# Make sure a usb cam is connected
```

To connect external cam.
Locate the usb_cam-test.launch file in folder
To connect external cam.
Locate the usb_cam-test.launch file in folder

`cd ~/ur5_ws/src/usb_cam/launch`
`cd ~/ur5_ws/src/usb_cam/launch`

Change
Change

`<param name="video_device" value="/dev/video0" />`
`<param name="video_device" value="/dev/video0" />`

to
`<param name="video_device" value="/dev/video1" />`

`<param name="video_device" value="/dev/video1" />`

From

`cd ~/catkin-ws/src/usb_cam/launch`
run

`roslaunch usb_cam-test.launch`

If this works, quit the test program, open rviz
Expand All @@ -147,12 +147,12 @@ run the following command in ur5_ws folder (`source devel/setup.bash`)
rosrun usb_cam usb_cam_node
```


#### 4. Revolute-Revolute Manipulator Robot
"[__`RRBot`__](https://github.com/ros-simulation/gazebo_ros_demos), or ''Revolute-Revolute Manipulator Robot'',
is a simple 3-linkage, 2-joint arm that we will use to demonstrate various
features of Gazebo and URDFs.
It essentially a double inverted pendulum and demonstrates some fun
"[__`RRBot`__](https://github.com/ros-simulation/gazebo_ros_demos), or ''Revolute-Revolute Manipulator Robot'',
is a simple 3-linkage, 2-joint arm that we will use to demonstrate various
features of Gazebo and URDFs.
It essentially a double inverted pendulum and demonstrates some fun
control concepts within a simulator."

To get RRBot, clone the gazebo_ros_demos Github repo into the `/src` folder of your catkin workspace and rebuild your workspace:
Expand Down Expand Up @@ -190,7 +190,7 @@ rostopic pub /rrbot/joint2_position_controller/command std_msgs/Float64 "data: -

- [`Tutorial: Using a URDF in Gazebo`](http://gazebosim.org/tutorials/?tut=ros_urdf#Tutorial:UsingaURDFinGazebo)
prerequisite for Gazebo plugins

- [`Tutorial: Using Gazebo plugins with ROS`](http://gazebosim.org/tutorials?tut=ros_gzplugins)
learning to use Gazebo plugins

Expand All @@ -216,7 +216,7 @@ catkin_make
source devel/setup.bash
```

In rviz, the first task is to choose the frame of reference for the visualization. In left panel, __`Global Options/Fixed Frame`__,
In rviz, the first task is to choose the frame of reference for the visualization. In left panel, __`Global Options/Fixed Frame`__,
choose a proper frame (e. g. __`world`__)

Next, we want to view the 3D model of the robot. To accomplish this, we will insert an instance of the `robot model` plugin
Expand All @@ -226,4 +226,38 @@ To test UR5 USB cam, run [`testvision.py`](src/testvision.py)

<p align="center">
<img src="https://github.com/lihuang3/ur5_notebook/blob/master/media/JointSpaceMotionCamera.gif" width="800">
</p>
</p>

#### 5. simulate world in gazebo

- [`Defining Joints in Solidworks to URDF Exporter for a Conveyor Belt`](https://answers.ros.org/question/52309/defining-joints-in-solidworks-to-urdf-exporter-for-a-conveyor-belt/)


- [`Tutorial: simulator in gazebo`](http://wiki.ros.org/simulator_gazebo/Tutorials/Gazebo_ROS_API)
Place the ur5_notebook folder under ros workspace folder. Foe Example: /home/ros_hw/src/ur5_notebook

launch gazebo urdf files :
1.Change the path in initialize. launch from:
```angularjs
<param name="red_box_path" type="str" value="/home/haoran/ros_hw/src/ur5_notebook/urdf/red_box.urdf"/>
```
to
```angularjs
<param name="red_box_path" type="str" value="/home/user_name/ros_hw/src/ur5_notebook/urdf/red_box.urdf"/>
```
2.cd to your ros workspace.
```angularjs
source devel/setup.bash
catkin_make
```
3.launch the gazebo world
```angularjs
roslaunch ur5_notebook initialize.launch
```
4.change object pose and twist with command line if you want to:
```angularjs
rosservice call /gazebo/set_model_state '{model_state: { model_name: red_box, pose: { position: { x: 0, y: 0 ,z: 1 }, orientation: {x: 0, y: 0, z: 0, w: 0 } }, twist: { linear: {x: 0.1 , y: 0 ,z: 0 } , angular: { x: 0.0 , y: 0 , z: 0.0 } } , reference_frame: world } }'
```
<p align="center">
<img src="https://github.com/lihuang3/ur5_notebook/blob/master/media/conveyor.gif" width="500">
</p>
7 changes: 7 additions & 0 deletions blocks_poses.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# message type to describe 3-D position of the cylinder blocks
# variable length array, length decided by topic /current_cylinder_blocks
# to be published as a topic

float64[] x # x coordinate in the world
float64[] y # y coordinate in the world
float64[] z # z coordinate in the world
135 changes: 135 additions & 0 deletions blocks_poses_publisher.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// this node will publish the topic "cylinder_blocks_poses"
// including all current cylinder blocks, pose is 3-D position

// ros communication:
// subscribe to topic "/current_cylinder_blocks"
// subscribe to topic "/gazebo/model_states"
// publish the topic "/cylinder_blocks_poses"

#include <ros/ros.h>
#include <vector>
#include <string>
#include <std_msgs/Int8MultiArray.h>
#include <gazebo_msgs/ModelStates.h>
#include <ur5_notebook/blocks_poses.h>

// global variables
int g_quantity;
std::vector<int8_t> g_current_blocks;
std::vector<double> g_x;
std::vector<double> g_y;
std::vector<double> g_z;
bool g_current_callback_started = false;
bool g_poses_updated = false; // act as frequency control of publish loop

std::string intToString(int a) {
std::stringstream ss;
ss << a;
return ss.str();
}

void currentCallback(const std_msgs::Int8MultiArray& current_blocks) {
// this topic contains information of what cylinder blocks have been spawned
if (!g_current_callback_started) {
// set first time started flag to true
g_current_callback_started = true;
ROS_INFO("current callback has been invoked first time");
}
g_quantity = current_blocks.data.size();
g_current_blocks.resize(g_quantity);
g_current_blocks = current_blocks.data;
}

void modelStatesCallback(const gazebo_msgs::ModelStates& current_model_states) {
// this callback update global values of cylinder positions
if (g_current_callback_started) {
// only update when currentCylinderCallback has been invoked the first time
// get cylinder blocks positions according to settings in g_current_cylinder_blocks
std::vector<double> box_x;
std::vector<double> box_y;
std::vector<double> box_z;
box_x.resize(g_quantity);
box_y.resize(g_quantity);
box_z.resize(g_quantity);
// find position of all current cylinders in topic message
bool poses_completed = true;
for (int i=0; i<g_quantity; i++) {
// get index of ith cylinder
std::string indexed_model_name;
if (g_current_blocks[i] == 0) {
indexed_model_name = "red_cylinder_" + intToString(i);
}
else {
indexed_model_name = "blue_cylinder_" + intToString(i);
}
int index = -1;
int model_quantity = current_model_states.name.size(); // number of models measured
for (int j=0; j<model_quantity; j++) {
if (current_model_states.name[j] == indexed_model_name) {
index = j; break;
}
}
if (index != -1) {
// this model name has been successfully indexed
box_x[i] = current_model_states.pose[index].position.x;
box_y[i] = current_model_states.pose[index].position.y;
box_z[i] = current_model_states.pose[index].position.z;
}
else {
// ROS_ERROR("fail to find model name in the model_states topic");
// in the test run, there is chance that the last cylinder is not in the topic message
// and g_cylinder_quantity (fron spawner node) is larger than the cylinder quantity here
// because /gazebo/model_states are sampled at a high rate of about 1000Hz
// so the position data should be aborted if fail to find the last cylinder
poses_completed = false;
}
}
if (poses_completed) {
// only pass data to globals when they are completed
g_x.resize(g_quantity);
g_y.resize(g_quantity);
g_z.resize(g_quantity);
g_x = box_x;
g_y = box_y;
g_z = box_z;
if (!g_poses_updated) {
// reset flag to true, after updating global value of g_x, g_y, g_z
g_poses_updated = true;
}
}
}
}

int main(int argc, char** argv) {
ros::init(argc, argv, "blocks_poses_publisher");
ros::NodeHandle nh;

// initialize subscribers for "/current_cylinder_blocks" and "/gazebo/model_states"
ros::Subscriber current_subscriber = nh.subscribe("/current_blocks"
, 1, currentCallback);
ros::Subscriber model_states_subscriber = nh.subscribe("/gazebo/model_states", 1, modelStatesCallback);
// initialize publisher for "/cylinder_blocks_poses"
ros::Publisher poses_publisher
= nh.advertise<ur5_notebook::blocks_poses>("blocks_poses", 1);
ur5_notebook::blocks_poses current_poses_msg;

// publishing loop
while (ros::ok()) {
if (g_poses_updated) {
// only publish when cylinder positions are updated
// no need to publish repeated data
g_poses_updated = false; // set flag to false
// there is tiny possibility that g_x is not in the length of g_cylinder_quantity
int local_quantity = g_x.size(); // so get length of g_x
current_poses_msg.x.resize(local_quantity);
current_poses_msg.y.resize(local_quantity);
current_poses_msg.z.resize(local_quantity);
current_poses_msg.x = g_x;
current_poses_msg.y = g_y;
current_poses_msg.z = g_z;
poses_publisher.publish(current_poses_msg);
}
ros::spinOnce();
}
return 0;
}
Loading

0 comments on commit bc809b4

Please sign in to comment.