├── README.md
└── multiDrone-ROS
├── px4ros
├── CMakeLists.txt
├── CMakeLists.txt~
├── msg
│ ├── gpsPosition.msg
│ └── gpsPosition.msg~
├── package.xml
├── package.xml~
├── scripts
│ ├── follower_control_decode.py
│ ├── follower_control_decode.py~
│ ├── leader_control_decode.py
│ ├── leader_control_decode.py~
│ ├── leader_controller.py~
│ ├── main_control.py
│ ├── main_control.py~
│ ├── serial_ros.py
│ └── serial_ros.py~
└── src
│ ├── px4_getpoint_node.cpp
│ ├── px4_getpoint_node.cpp~
│ └── px4_getpoint_node_bp.cpp
└── spiri_go
├── CMakeLists.txt
├── README.md
├── action
├── LandHere.action
└── Takeoff.action
├── include
├── spiri_data_classes.h
├── spiri_go.h
└── spiri_go.h~
├── initialize
└── apm_sim
├── launch
├── apm_pluginlists.yaml
├── collision_avoidance.launch
├── collision_avoidance.launch~
├── jetson.launch
├── kbteleop.launch
├── leader-sitl.launch
├── leader-sitl.launch~
├── leader.launch
├── leader.launch~
├── sitl.launch
├── spiri_go.launch
├── takeoff_and_land.launch
└── takeoff_and_land.launch~
├── package.xml
├── scripts
└── mavkbteleop.py
├── setup.py
├── spiripy
├── __init__.py
├── api.py
└── spiri_except.py
├── src
├── arm_and_takeoff.cpp~
├── collision_avoidance.cpp
├── collision_avoidance.cpp~
├── follower.cpp
├── follower.cpp~
├── leader.cpp
├── leader.cpp~
├── leader_control.cpp
├── leader_control.cpp~
├── leader_go.cpp~
├── read me.txt
├── read me.txt~
├── spiri_data_classes.cpp
├── spiri_go.cpp
├── spiri_go.cpp~
├── spiri_go_client.cpp~
├── takeoff_and_land.cpp
├── takeoff_and_land.cpp~
└── test
│ ├── spiri_go_test.cpp
│ ├── test_com.cpp
│ └── test_com.cpp~
├── srv
├── LastState.srv
└── LocalPosition.srv
└── test
├── api.py
├── sim.py
└── sitl.test
/README.md:
--------------------------------------------------------------------------------
1 | # multiDrone-ROS
2 | 本工程基于开源飞控程序Ardupilot,以及Mavros,实现多个飞行器的编队控制。
3 | Package:
4 | px4ros: 负责数据通信,从串口/网口读写数据,解码接收到的数据
5 | spiri_go: 主程序,程序完整流程和循环控制
6 |
7 | # leader参考代码
8 | px4ros/scripts/seral_ros.py
9 | px4rod/scripts/leader_control_decode.py
10 | spiri_go/src/spiri_go.cpp
11 | spiri_go/src/leader.cpp
12 |
13 | # follower参考代码类似
14 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(px4ros)
3 |
4 | ## Find catkin macros and libraries
5 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
6 | ## is used, also find other catkin packages
7 | find_package(catkin REQUIRED COMPONENTS
8 | roscpp
9 | rospy
10 | std_msgs
11 | mavros
12 | mavros_extras
13 | geometry_msgs
14 | angles
15 |
16 | message_generation
17 | )
18 |
19 | add_message_files(FILES gpsPosition.msg)
20 |
21 | generate_messages()
22 |
23 |
24 | catkin_package(
25 | CATKIN_DEPENDS message_runtime
26 | )
27 |
28 |
29 | include_directories(
30 | ${catkin_INCLUDE_DIRS}
31 | )
32 |
33 |
34 | add_executable(px4ros src/px4_getpoint_node.cpp)
35 |
36 |
37 | target_link_libraries(px4ros
38 | ${catkin_LIBRARIES}
39 | )
40 |
41 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/CMakeLists.txt~:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(px4ros)
3 |
4 | ## Find catkin macros and libraries
5 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
6 | ## is used, also find other catkin packages
7 | find_package(catkin REQUIRED COMPONENTS
8 | roscpp
9 | rospy
10 | std_msgs
11 | mavros
12 | mavros_extras
13 | geometry_msgs
14 | angles
15 |
16 | message_generation
17 | )
18 |
19 | add_message_files(FILES gpsPosition.msg)
20 | generate_messages()
21 |
22 |
23 | catkin_package(
24 | CATKIN_DEPENDS message_runtime
25 | )
26 |
27 |
28 | include_directories(
29 | ${catkin_INCLUDE_DIRS}
30 | )
31 |
32 |
33 | add_executable(px4ros src/px4_getpoint_node.cpp)
34 |
35 |
36 | target_link_libraries(px4ros
37 | ${catkin_LIBRARIES}
38 | )
39 |
40 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/msg/gpsPosition.msg:
--------------------------------------------------------------------------------
1 | float64 lat
2 | float64 lon
3 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/msg/gpsPosition.msg~:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PenguinCheng/multiDrone-ROS/73df4bb83e1091565331f9467f779e4a3ad9bd95/multiDrone-ROS/px4ros/msg/gpsPosition.msg~
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | px4ros
4 | 0.0.0
5 | The px4ros package
6 |
7 |
8 | odroid
9 | TODO
10 |
11 | catkin
12 | roscpp
13 | rospy
14 | std_msgs
15 |
16 | message_generation
17 | roscpp
18 | rospy
19 | std_msgs
20 |
21 | message_runtime
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/package.xml~:
--------------------------------------------------------------------------------
1 |
2 |
3 | px4ros
4 | 0.0.0
5 | The px4ros package
6 |
7 |
8 | odroid
9 | TODO
10 |
11 | catkin
12 | roscpp
13 | rospy
14 | std_msgs
15 |
16 | message_generation
17 | roscpp
18 | rospy
19 | std_msgs
20 |
21 | message_runtime
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/scripts/follower_control_decode.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import rospy
3 | from std_msgs.msg import String
4 | from px4ros.msg import gpsPosition
5 |
6 | def decode_node():
7 | rospy.init_node('px4ros_leader_control_decode', anonymous=True)
8 | pub = rospy.Publisher('neighbour_position', gpsPosition, queue_size=20)
9 | pub2 = rospy.Publisher('neighbour_position_2', gpsPosition, queue_size=20)
10 | rate = rospy.Rate(10) # 10hz
11 |
12 | rospy.Subscriber("serial_data_received", String, decodeInfo)
13 |
14 | position = gpsPosition()
15 | position2 = gpsPosition()
16 | while not rospy.is_shutdown():
17 | position.lat = neighbour_one_lat
18 | position.lon = neighbour_one_lon
19 | pub.publish(position)
20 | rospy.loginfo("1:%s",position)
21 |
22 | position2.lat = neighbour_two_lat
23 | position2.lon = neighbour_two_lon
24 | pub.publish(position2)
25 | rospy.loginfo("2:%s",position2)
26 |
27 | rate.sleep()
28 |
29 | '''callback function'''
30 | def decodeInfo(data):
31 | global neighbour_one_lon
32 | global neighbour_one_lat
33 | global last_neighbour_one_lon
34 | global last_neighbour_one_lat
35 | global neighbour_two_lon
36 | global neighbour_two_lat
37 | global last_neighbour_two_lon
38 | global last_neighbour_two_lat
39 |
40 | if data.data:
41 | latStr = ""
42 | lonStr = ""
43 | latStr2 = ""
44 | lonStr2 = ""
45 | i = 3
46 | if data.data[0:3] == "x1o": #receive the data of leader 1 and leader 2
47 | while i= 6:
26 | # to_send_string = opm_string[5:len(opm_string)-2]
27 | if len(opm_string) > 0:
28 | to_send_string = opm_string
29 | else:
30 | to_send_string = ''
31 |
32 | #print to_send_string
33 | rospy.loginfo("["+"%s"+"] "+"%s",current_milli_time(),to_send_string)
34 | pub.publish(to_send_string)
35 | rate.sleep()
36 |
37 | '''callback function'''
38 | def callback(data):
39 | rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
40 | myserial.write(data.data)
41 |
42 |
43 | if __name__ == '__main__':
44 | myserial = serial.Serial('/dev/ttyUSB0',115200,timeout=None)
45 | print myserial.portstr
46 | try:
47 | serial_node()
48 | except rospy.ROSInterruptException:
49 | pass
50 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/scripts/serial_ros.py~:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | import rospy
3 | from std_msgs.msg import String
4 | import serial
5 | import time
6 |
7 | #function: record current time(s)
8 | current_milli_time = lambda: int(time.time()*1000)
9 |
10 | def serial_node():
11 |
12 | pub = rospy.Publisher('serial_data_received', String, queue_size=20)
13 | rospy.init_node('px4ros_serial', anonymous=True)
14 | rate = rospy.Rate(10) # 10hz
15 |
16 | rospy.Subscriber("serial_data_send", String, callback)
17 |
18 | opm_string = ''
19 | to_send_string = ''
20 |
21 | while not rospy.is_shutdown():
22 | #hello_str = "hello world %s" % rospy.get_time()
23 |
24 | opm_string = myserial.read(myserial.inWaiting())
25 | #if len(opm_string) >= 6:
26 | # to_send_string = opm_string[5:len(opm_string)-2]
27 | if len(opm_string) > 0:
28 | to_send_string = opm_string
29 | else:
30 | to_send_string = ''
31 |
32 | #print to_send_string
33 | rospy.loginfo("["+"%s"+"] "+"%s",current_milli_time(),to_send_string)
34 | pub.publish(to_send_string)
35 | rate.sleep()
36 |
37 | '''callback function'''
38 | def callback(data):
39 | rospy.loginfo(rospy.get_caller_id() + "I heard %s", data.data)
40 | #myserial.write(data.data)
41 |
42 |
43 | if __name__ == '__main__':
44 | myserial = serial.Serial('/dev/ttyUSB0',115200,timeout=None)
45 | print myserial.portstr
46 | try:
47 | serial_node()
48 | except rospy.ROSInterruptException:
49 | pass
50 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/src/px4_getpoint_node.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | //set velocity
13 | ros::Publisher vel_sp_pub;
14 | ros::Publisher gps_pub;
15 | //current position
16 | // next position
17 | geometry_msgs::PoseStamped currentPos,nextPos,initCirclePos;
18 | geometry_msgs::TwistStamped vs;
19 | sensor_msgs::NavSatFix currentGlobalPos;
20 | bool isGetpoint, isGetGPSPoint;
21 | float speed;
22 | //radius
23 | int R = 6371000;
24 |
25 | // go to specific point
26 | void getPoint(double x, double y,double z){
27 | bool reached = false;
28 | double dis = sqrt((currentPos.pose.position.x-x)*(currentPos.pose.position.x-x) +(currentPos.pose.position.y-y)*(currentPos.pose.position.y-y) + (currentPos.pose.position.z-z)*(currentPos.pose.position.z-z));
29 | double thresh = 0.5;
30 | if(dis < thresh){
31 | reached = true;
32 | isGetpoint =false;
33 | ROS_INFO_STREAM("get There!");
34 | }
35 |
36 | geometry_msgs::Point velocityV;
37 | velocityV.x = x - currentPos.pose.position.x;
38 | velocityV.y = y - currentPos.pose.position.y;
39 | velocityV.z = z - currentPos.pose.position.z;
40 |
41 | //set velocity
42 | vs.twist.linear.x = velocityV.x*0.2;
43 | vs.twist.linear.y = velocityV.y*0.2;
44 | vs.twist.linear.z = velocityV.z*0.2;
45 | // ROS_INFO_STREAM("getPoint1");
46 | vs.header.stamp = ros::Time::now();
47 | vel_sp_pub.publish(vs);
48 | }
49 |
50 | //GPS point
51 | void gotoGPSPoint(double lat, double lon){
52 | double delta_x = R * (lat - currentGlobalPos.latitude) * float(3.1415926535898 / 180);
53 | double delta_y = R * (lon - currentGlobalPos.longitude) * float(3.1415926535898 / 180);
54 | vs.twist.linear.x = delta_x*0.1;
55 | vs.twist.linear.y = -delta_y*0.1;
56 | vs.header.stamp = ros::Time::now();
57 | vel_sp_pub.publish(vs);
58 | }
59 |
60 | //received local position
61 | void localPositionReceived(const geometry_msgs::PoseStampedConstPtr& msg){
62 | currentPos = *msg;
63 | }
64 |
65 | //
66 | void serialDataReceived(const std_msgs::String::ConstPtr& msg){
67 | ROS_INFO("I heard:[%s]",msg->data.c_str());
68 | }
69 |
70 | void globalPositionReceived(const sensor_msgs::NavSatFixConstPtr& msg){
71 | currentGlobalPos = *msg;
72 | }
73 |
74 | //keyboard command
75 | void sendCommand(const keyboard::Key &key){
76 | switch (key.code)
77 | {
78 | case 'w':
79 | {
80 | ROS_INFO_STREAM("up");
81 | vs.twist.linear.z += 0.1;
82 | break;
83 | }
84 | case 's':
85 | {
86 | ROS_INFO_STREAM("down");
87 | vs.twist.linear.z -= 0.1;
88 | break;
89 | }
90 | case 'j':
91 | {
92 | ROS_INFO_STREAM("left");
93 | vs.twist.linear.y += 0.1;
94 | break;
95 | }
96 | case 'l':
97 | {
98 | ROS_INFO_STREAM("right");
99 | vs.twist.linear.y -= 0.1;
100 | break;
101 | }
102 | case 'i':
103 | {
104 | ROS_INFO_STREAM("forward");
105 | vs.twist.linear.x += 0.1;
106 | break;
107 | }
108 | case 'k':
109 | {
110 | ROS_INFO_STREAM("backward");
111 | vs.twist.linear.x -= 0.1;
112 | break;
113 | }
114 | case 'u':
115 | {
116 | ROS_INFO_STREAM("rotate left");
117 | vs.twist.angular.z += 0.1;
118 | break;
119 | }
120 | case 'o':
121 | {
122 | ROS_INFO_STREAM("rotate right");
123 | vs.twist.angular.z -= 0.1;
124 | break;
125 | }
126 | case 'p':
127 | {
128 | isGetpoint = true;
129 | isGetGPSPoint = false;
130 | ROS_INFO_STREAM("get to point 10 10 3");
131 | break;
132 | }
133 | case 'g':
134 | {
135 | isGetGPSPoint = true;
136 | isGetpoint = false;
137 | ROS_INFO_STREAM("get to GPS point");
138 | break;
139 | }
140 | case 'h':
141 | {
142 | // turn to manual mode
143 | isGetpoint = false;
144 | isGetGPSPoint =false;
145 | vs.twist.linear.x = 0;
146 | vs.twist.linear.y = 0;
147 | vs.twist.linear.z = 0;
148 | vs.twist.angular.z = 0;
149 | ROS_INFO_STREAM("Manual Mode");
150 | break;
151 | }
152 |
153 | case 'a':
154 | {
155 | speed += 0.1;
156 | ROS_INFO_STREAM("speed up" << speed);
157 | break;
158 | }
159 | case 'd':
160 | {
161 | speed -= 0.1;
162 | ROS_INFO_STREAM("speed down" << speed);
163 | break;
164 | }
165 |
166 |
167 | default:
168 | {
169 |
170 | }
171 |
172 | }
173 | }
174 |
175 | int main(int argc, char **argv){
176 | ros::init(argc, argv, "px4_offboard_velocity_control_node");
177 | ros::NodeHandle nodeHandle;
178 | //publish set_velocity topic 100ms
179 | vel_sp_pub = nodeHandle.advertise("/mavros/setpoint_velocity/cmd_vel", 10);
180 | ros::Subscriber commandSubscriber = nodeHandle.subscribe("/keyboard/keydown",1,sendCommand);
181 | ros::Subscriber localPositionSubsciber = nodeHandle.subscribe("/mavros/local_position/local", 10, localPositionReceived);
182 | ros::Subscriber globalPositionSubsciber = nodeHandle.subscribe("/mavros/global_position/raw/fix", 10, globalPositionReceived);
183 |
184 | gps_pub = nodeHandle.advertise("serial_data_send", 10);
185 | ros::Subscriber serialSubscriber = nodeHandle.subscribe("serial_data_received", 10, serialDataReceived);
186 |
187 | isGetpoint = false;
188 | isGetGPSPoint = false;
189 | speed = 0.2;
190 | //ros rate
191 | ros::Rate loop_rate(10.0);
192 |
193 | while(ros::ok())
194 | {
195 |
196 | vs.header.seq++;
197 | //GPS topic
198 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.longitude);
199 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.latitude);
200 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.altitude);
201 |
202 | if((!isGetpoint) && (!isGetGPSPoint)){
203 |
204 | vs.header.stamp = ros::Time::now();
205 | //ROS_INFO_STREAM("send ps" << ps);
206 | vel_sp_pub.publish(vs);
207 | }else if(isGetGPSPoint) {
208 | gotoGPSPoint(55.7530147,37.6273584);
209 | ROS_INFO_STREAM("GPS");
210 | }else if(isGetpoint){
211 | getPoint(10,10,3);
212 | ROS_INFO_STREAM("local position");
213 | }
214 |
215 | std_msgs::String gps_location;
216 | std::stringstream ss;
217 | ss << "o120.11111111a30.3333333333#";
218 | gps_location.data = ss.str();
219 | gps_pub.publish(gps_location);
220 |
221 | ros::spinOnce();
222 |
223 | loop_rate.sleep();
224 | }
225 | }
226 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/src/px4_getpoint_node.cpp~:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | //set velocity
14 | ros::Publisher vel_sp_pub;
15 | ros::Publisher gps_pub;
16 | //current position
17 | // next position
18 | geometry_msgs::PoseStamped currentPos,nextPos,initCirclePos;
19 | geometry_msgs::TwistStamped vs;
20 | sensor_msgs::NavSatFix currentGlobalPos;
21 | bool isGetpoint, isGetGPSPoint;
22 | float speed;
23 | //radius
24 | int R = 6371000;
25 |
26 | // go to specific point
27 | void getPoint(double x, double y,double z){
28 | bool reached = false;
29 | double dis = sqrt((currentPos.pose.position.x-x)*(currentPos.pose.position.x-x) +(currentPos.pose.position.y-y)*(currentPos.pose.position.y-y) + (currentPos.pose.position.z-z)*(currentPos.pose.position.z-z));
30 | double thresh = 0.5;
31 | if(dis < thresh){
32 | reached = true;
33 | isGetpoint =false;
34 | ROS_INFO_STREAM("get There!");
35 | }
36 |
37 | geometry_msgs::Point velocityV;
38 | velocityV.x = x - currentPos.pose.position.x;
39 | velocityV.y = y - currentPos.pose.position.y;
40 | velocityV.z = z - currentPos.pose.position.z;
41 |
42 | //set velocity
43 | vs.twist.linear.x = velocityV.x*0.2;
44 | vs.twist.linear.y = velocityV.y*0.2;
45 | vs.twist.linear.z = velocityV.z*0.2;
46 | // ROS_INFO_STREAM("getPoint1");
47 | vs.header.stamp = ros::Time::now();
48 | vel_sp_pub.publish(vs);
49 | }
50 |
51 | //GPS point
52 | void gotoGPSPoint(double lat, double lon){
53 | double delta_x = R * (lat - currentGlobalPos.latitude) * float(3.1415926535898 / 180);
54 | double delta_y = R * (lon - currentGlobalPos.longitude) * float(3.1415926535898 / 180);
55 | vs.twist.linear.x = delta_x*0.1;
56 | vs.twist.linear.y = -delta_y*0.1;
57 | vs.header.stamp = ros::Time::now();
58 | vel_sp_pub.publish(vs);
59 | }
60 |
61 | //received local position
62 | void localPositionReceived(const geometry_msgs::PoseStampedConstPtr& msg){
63 | currentPos = *msg;
64 | }
65 |
66 | //
67 | void serialDataReceived(const std_msgs::String::ConstPtr& msg){
68 | ROS_INFO("I heard:[%s]",msg->data.c_str());
69 | }
70 |
71 | void globalPositionReceived(const sensor_msgs::NavSatFixConstPtr& msg){
72 | currentGlobalPos = *msg;
73 | }
74 |
75 | //keyboard command
76 | void sendCommand(const keyboard::Key &key){
77 | switch (key.code)
78 | {
79 | case 'w':
80 | {
81 | ROS_INFO_STREAM("up");
82 | vs.twist.linear.z += 0.1;
83 | break;
84 | }
85 | case 's':
86 | {
87 | ROS_INFO_STREAM("down");
88 | vs.twist.linear.z -= 0.1;
89 | break;
90 | }
91 | case 'j':
92 | {
93 | ROS_INFO_STREAM("left");
94 | vs.twist.linear.y += 0.1;
95 | break;
96 | }
97 | case 'l':
98 | {
99 | ROS_INFO_STREAM("right");
100 | vs.twist.linear.y -= 0.1;
101 | break;
102 | }
103 | case 'i':
104 | {
105 | ROS_INFO_STREAM("forward");
106 | vs.twist.linear.x += 0.1;
107 | break;
108 | }
109 | case 'k':
110 | {
111 | ROS_INFO_STREAM("backward");
112 | vs.twist.linear.x -= 0.1;
113 | break;
114 | }
115 | case 'u':
116 | {
117 | ROS_INFO_STREAM("rotate left");
118 | vs.twist.angular.z += 0.1;
119 | break;
120 | }
121 | case 'o':
122 | {
123 | ROS_INFO_STREAM("rotate right");
124 | vs.twist.angular.z -= 0.1;
125 | break;
126 | }
127 | case 'p':
128 | {
129 | isGetpoint = true;
130 | isGetGPSPoint = false;
131 | ROS_INFO_STREAM("get to point 10 10 3");
132 | break;
133 | }
134 | case 'g':
135 | {
136 | isGetGPSPoint = true;
137 | isGetpoint = false;
138 | ROS_INFO_STREAM("get to GPS point");
139 | break;
140 | }
141 | case 'h':
142 | {
143 | // turn to manual mode
144 | isGetpoint = false;
145 | isGetGPSPoint =false;
146 | vs.twist.linear.x = 0;
147 | vs.twist.linear.y = 0;
148 | vs.twist.linear.z = 0;
149 | vs.twist.angular.z = 0;
150 | ROS_INFO_STREAM("Manual Mode");
151 | break;
152 | }
153 |
154 | case 'a':
155 | {
156 | speed += 0.1;
157 | ROS_INFO_STREAM("speed up" << speed);
158 | break;
159 | }
160 | case 'd':
161 | {
162 | speed -= 0.1;
163 | ROS_INFO_STREAM("speed down" << speed);
164 | break;
165 | }
166 |
167 |
168 | default:
169 | {
170 |
171 | }
172 |
173 | }
174 | }
175 |
176 | int main(int argc, char **argv){
177 | ros::init(argc, argv, "px4_offboard_velocity_control_node");
178 | ros::NodeHandle nodeHandle;
179 | //publish set_velocity topic 100ms
180 | vel_sp_pub = nodeHandle.advertise("/mavros/setpoint_velocity/cmd_vel", 10);
181 | ros::Subscriber commandSubscriber = nodeHandle.subscribe("/keyboard/keydown",1,sendCommand);
182 | ros::Subscriber localPositionSubsciber = nodeHandle.subscribe("/mavros/local_position/local", 10, localPositionReceived);
183 | ros::Subscriber globalPositionSubsciber = nodeHandle.subscribe("/mavros/global_position/raw/fix", 10, globalPositionReceived);
184 |
185 | gps_pub = nodeHandle.advertise("serial_data_send", 10);
186 | ros::Subscriber serialSubscriber = nodeHandle.subscribe("serial_data_received", 10, serialDataReceived);
187 |
188 | isGetpoint = false;
189 | isGetGPSPoint = false;
190 | speed = 0.2;
191 | //ros rate
192 | ros::Rate loop_rate(10.0);
193 |
194 | while(ros::ok())
195 | {
196 |
197 | vs.header.seq++;
198 | //GPS topic
199 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.longitude);
200 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.latitude);
201 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.altitude);
202 |
203 | if((!isGetpoint) && (!isGetGPSPoint)){
204 |
205 | vs.header.stamp = ros::Time::now();
206 | //ROS_INFO_STREAM("send ps" << ps);
207 | vel_sp_pub.publish(vs);
208 | }else if(isGetGPSPoint) {
209 | gotoGPSPoint(55.7530147,37.6273584);
210 | ROS_INFO_STREAM("GPS");
211 | }else if(isGetpoint){
212 | getPoint(10,10,3);
213 | ROS_INFO_STREAM("local position");
214 | }
215 |
216 | std_msgs::String gps_location;
217 | std::stringstream ss;
218 | ss << "o120.11111111a30.3333333333#";
219 | gps_location.data = ss.str();
220 | gps_pub.publish(gps_location);
221 |
222 | ros::spinOnce();
223 |
224 | loop_rate.sleep();
225 | }
226 | }
227 |
--------------------------------------------------------------------------------
/multiDrone-ROS/px4ros/src/px4_getpoint_node_bp.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | //set velocity
10 | ros::Publisher vel_sp_pub;
11 | //current position
12 | // next position
13 | geometry_msgs::PoseStamped currentPos,nextPos,initCirclePos;
14 | geometry_msgs::TwistStamped vs;
15 | sensor_msgs::NavSatFix currentGlobalPos;
16 | bool isGetpoint, isGetGPSPoint;
17 | float speed;
18 | //radius
19 | int R = 6371000;
20 |
21 | // go to specific point
22 | void getPoint(double x, double y,double z){
23 | bool reached = false;
24 | double dis = sqrt((currentPos.pose.position.x-x)*(currentPos.pose.position.x-x) +(currentPos.pose.position.y-y)*(currentPos.pose.position.y-y) + (currentPos.pose.position.z-z)*(currentPos.pose.position.z-z));
25 | double thresh = 0.5;
26 | if(dis < thresh){
27 | reached = true;
28 | isGetpoint =false;
29 | ROS_INFO_STREAM("get There!");
30 | }
31 |
32 | geometry_msgs::Point velocityV;
33 | velocityV.x = x - currentPos.pose.position.x;
34 | velocityV.y = y - currentPos.pose.position.y;
35 | velocityV.z = z - currentPos.pose.position.z;
36 |
37 | //set velocity
38 | vs.twist.linear.x = velocityV.x*0.2;
39 | vs.twist.linear.y = velocityV.y*0.2;
40 | vs.twist.linear.z = velocityV.z*0.2;
41 | // ROS_INFO_STREAM("getPoint1");
42 | vs.header.stamp = ros::Time::now();
43 | vel_sp_pub.publish(vs);
44 | }
45 |
46 | //GPS point
47 | void gotoGPSPoint(double lat, double lon){
48 | double delta_x = R * (lat - currentGlobalPos.latitude) * float(3.1415926535898 / 180);
49 | double delta_y = R * (lon - currentGlobalPos.longitude) * float(3.1415926535898 / 180);
50 | vs.twist.linear.x = delta_x*0.1;
51 | vs.twist.linear.y = -delta_y*0.1;
52 | vs.header.stamp = ros::Time::now();
53 | vel_sp_pub.publish(vs);
54 | }
55 | //received local position
56 | void localPositionReceived(const geometry_msgs::PoseStampedConstPtr& msg){
57 | currentPos = *msg;
58 | }
59 |
60 | void globalPositionReceived(const sensor_msgs::NavSatFixConstPtr& msg){
61 | currentGlobalPos = *msg;
62 | }
63 | //keyboard command
64 | void sendCommand(const keyboard::Key &key){
65 | switch (key.code)
66 | {
67 | case 'w':
68 | {
69 | ROS_INFO_STREAM("up");
70 | vs.twist.linear.z += 0.1;
71 | break;
72 | }
73 | case 's':
74 | {
75 | ROS_INFO_STREAM("down");
76 | vs.twist.linear.z -= 0.1;
77 | break;
78 | }
79 | case 'j':
80 | {
81 | ROS_INFO_STREAM("left");
82 | vs.twist.linear.y += 0.1;
83 | break;
84 | }
85 | case 'l':
86 | {
87 | ROS_INFO_STREAM("right");
88 | vs.twist.linear.y -= 0.1;
89 | break;
90 | }
91 | case 'i':
92 | {
93 | ROS_INFO_STREAM("forward");
94 | vs.twist.linear.x += 0.1;
95 | break;
96 | }
97 | case 'k':
98 | {
99 | ROS_INFO_STREAM("backward");
100 | vs.twist.linear.x -= 0.1;
101 | break;
102 | }
103 | case 'u':
104 | {
105 | ROS_INFO_STREAM("rotate left");
106 | vs.twist.angular.z += 0.1;
107 | break;
108 | }
109 | case 'o':
110 | {
111 | ROS_INFO_STREAM("rotate right");
112 | vs.twist.angular.z -= 0.1;
113 | break;
114 | }
115 | case 'p':
116 | {
117 | isGetpoint = true;
118 | isGetGPSPoint = false;
119 | ROS_INFO_STREAM("get to point 10 10 3");
120 | break;
121 | }
122 | case 'g':
123 | {
124 | isGetGPSPoint = true;
125 | isGetpoint = false;
126 | ROS_INFO_STREAM("get to GPS point");
127 | break;
128 | }
129 | case 'h':
130 | {
131 | // turn to manual mode
132 | isGetpoint = false;
133 | isGetGPSPoint =false;
134 | vs.twist.linear.x = 0;
135 | vs.twist.linear.y = 0;
136 | vs.twist.linear.z = 0;
137 | vs.twist.angular.z = 0;
138 | ROS_INFO_STREAM("Manual Mode");
139 | break;
140 | }
141 |
142 | case 'a':
143 | {
144 | speed += 0.1;
145 | ROS_INFO_STREAM("speed up" << speed);
146 | break;
147 | }
148 | case 'd':
149 | {
150 | speed -= 0.1;
151 | ROS_INFO_STREAM("speed down" << speed);
152 | break;
153 | }
154 |
155 |
156 | default:
157 | {
158 |
159 | }
160 |
161 | }
162 | }
163 | int main(int argc, char **argv){
164 | ros::init(argc, argv, "px4_offboard_velocity_control_node");
165 | ros::NodeHandle nodeHandle;
166 | //publish set_velocity topic 100ms
167 | vel_sp_pub = nodeHandle.advertise("/mavros/setpoint_velocity/cmd_vel", 10);
168 | ros::Subscriber commandSubscriber = nodeHandle.subscribe("/keyboard/keydown",1,sendCommand);
169 | ros::Subscriber localPositionSubsciber = nodeHandle.subscribe("/mavros/local_position/local", 10, localPositionReceived);
170 | ros::Subscriber globalPositionSubsciber = nodeHandle.subscribe("/mavros/global_position/raw/fix", 10, globalPositionReceived);
171 | isGetpoint = false;
172 | isGetGPSPoint = false;
173 | speed = 0.2;
174 | //ros rate
175 | ros::Rate loop_rate(10.0);
176 |
177 | while(ros::ok())
178 | {
179 |
180 | vs.header.seq++;
181 | //GPS topic
182 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.longitude);
183 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.latitude);
184 | // ROS_INFO_STREAM("GPS longitude" << currentGlobalPos.altitude);
185 |
186 | if((!isGetpoint) && (!isGetGPSPoint)){
187 |
188 | vs.header.stamp = ros::Time::now();
189 | //ROS_INFO_STREAM("send ps" << ps);
190 | vel_sp_pub.publish(vs);
191 | }else if(isGetGPSPoint) {
192 | gotoGPSPoint(55.7530147,37.6273584);
193 | ROS_INFO_STREAM("GPS");
194 | }else if(isGetpoint){
195 | getPoint(10,10,3);
196 | ROS_INFO_STREAM("local position");
197 | }
198 | ros::spinOnce();
199 |
200 | loop_rate.sleep();
201 | }
202 | }
203 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.3)
2 | project(spiri_go)
3 |
4 | ## Find catkin macros and libraries
5 | ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
6 | ## is used, also find other catkin packages
7 | find_package(catkin REQUIRED COMPONENTS
8 | roscpp
9 | rospy
10 | std_msgs
11 | actionlib_msgs
12 | actionlib
13 | )
14 |
15 |
16 | include_directories(
17 | ${catkin_INCLUDE_DIRS}
18 | )
19 |
20 |
21 | find_package(PythonLibs 2.7 REQUIRED)
22 | find_package(PythonInterp 2.7 REQUIRED)
23 | EXEC_PROGRAM ("${PYTHON_EXECUTABLE}"
24 | ARGS "-c 'import numpy; print numpy.get_include()'"
25 | OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
26 | RETURN_VALUE NUMPY_NOT_FOUND)
27 |
28 |
29 | # find_package(OpenCV REQUIRED)
30 |
31 | ## Add folders to be run by python nosetests
32 | # catkin_add_nosetests(test)
33 |
34 | include_directories(include ${catkin_INCLUDE_DIRS})
35 | include_directories(/usr/include/python2.7/)
36 |
37 |
38 | ###############################################
39 | ## Things needed to add messages should be here
40 | ###############################################
41 | add_service_files(
42 | FILES LocalPosition.srv LastState.srv
43 | )
44 | add_action_files(
45 | DIRECTORY action
46 | FILES Takeoff.action LandHere.action
47 | )
48 | ##############################
49 | ## Now generate those messages
50 | ##############################
51 | generate_messages(
52 | DEPENDENCIES actionlib_msgs std_msgs # Or other packages containing msgs
53 | )
54 | ######################
55 | ## Call catkin_package
56 | ######################
57 | catkin_package(
58 | CATKIN_DEPENDS actionlib_msgs
59 | )
60 |
61 | #######################################
62 | ## Use Cmake commands to build the code
63 | #######################################
64 | add_library(spiri_data_classes src/spiri_data_classes.cpp)
65 | target_link_libraries(spiri_data_classes ${catkin_LIBRARIES})
66 | add_executable(spiri_go src/spiri_go.cpp)
67 | add_dependencies(spiri_go spiri_go_generate_messages_cpp)
68 | target_link_libraries(spiri_go spiri_data_classes ${catkin_LIBRARIES} ${Boost_LIBRARIES})
69 | #add_library(spiri_boost src/spiri_boost.cpp)
70 | #target_link_libraries(spiri_boost ${catkin_LIBRARIES} ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} spiri_go spiri_data_classes)
71 |
72 | # Test
73 | if(CATKIN_ENABLE_TESTING)
74 | find_package(rostest REQUIRED)
75 | add_rostest_gtest(spiri_go_test test/sitl.test src/test/spiri_go_test.cpp)
76 | target_link_libraries(spiri_go_test ${catkin_LIBRARIES} ${GTEST_LIBRARIES})
77 | endif()
78 |
79 | #my test
80 | add_executable(takeoff_and_land src/takeoff_and_land.cpp)
81 | add_dependencies(takeoff_and_land spiri_go_generate_messages_cpp)
82 | target_link_libraries(takeoff_and_land spiri_data_classes ${catkin_LIBRARIES} ${Boost_LIBRARIES})
83 |
84 | add_executable(leader_control src/leader_control.cpp)
85 | add_dependencies(leader_control spiri_go_generate_messages_cpp)
86 | target_link_libraries(leader_control spiri_data_classes ${catkin_LIBRARIES} ${Boost_LIBRARIES})
87 |
88 | add_executable(collision_avoidance src/collision_avoidance.cpp)
89 | add_dependencies(collision_avoidance spiri_go_generate_messages_cpp)
90 | target_link_libraries(collision_avoidance spiri_data_classes ${catkin_LIBRARIES} ${Boost_LIBRARIES})
91 |
92 | add_executable(leader src/leader.cpp)
93 | add_dependencies(leader spiri_go_generate_messages_cpp)
94 | target_link_libraries(leader spiri_data_classes ${catkin_LIBRARIES} ${Boost_LIBRARIES})
95 |
96 | add_executable(follower src/follower.cpp)
97 | add_dependencies(follower spiri_go_generate_messages_cpp)
98 | target_link_libraries(follower spiri_data_classes ${catkin_LIBRARIES} ${Boost_LIBRARIES})
99 |
100 | add_executable(test_com src/test/test_com.cpp)
101 | add_dependencies(test_com spiri_go_generate_messages_cpp)
102 | target_link_libraries(test_com spiri_data_classes ${catkin_LIBRARIES} ${Boost_LIBRARIES})
103 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/README.md:
--------------------------------------------------------------------------------
1 | # SpiriGo
2 |
3 | SpiriGo is a ROS package for performing autonomous flights with a MAVLink UAV. It is built upon [`mavros`](http://wiki.ros.org/mavros) and [ArduPilot](https://github.com/diydrones/ardupilot).
4 |
5 | SpiriGo is currently in very early stages of development. We have some features planned for later:
6 |
7 | - Trajectory planning for goals
8 | - SLAM
9 | - Depth mapping
10 |
11 | But for now it provides some basic convenience methods for `mavros` use.
12 |
13 | ## Installation and Usage
14 |
15 | ### On the Jetson TK1
16 |
17 | SpiriGo is primarily being developed for use on the [Jetson TK1](http://www.nvidia.ca/object/jetson-tk1-embedded-dev-kit.html) for now. We have thus created an [automated install script](https://github.com/Pleiades-Spiri/spiri_go/blob/master/install-spirigo.sh) that will install necessary components on the Jetson for autonomous UAV development. This includes:
18 |
19 | - [ROS Indigo](http://wiki.ros.org/indigo),
20 | - [CUDA 6.5](https://developer.nvidia.com/cuda-toolkit-65), and
21 | - [OpenCV4Tegra](http://elinux.org/Jetson/Computer_Vision_Performance#Hardware_Acceleration_of_OpenCV).
22 |
23 | Although it is [generally recognized that ROS is incompatible with OpenCV4Tegra](http://wiki.ros.org/NvidiaJetsonTK1), our install script correctly works around the issue via [methods outlined in this post](https://devtalk.nvidia.com/default/topic/835118/embedded-systems/incorrect-configuration-in-opencv4tegra-debian-packages-and-solution). To install:
24 |
25 | 1. Flash your Jetson with the latest L4T using [Jetpack](https://developer.nvidia.com/embedded/jetson-development-pack-archive);
26 | 2. Install the [Grinch kernel](https://devtalk.nvidia.com/default/topic/766303/embedded-systems/-customkernel-the-grinch-19-3-8-for-jetson-tk1-developed/) for your version of L4T; then
27 | 3. Get the installation script and run it *without* root:
28 |
29 | ```bash
30 | $ wget https://raw.githubusercontent.com/Pleiades-Spiri/spiri_go/master/install-spirigo.sh
31 | $ chmod +x install-spirigo.sh
32 | $ ./install-spirigo.sh
33 | ```
34 |
35 | Note: you will be prompted for your password right away even though it's without `sudo`.
36 |
37 | #### Connect the Jetson to the Pixhawk via serial/UART connection
38 |
39 | 1. Connect the Jetson's UART ports to an added voltage converter (1.8 V to 5V);
40 | 2. Connect the voltage converter to the Pixhawk;
41 | 3. Make sure that the serial connection is established by checking `/dev/ttyTHS0`;
42 | 4. Validate the Jetson to Pixhawk communication using maximum baud rate (921600).
43 |
44 | | TK1 | TXB0104 | Pixhawk |
45 | | ------------- | ----------- | ------- |
46 | | 1.8V: P37 | VCCA - VCCB | 5V: P1 |
47 | | GND: P38 | GND - GND | GND: P6 |
48 | | TXd1: P41 | A1 - B1 | TX1: P2 |
49 | | RXd1: P44 | A2 - B2 | RX1: P3 |
50 |
51 | See [this diagram](https://drive.google.com/open?id=0BxXn6LyBxnG6b01mc1N5X2diVlU) for pinout details.
52 |
53 | #### Running the launch file
54 |
55 | Use this command to launch SpiriGo with serial communication:
56 |
57 | ```
58 | $ roslaunch spiri_go jetson.launch
59 | ```
60 |
61 | If you see
62 |
63 | ```
64 | $ [ INFO] [1447370932.205419674]: CON: Got HEARTBEAT, connected.
65 | ```
66 |
67 | It means you've succeeded. Note the baud rate is set to `921600` because that's the highest allowed by `mavros`. We're looking into increasing this to `1500000` maybe if we really need to.
68 |
69 | ### On Ubuntu 14.04 desktop (for simulator)
70 |
71 | To run the simulator, clone a copy of the ardupilot project from ArduPilot. Follow the directions at [ArduPilot SITL](http://dev.ardupilot.com/wiki/sitl-simulator-software-in-the-loop) to set up the simulator. There is also a script, `initalization/apm_sim` that will do this set-up automatically.
72 |
73 | This script is meant to be ran from a fresh Ubuntu 14.04 installation. Please proceed with caution if you plan on installing on a system with ROS already installed.
74 |
75 | ```bash
76 | $ wget https://raw.githubusercontent.com/Pleiades-Spiri/spiri_go/master/initialize/apm_sim
77 | $ chmod +x apm_sim
78 | $ ./apm_sim
79 | ```
80 |
81 | #### Running the simulator and the launch file
82 |
83 | Start the simulator with:
84 |
85 | ```bash
86 | $ sim_vehicle.sh --map --console --aircraft test
87 | ```
88 |
89 | Next launch the sitl node for spiri:
90 |
91 | ```bash
92 | $ roslaunch spiri_go sitl.launch
93 | ```
94 |
95 | Note: if you're running this the first time, you may need to disable RC calibration pre-arm check via the `mavproxy` console.
96 |
97 | If you are using a ground control station such as APM Planner 2, it should connect on UDP port `14551`.
98 |
99 | ### Python API
100 |
101 | We also provide a python API to control Spiri, using the services and actions provided by the ROS library.
102 |
103 | To install this on your system, run:
104 |
105 | ```bash
106 | $ python setup.py install
107 | ```
108 |
109 | from the root of this repository.
110 |
111 | To use this in a python script, include the following line:
112 |
113 | ```python
114 | from spiripy import api
115 | spiri = api.SpiriGo()
116 | ```
117 |
118 | `spiri` will then be a SpiriGo instance with the following methods:
119 |
120 | ```python
121 | wait_for_ros([timeout])
122 | wait_for_fcu([timeout])
123 | get_state()
124 | get_local_position()
125 | takeoff([height])
126 | land()
127 | ```
128 |
129 | Your script can be launched as a normal python scripts, but `spiri_go`, and `mavros` packages must be running in the background for it to control a quadcopter.
130 |
131 | Detailed API documentation coming soon.
132 |
133 | ## Generating documentation
134 |
135 | TODO
136 |
137 | ## Developers
138 |
139 | ### Running tests
140 |
141 | To test the python API, run:
142 |
143 | ```bash
144 | $ python test/api.py
145 | ```
146 |
147 | To test those parts that require the simulator running, use:
148 |
149 | ```bash
150 | $ python test/sim.py
151 | ```
152 |
153 | Any new methods that are made MUST have a corresponding unit test, and if possible should have a corresponding unit test with the simulator. It is good practice to write the test before implementing the method.
154 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/action/LandHere.action:
--------------------------------------------------------------------------------
1 | #goal definition
2 | int32 height
3 | ---
4 | #result definition
5 | ---
6 | #feedback
7 | int32 currentHeight
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/action/Takeoff.action:
--------------------------------------------------------------------------------
1 | #goal definition
2 | float32 height
3 | ---
4 | #result definition
5 | ---
6 | #feedback
7 | int32 currentHeight
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/include/spiri_data_classes.h:
--------------------------------------------------------------------------------
1 | #ifndef __SPIRI_DATA_CLASSES_H__
2 | #define __SPIRI_DATA_CLASSES_H__
3 |
4 | class SpiriAttitude{
5 | public:
6 | double roll, pitch, yaw;
7 | SpiriAttitude();
8 | SpiriAttitude(double roll, double pitch, double yaw);
9 | };
10 |
11 | #endif //__SPIRI_DATA_CLASSES__
12 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/include/spiri_go.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef __SPIRIGO_H
4 | #define __SPIRIGO_H
5 |
6 |
7 | #include "ros/ros.h"
8 | #include "geometry_msgs/Twist.h"
9 | #include "geometry_msgs/Vector3Stamped.h"
10 | #include "geometry_msgs/Pose.h"
11 | #include "sensor_msgs/Image.h"
12 | #include "sensor_msgs/Imu.h"
13 | #include
14 | #include "tf/tfMessage.h"
15 | #include "tf/transform_listener.h"
16 | #include "tf/transform_broadcaster.h"
17 | #include "tf2_ros/buffer.h"
18 | #include "tf2_ros/transform_listener.h"
19 | #include
20 | #include
21 | #include "std_msgs/Empty.h"
22 | #include "std_srvs/Empty.h"
23 | #include "mavros_msgs/State.h"
24 | #include "mavros_msgs/Mavlink.h"
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | using namespace std;
34 |
35 | class SpiriGo
36 | {
37 | private:
38 | // subscribers
39 | // the local position of the copter
40 | ros::Subscriber local;
41 | // the state of the copter
42 | ros::Subscriber state;
43 | // the gps position, I add
44 | ros::Subscriber gps;
45 | // the height, I add
46 | ros::Subscriber alt;
47 | // the connect state, I add
48 | ros::Subscriber connect_state;
49 |
50 | // publishers
51 | // sets the velocity
52 | ros::Publisher vel;
53 | ros::Publisher rc_out;
54 |
55 | // service clients
56 | // Arm the copter
57 | ros::ServiceClient arm;
58 | // a service to set the mode
59 | ros::ServiceClient set_mode;
60 | // a service to set the stream rate
61 | ros::ServiceClient set_stream_rate;
62 | // tell the copter to take off
63 | ros::ServiceClient takeoff;
64 | // MAVLink service for other needs
65 | ros::ServiceClient mavlink_cmd_srv;
66 |
67 | ros::NodeHandle nh;
68 |
69 | // save last imu received for forwarding...
70 | sensor_msgs::Imu lastLocalReceived;
71 |
72 | // ROS message callbacks
73 | void localSubCb(const geometry_msgs::PoseStamped localPtr);
74 | void stateSubCb(const mavros_msgs::State);
75 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg); //I add
76 | void altSubCb(const sensor_msgs::NavSatFixConstPtr& msg);
77 | void connectSubCb(const mavros_msgs::MavlinkPtr& fromPtr);
78 |
79 | // state variables
80 | mavros_msgs::State last_state;
81 | bool taking_off; // has taken off
82 | bool flying; // has finished taking off
83 |
84 | // location last returned by mavros
85 | geometry_msgs::Pose last_location;
86 | // guess of nearest location, itegrated using velocity
87 | geometry_msgs::Pose location;
88 | // target velocity
89 | geometry_msgs::Twist velocity;
90 | // gps returned by mavros, I add
91 | sensor_msgs::NavSatFix last_gps;
92 | // height
93 | sensor_msgs::NavSatFix last_alt;
94 | //
95 | mavros_msgs::Mavlink last_connect_state;
96 |
97 | // internal control methods
98 | geometry_msgs::Quaternion getOrientation();
99 | bool setMode(const char* targetMode);
100 | bool setArmed();
101 | //bool setGuided();
102 | void takeOff(float targetAlt);
103 |
104 | // service callbacks
105 | bool getLocalPositionSCB(spiri_go::LocalPosition::Request &req, spiri_go::LocalPosition::Response &rsp);
106 | bool getLastStateSCB(spiri_go::LastState::Request &req, spiri_go::LastState::Response &rsp);
107 |
108 | void updateLocation(ros::Duration dt);
109 |
110 | public:
111 |
112 | // action servers
113 | actionlib::SimpleActionServer takeoff_as;
114 | actionlib::SimpleActionServer land_here_as;
115 |
116 | // services, should all be a descriptive name with "Service" at the end
117 | // Their corresponding call back should have the same name, replacing "Service" with SCB
118 | // thus if you have a service named doSomethingService, it's call back should be doSomethingSCB
119 | ros::ServiceServer getLocalPositionService;
120 | ros::ServiceServer getLastStateService;
121 |
122 | SpiriGo();
123 | ~SpiriGo();
124 |
125 | // getter functions
126 | bool isArmed();
127 | bool isControllable();
128 | std::string getMode();
129 | geometry_msgs::Point getLocalPosition();
130 | SpiriAttitude getAttitude();
131 | bool isValid();
132 |
133 | bool setGuided();
134 |
135 | bool setStreamRate(unsigned char streamID, int rate);
136 |
137 |
138 |
139 | // Yaw commander with MAVLink; angles are in degrees
140 | // Eigen::Vector3d getAttitude();
141 |
142 |
143 | // basic Spiri control functions
144 | void armAndTakeOff(const spiri_go::TakeoffGoalConstPtr& goal);
145 | void landHere(const spiri_go::LandHereGoalConstPtr& goal);
146 | void conditionYaw(float targetYaw, float targetYawRate);
147 | void setENUVelocity(/*double eastwardVelocity, double northwardVelocity*/);
148 | void setHorizontalVelocity(double u, double v);
149 |
150 | // main pose-estimation loop
151 | void Loop();
152 |
153 | };
154 | #endif /* __SPIRIGO_H */
155 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/include/spiri_go.h~:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifndef __SPIRIGO_H
4 | #define __SPIRIGO_H
5 |
6 |
7 | #include "ros/ros.h"
8 | #include "geometry_msgs/Twist.h"
9 | #include "geometry_msgs/Vector3Stamped.h"
10 | #include "geometry_msgs/Pose.h"
11 | #include "sensor_msgs/Image.h"
12 | #include "sensor_msgs/Imu.h"
13 | #include
14 | #include "tf/tfMessage.h"
15 | #include "tf/transform_listener.h"
16 | #include "tf/transform_broadcaster.h"
17 | #include "tf2_ros/buffer.h"
18 | #include "tf2_ros/transform_listener.h"
19 | #include
20 | #include
21 | #include "std_msgs/Empty.h"
22 | #include "std_srvs/Empty.h"
23 | #include "mavros_msgs/State.h"
24 | #include "mavros_msgs/Mavlink.h"
25 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 |
33 | using namespace std;
34 |
35 | class SpiriGo
36 | {
37 | private:
38 | // subscribers
39 | // the local position of the copter
40 | ros::Subscriber local;
41 | // the state of the copter
42 | ros::Subscriber state;
43 | // the gps position, I add
44 | ros::Subscriber gps;
45 | // the height, I add
46 | ros::Subscriber alt;
47 | // the connect state, I add
48 | ros::Subscriber connect_state;
49 |
50 | // publishers
51 | // sets the velocity
52 | ros::Publisher vel;
53 | ros::Publisher rc_out;
54 |
55 | // service clients
56 | // Arm the copter
57 | ros::ServiceClient arm;
58 | // a service to set the mode
59 | ros::ServiceClient set_mode;
60 | // a service to set the stream rate
61 | ros::ServiceClient set_stream_rate;
62 | // tell the copter to take off
63 | ros::ServiceClient takeoff;
64 | // MAVLink service for other needs
65 | ros::ServiceClient mavlink_cmd_srv;
66 |
67 | ros::NodeHandle nh;
68 |
69 | // save last imu received for forwarding...
70 | sensor_msgs::Imu lastLocalReceived;
71 |
72 | // ROS message callbacks
73 | void localSubCb(const geometry_msgs::PoseStamped localPtr);
74 | void stateSubCb(const mavros_msgs::State);
75 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg); //I add
76 | void altSubCb(const sensor_msgs::NavSatFixConstPtr& msg);
77 | void connectSubCb(const mavros_msgs::Mavlink fromPtr);
78 |
79 | // state variables
80 | mavros_msgs::State last_state;
81 | bool taking_off; // has taken off
82 | bool flying; // has finished taking off
83 |
84 | // location last returned by mavros
85 | geometry_msgs::Pose last_location;
86 | // guess of nearest location, itegrated using velocity
87 | geometry_msgs::Pose location;
88 | // target velocity
89 | geometry_msgs::Twist velocity;
90 | // gps returned by mavros, I add
91 | sensor_msgs::NavSatFix last_gps;
92 | // height
93 | sensor_msgs::NavSatFix last_alt;
94 | //
95 | mavros_msgs::Mavlink last_connect_state;
96 |
97 | // internal control methods
98 | geometry_msgs::Quaternion getOrientation();
99 | bool setMode(const char* targetMode);
100 | bool setArmed();
101 | //bool setGuided();
102 | void takeOff(float targetAlt);
103 |
104 | // service callbacks
105 | bool getLocalPositionSCB(spiri_go::LocalPosition::Request &req, spiri_go::LocalPosition::Response &rsp);
106 | bool getLastStateSCB(spiri_go::LastState::Request &req, spiri_go::LastState::Response &rsp);
107 |
108 | void updateLocation(ros::Duration dt);
109 |
110 | public:
111 |
112 | // action servers
113 | actionlib::SimpleActionServer takeoff_as;
114 | actionlib::SimpleActionServer land_here_as;
115 |
116 | // services, should all be a descriptive name with "Service" at the end
117 | // Their corresponding call back should have the same name, replacing "Service" with SCB
118 | // thus if you have a service named doSomethingService, it's call back should be doSomethingSCB
119 | ros::ServiceServer getLocalPositionService;
120 | ros::ServiceServer getLastStateService;
121 |
122 | SpiriGo();
123 | ~SpiriGo();
124 |
125 | // getter functions
126 | bool isArmed();
127 | bool isControllable();
128 | std::string getMode();
129 | geometry_msgs::Point getLocalPosition();
130 | SpiriAttitude getAttitude();
131 | bool isValid();
132 |
133 | bool setGuided();
134 |
135 | bool setStreamRate(unsigned char streamID, int rate);
136 |
137 |
138 |
139 | // Yaw commander with MAVLink; angles are in degrees
140 | // Eigen::Vector3d getAttitude();
141 |
142 |
143 | // basic Spiri control functions
144 | void armAndTakeOff(const spiri_go::TakeoffGoalConstPtr& goal);
145 | void landHere(const spiri_go::LandHereGoalConstPtr& goal);
146 | void conditionYaw(float targetYaw, float targetYawRate);
147 | void setENUVelocity(/*double eastwardVelocity, double northwardVelocity*/);
148 | void setHorizontalVelocity(double u, double v);
149 |
150 | // main pose-estimation loop
151 | void Loop();
152 |
153 | };
154 | #endif /* __SPIRIGO_H */
155 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/initialize/apm_sim:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 | ###############################################################################
3 | ## First thing to do in any system, gotta install git to get anything done
4 | ###############################################################################
5 |
6 | sudo apt-get update
7 | sudo apt-get install -y git screen
8 |
9 | ###############################################################################
10 | ## Ardupilot and simulator installation
11 | ## Taken from http://dev.ardupilot.com/wiki/setting-up-sitl-on-linux/
12 | ###############################################################################
13 |
14 | # Download a copy of our own fork of ardupilot
15 | git clone https://github.com/Pleiades-Spiri/ardupilot.git ~/ardupilot
16 |
17 | # Install some required packages for the APM SITL simulator
18 | sudo apt-get -y install python-matplotlib python-serial python-wxgtk2.8 python-lxml
19 | sudo apt-get -y install python-scipy python-opencv ccache gawk git python-pip python-pexpect
20 | sudo pip install pymavlink MAVProxy
21 |
22 | # Gotta source the simulator paths
23 | echo "
24 | export PATH=\$PATH:\$HOME/ardupilot/Tools/autotest
25 | export PATH=/usr/lib/ccache:\$PATH
26 | " >> ~/.bashrc
27 | source ~/.bashrc
28 |
29 | ###############################################################################
30 | ## ROS Installation
31 | ## Taken from https://pixhawk.org/dev/ros/installation
32 | ###############################################################################
33 |
34 | # Add the ROS repository for Trusty(14.04):
35 | sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu trusty main" > /etc/apt/sources.list.d/ros-latest.list'
36 |
37 | # Get the official ROS key
38 | wget https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -O - | sudo apt-key add -
39 |
40 | # And install the packages we recommend for having a development environment good for MAVs.
41 | # You can install any other project-specific dependencies via rosdep or manually.
42 | sudo apt-get update
43 | sudo apt-get install -y ros-indigo-ros-base \
44 | ros-indigo-usb-cam \
45 | ros-indigo-mavlink \
46 | ros-indigo-mavros \
47 | ros-indigo-cv-bridge \
48 | ros-indigo-image-proc \
49 | ros-indigo-tf
50 |
51 | # Setup rosdep which makes life a lot easier by auto-installing dependencies wherever possible.
52 | sudo apt-get install -y python-rosdep
53 | sudo rosdep init
54 | rosdep update
55 |
56 | # Gotta source the ROS binary path
57 | echo "source /opt/ros/indigo/setup.bash" >> ~/.bashrc
58 | source /opt/ros/indigo/setup.bash
59 |
60 | ###############################################################################
61 | ## Set up minimal workspace for spiri_go
62 | ## On desktop we want just ONE package in the workspace to minimize compilation issues
63 | ###############################################################################
64 | WORKSPACE=~/spiri_ws
65 |
66 | # Make workspace directory then "compile" to initialize the ROS workspace
67 | mkdir -p $WORKSPACE/src
68 | cd $WORKSPACE/src
69 | catkin_init_workspace
70 | cd $WORKSPACE
71 | catkin_make
72 |
73 | # Download spiri_go package into source
74 | cd $WORKSPACE/src
75 | git clone https://github.com/Pleiades-Spiri/spiri_go.git
76 |
77 | # Now compile the one package we have
78 | cd $WORKSPACE
79 | catkin_make
80 |
81 | # Gotta source the package paths for roslaunch/rosrun to find them
82 | sh -c "echo 'source $WORKSPACE/devel/setup.bash' >> ~/.bashrc"
83 | source $WORKSPACE/devel/setup.bash
84 |
85 | ###############################################################################
86 | ## Commands for running the simulator
87 | ###############################################################################
88 |
89 | # Run this to open the simulator (it'll take a while to compile the first time):
90 | # sim_vehicle.sh --map --console --aircraft test
91 |
92 | # Once you're in run this in the mavproxy console
93 | # to get rid of the 'RC not calibrated' problem:
94 | # param load ../Tools/autotest/copter_params.parm
95 |
96 | # In a different terminal run this to start spiri_go and mavros:
97 | # roslaunch spiri_go sitl.launch
98 |
99 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/apm_pluginlists.yaml:
--------------------------------------------------------------------------------
1 | plugin_blacklist:
2 | # common
3 | - actuator_control
4 | - ftp
5 | - safety_area
6 | - setpoint_attitude
7 | # extras
8 | - image_pub
9 | - 'mocap_*'
10 | - px4flow
11 | - 'vision_*'
12 | - distance_sensor
13 | - vibration
14 |
15 | plugin_whitelist: []
16 | #- 'sys_*'
17 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/collision_avoidance.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/collision_avoidance.launch~:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/jetson.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/kbteleop.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/leader-sitl.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/leader-sitl.launch~:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/leader.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/leader.launch~:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/sitl.launch:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/spiri_go.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/takeoff_and_land.launch:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/launch/takeoff_and_land.launch~:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | spiri_go
4 | 0.1.0
5 | The spiri_go package
6 |
7 |
8 |
9 |
10 | Skyler Olson
11 | John Lian
12 |
13 |
14 |
15 |
16 |
17 | TODO
18 |
19 |
20 |
21 |
22 |
23 | https://github.com/Pleiades-Spiri/spiri_go
24 |
25 |
26 |
27 |
28 |
29 | Skyler Olson
30 | John Lian
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | catkin
44 | roscpp
45 | rospy
46 | boost
47 | std_msgs
48 | actionlib_msgs
49 | roscpp
50 | boost
51 | rospy
52 | std_msgs
53 | actionlib_msgs
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/scripts/mavkbteleop.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # vim:set ts=4 sw=4 et:
3 | #
4 | # Copyright 2014 Vladimir Ermakov.
5 | #
6 | # This file is part of the mavros package and subject to the license terms
7 | # in the top-level LICENSE file of the mavros repository.
8 | # https://github.com/mavlink/mavros/tree/master/LICENSE.md
9 |
10 | import rospy
11 | from mavros.srv import SetMode
12 |
13 | def set_mode(mode):
14 | try:
15 | setmode_cl = rospy.ServiceProxy("/mavros/set_mode", SetMode)
16 |
17 | ret = setmode_cl(base_mode=0, custom_mode=mode)
18 | except rospy.ServiceException as ex:
19 | fault(ex)
20 |
21 | if not ret.success:
22 | rospy.loginfo("SET MODE Request failed.")
23 | else:
24 | rospy.loginfo("SET MODE Request success")
25 |
26 |
27 | def rc_override_control():
28 |
29 | rospy.init_node("mavteleop")
30 | rospy.loginfo("MAV-Teleop: RC Override control type.")
31 |
32 | while(1):
33 | set_mode("GUIDED")
34 |
35 |
36 |
37 | def main():
38 | rc_override_control()
39 |
40 |
41 | if __name__ == '__main__':
42 | main()
43 |
44 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | from distutils.core import setup
4 |
5 | setup(name='SpiriGo',
6 | version='1.0',
7 | description='An API to control Spiri',
8 | author='Skyler Olson',
9 | author_email='skyler.olson@pleiades.ca',
10 | url='',
11 | packages=["spiripy"],
12 | )
13 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/spiripy/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/PenguinCheng/multiDrone-ROS/73df4bb83e1091565331f9467f779e4a3ad9bd95/multiDrone-ROS/spiri_go/spiripy/__init__.py
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/spiripy/api.py:
--------------------------------------------------------------------------------
1 | import rospy
2 | import roslib
3 | import time
4 | roslib.load_manifest('spiri_go')
5 | import actionlib
6 | # Load specific service and action server definitions
7 | from spiri_go.msg import * # imports actions too
8 | from spiri_go.srv import *
9 | # Import the exceptions defined here
10 | from spiripy import spiri_except
11 |
12 |
13 | class SpiriGo(object):
14 | """A top level python API to command Spiri to perform autonomous actions.
15 |
16 | The idea for this class is to supply methods for users to perform autonomous
17 | actions via simple python scripts.
18 |
19 | It interfaces with the SpiriGo ROS node via services and actions, not publishing
20 | and subscribing. This guarantees the promptness of information.
21 |
22 | Attributes:
23 |
24 | """
25 |
26 | def __init__(self):
27 | rospy.init_node('spiri_go_api', anonymous=True)
28 |
29 | def wait_for_ros(self, timeout=-1):
30 | """ Waits for the ros interfaces to come online
31 |
32 | Args:
33 | timeout (number): How long to wait until this should be considered
34 | a failure. If timeout is less than 0, will never stop trying
35 |
36 | Raises:
37 | SpiriGoConnectionError: If the connection times out.
38 | """
39 | try:
40 | rospy.wait_for_service('spiri_state', timeout)
41 | except:
42 | raise spiri_except.SpiriGoConnectionError("Timed out connecting to ROS")
43 |
44 | def wait_for_fcu(self, timeout=-1):
45 | """Waits for mavros to connect to the flight controller.
46 |
47 | Args:
48 | timeout (number): How long to wait until this should be considered
49 | a failure. If timeout is less than 0, will never stop trying
50 |
51 | Raises:
52 | SpiriGoConnectionError: If the connection times out.
53 | """
54 | start_time = time.time()
55 | state = self.get_state()
56 |
57 | while not state.connected:
58 | time.sleep(0.5)
59 | state = self.get_state()
60 | duration = time.time() - start_time
61 | # print "waiting for fuc: " + str(duration) + "/" + str(timeout)
62 | # check if this should time out
63 | if timeout > 0 and duration > timeout:
64 | raise spiri_except.SpiriGoConnectionError("Timed out connecting to the FCU")
65 |
66 | def get_state(self):
67 | """mavros_msgs/State: returns state of the copter."""
68 | state_service_client = get_service_client('spiri_state', LastState)
69 | return state_service_client()
70 |
71 | def get_local_position(self):
72 | """geometry_msgs/Point Message: returns the 3D position vector in meters."""
73 | pos_service_client = get_service_client('spiri_local_position', LocalPosition)
74 | return pos_service_client()
75 |
76 | def takeoff(self, height=4):
77 | """Commands the copter to takeoff autonomously.
78 |
79 | Note:
80 | The copter will go to GUIDED mode, arm motors, and takeoff all in once shot.
81 | This is a ROS action and will be blocking until it completes.
82 |
83 | Args:
84 | height (int): The takeoff height, default is 4 meters.
85 |
86 | Returns:
87 | bool: True if successful, False otherwise.
88 | """
89 |
90 | # Connection to the server
91 | client = get_action_client('spiri_take_off', TakeoffAction)
92 |
93 | # Make a goal object for the copter to complete
94 | goal = TakeoffGoal()
95 | goal.height = height
96 | print "Sending takoff command"
97 | client.send_goal(goal)
98 | client.wait_for_result()
99 |
100 | return True
101 |
102 | def land(self):
103 | """Command the copter to land in place.
104 |
105 | Note:
106 | The copter will go to LAND mode.
107 | The method will block until it completes.
108 |
109 | Args:
110 |
111 | Returns:
112 | bool: True if successful, False otherwise.
113 | """
114 | client = get_action_client('spiri_land_here', LandHereAction)
115 | goal = LandHereGoal()
116 | goal.height = 0
117 | print "Sending land here command"
118 | client.send_goal(goal)
119 | client.wait_for_result()
120 |
121 | return True
122 |
123 |
124 | def get_action_client(name, action):
125 | """Gets the client and ensures that the server is running
126 |
127 | Args:
128 | name: a string, the server's name (eg. 'spiri_take_off').
129 | action: an object, the type of server (eg. TakeoffAction).
130 |
131 | Returns:
132 | The action client object.
133 | """
134 | client = actionlib.SimpleActionClient(name, action)
135 | server_present = client.wait_for_server(rospy.Duration(1))
136 | if server_present:
137 | return client
138 | else:
139 | raise spiri_except.SpiriGoConnectionError("Could not create action client " + name)
140 |
141 |
142 | def get_service_client(name, service):
143 | """Ensure that the service exists.
144 |
145 | Args:
146 | service: an object, the name of the service.
147 |
148 | Returns:
149 | The service client object.
150 | """
151 | try:
152 | rospy.wait_for_service(name, 1)
153 | except:
154 | raise spiri_except.SpiriGoConnectionError("Could not create service client " + name)
155 | return rospy.ServiceProxy(name, service)
156 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/spiripy/spiri_except.py:
--------------------------------------------------------------------------------
1 | class SpiriGoConnectionError(Exception):
2 | def __init__(self, description = "unknown"):
3 | self.description = description
4 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/arm_and_takeoff.cpp~:
--------------------------------------------------------------------------------
1 | /**
2 | * simpely takeoff and land
3 | */
4 |
5 | #include "ros/ros.h"
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | int main(int argc, char **argv) {
12 | ros::init(argc, argv, "spiri_go_client");
13 |
14 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name, second param: true means a new thread
15 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
16 |
17 | ROS_INFO("Waiting for action server(takeOff) to start.");
18 |
19 | ac.waitForServer();
20 |
21 | ROS_INFO("Action server started--Taking off!");
22 |
23 | spiri_go::TakeoffGoal goal;
24 |
25 | //set the target height to take off!
26 | goal.height = 10;
27 | ac.sendGoal(goal);
28 |
29 | //wait for action(takeOff) to return
30 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
31 |
32 | if(is_takeOff_finished ) {
33 | ROS_INFO("reached target height!");
34 |
35 | //do something
36 | ros::Duration(10).sleep();
37 | }
38 | else {
39 | ROS_INFO("should set mode Land!");
40 | }
41 |
42 | //land
43 | ROS_INFO("Waiting for action server(land) to start.");
44 | ac1.waitForServer();
45 | ROS_INFO("Start to land!.");
46 |
47 | spiri_go::LandHereGoal goal_1;
48 | goal_1.height = 0;
49 | ac1.sendGoal(goal_1);
50 |
51 | //wait for action(land) to return
52 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
53 | if(is_land_finished ) {
54 | ROS_INFO("Land success!");
55 | }
56 |
57 | return 0;
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/collision_avoidance.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: collision_avoidance.cpp
6 | *
7 | * Purpose: collision avoidance control using releative position.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2016/3/30
11 | ******************************************************************************/
12 |
13 | #include "ros/ros.h"
14 | #include
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 |
31 | #define R 6371000 //meter
32 | #define PI 3.1415926535898
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
40 | selfGlobalPos = *msg;
41 | }
42 |
43 | /*******************************************************************************
44 | * Callback function on the gps of the neighbour copter
45 | *
46 | * @param gpsPositionConstPtr& the gps callback pointer
47 | ******************************************************************************/
48 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
49 | {
50 | neigGlobalPos = *msg;
51 | }
52 |
53 | /*******************************************************************************
54 | * Main function
55 | *
56 | * @param
57 | ******************************************************************************/
58 | int main(int argc, char **argv) {
59 | ros::init(argc, argv, "spiri_go_client");
60 | ros::NodeHandle nh;
61 |
62 | ros::Rate loop_rate(10.0);
63 |
64 | //velocity to publish
65 | geometry_msgs::TwistStamped vel;
66 | vel.twist.linear.x = 0.0;
67 | vel.twist.linear.y = 0.0;
68 | vel.header.stamp = ros::Time::now();
69 |
70 | //variables definition
71 | float x_0 = 0.0;
72 | float y_0 = 0.0;
73 | float x_1 = 0.0;
74 | float y_1 = 0.0;
75 | float d12 = 10; //meter,two leaders mantain the distance
76 | float r = 1.0; // the region that collision avoidance algorithm will take effect
77 | float r1 = 5.0; // the region that collision avoidance algorithm will take effect
78 | float vx0 = 0.0;
79 | float vy0 = 0.0;
80 | float currentDisPow = 0.0;
81 | float x_offset = 0.0;
82 | float y_offset = 0.0;
83 |
84 | ofstream ofile;
85 | float begin_time = ros::Time::now().toSec();
86 | ROS_INFO("begin_time,%6.4f",begin_time);
87 |
88 | //takeoff action object
89 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
90 | //land action object
91 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
92 |
93 | // Subscriber to the Copter gps
94 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
95 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
96 |
97 | // Subscriber to the neighbour gps
98 | string neigGps_ = nh.resolveName("neighbour_position");
99 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
100 |
101 | //Publisher to the gps(toString)
102 | string gps_string_pub_ = nh.resolveName("serial_data_send");
103 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
104 |
105 | //Publisher to the velocity of the copter
106 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
107 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
108 |
109 | ROS_INFO("Waiting for action server(takeOff) to start.");
110 |
111 | ac.waitForServer();
112 |
113 | ROS_INFO("Action server started--Taking off!");
114 |
115 | spiri_go::TakeoffGoal goal;
116 |
117 | //set the target height to take off!
118 | goal.height = 3;
119 |
120 | ac.sendGoal(goal);
121 |
122 | //wait for action(takeOff) to return
123 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
124 | ros::Duration(2).sleep();
125 | if(is_takeOff_finished ) {
126 | ROS_INFO("reached target height!");
127 | ofile.open("./log/data.log", ios::trunc);
128 |
129 | while(nh.ok()) {
130 | //1.publish self gps(toString)
131 | std_msgs::String gps_string;
132 | std::stringstream ss;
133 | ss << "o"<= 1) {
183 | vel.twist.linear.x = 1;
184 | }else if(vel.twist.linear.x <= -1) {
185 | vel.twist.linear.x = -1;
186 | }
187 | if(vel.twist.linear.y >= 1) {
188 | vel.twist.linear.y = 1;
189 | }else if(vel.twist.linear.y <= -1) {
190 | vel.twist.linear.y = -1;
191 | }
192 |
193 |
194 | vel.header.stamp = ros::Time::now();
195 |
196 | //4.publish velocity to mavros
197 | vel_pub.publish(vel);
198 | //ROS_INFO("velocity_x:%f", vel.twist.linear.x);
199 | //ROS_INFO("velocity_y:%f", vel.twist.linear.y);
200 | ofile << vel.twist.linear.x << " " << vel.twist.linear.y << x_0 << y_0 << x_1 << y_1 << std::endl;
201 |
202 | // if fly for 4 minutes
203 | if( (ros::Time::now().toSec() - begin_time) > 4*60 ) {
204 | //land
205 | ROS_INFO("Waiting for action server(land) to start.");
206 | ac1.waitForServer();
207 | ROS_INFO("Start to land!.");
208 |
209 | spiri_go::LandHereGoal goal_1;
210 | goal_1.height = 0;
211 | ac1.sendGoal(goal_1);
212 |
213 | //wait for action(land) to return
214 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
215 | if(is_land_finished ) {
216 | ROS_INFO("Land success!");
217 | }
218 | }
219 |
220 | ros::spinOnce();
221 | loop_rate.sleep();
222 | }
223 | }
224 | else {
225 | ROS_INFO("should set mode Land!");
226 | }
227 |
228 | return 0;
229 |
230 | }
231 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/collision_avoidance.cpp~:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: collision_avoidance.cpp
6 | *
7 | * Purpose: collision avoidance control using releative position.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2016/3/30
11 | ******************************************************************************/
12 |
13 | #include "ros/ros.h"
14 | #include
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 |
31 | #define R 6371000 //meter
32 | #define PI 3.1415926535898
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
40 | selfGlobalPos = *msg;
41 | }
42 |
43 | /*******************************************************************************
44 | * Callback function on the gps of the neighbour copter
45 | *
46 | * @param gpsPositionConstPtr& the gps callback pointer
47 | ******************************************************************************/
48 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
49 | {
50 | neigGlobalPos = *msg;
51 | }
52 |
53 | /*******************************************************************************
54 | * Main function
55 | *
56 | * @param
57 | ******************************************************************************/
58 | int main(int argc, char **argv) {
59 | ros::init(argc, argv, "spiri_go_client");
60 | ros::NodeHandle nh;
61 |
62 | ros::Rate loop_rate(10.0);
63 |
64 | //velocity to publish
65 | geometry_msgs::TwistStamped vel;
66 | vel.twist.linear.x = 0.0;
67 | vel.twist.linear.y = 0.0;
68 | vel.header.stamp = ros::Time::now();
69 |
70 | //variables definition
71 | float x_0 = 0.0;
72 | float y_0 = 0.0;
73 | float x_1 = 0.0;
74 | float y_1 = 0.0;
75 | float d12 = 10; //meter,two leaders mantain the distance
76 | float r = 1.0; // the region that collision avoidance algorithm will take effect
77 | float r1 = 5.0; // the region that collision avoidance algorithm will take effect
78 | float vx0 = 0.0;
79 | float vy0 = 0.0;
80 | float currentDisPow = 0.0;
81 | float x_offset = 0.0;
82 | float y_offset = 0.0;
83 |
84 | ofstream ofile;
85 | float begin_time = ros::Time::now().toSec();
86 | ROS_INFO("begin_time,%6.4f",begin_time);
87 |
88 | //takeoff action object
89 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
90 | //land action object
91 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
92 |
93 | // Subscriber to the Copter gps
94 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
95 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
96 |
97 | // Subscriber to the neighbour gps
98 | string neigGps_ = nh.resolveName("neighbour_position");
99 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
100 |
101 | //Publisher to the gps(toString)
102 | string gps_string_pub_ = nh.resolveName("serial_data_send");
103 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
104 |
105 | //Publisher to the velocity of the copter
106 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
107 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
108 |
109 | ROS_INFO("Waiting for action server(takeOff) to start.");
110 |
111 | ac.waitForServer();
112 |
113 | ROS_INFO("Action server started--Taking off!");
114 |
115 | spiri_go::TakeoffGoal goal;
116 |
117 | //set the target height to take off!
118 | goal.height = 3;
119 |
120 | ac.sendGoal(goal);
121 |
122 | //wait for action(takeOff) to return
123 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
124 | ros::Duration(2).sleep();
125 | if(is_takeOff_finished ) {
126 | ROS_INFO("reached target height!");
127 | ofile.open("./log/data.log", ios::trunc);
128 |
129 | while(nh.ok()) {
130 | //1.publish self gps(toString)
131 | std_msgs::String gps_string;
132 | std::stringstream ss;
133 | ss << "o"<= 1) {
183 | vel.twist.linear.x = 1;
184 | }else if(vel.twist.linear.x <= -1) {
185 | vel.twist.linear.x = -1;
186 | }
187 | if(vel.twist.linear.y >= 1) {
188 | vel.twist.linear.y = 1;
189 | }else if(vel.twist.linear.y <= -1) {
190 | vel.twist.linear.y = -1;
191 | }
192 |
193 |
194 | vel.header.stamp = ros::Time::now();
195 |
196 | //4.publish velocity to mavros
197 | vel_pub.publish(vel);
198 | //ROS_INFO("velocity_x:%f", vel.twist.linear.x);
199 | //ROS_INFO("velocity_y:%f", vel.twist.linear.y);
200 | ofile << vel.twist.linear.x << " " << vel.twist.linear.y << x_0 << y_0 << x_1 << y_1 << std::endl;
201 |
202 | // if fly for 4 minutes
203 | if( (ros::Time::now().toSec() - begin_time) > 4*60 ) {
204 | //land
205 | ROS_INFO("Waiting for action server(land) to start.");
206 | ac1.waitForServer();
207 | ROS_INFO("Start to land!.");
208 |
209 | spiri_go::LandHereGoal goal_1;
210 | goal_1.height = 0;
211 | ac1.sendGoal(goal_1);
212 |
213 | //wait for action(land) to return
214 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
215 | if(is_land_finished ) {
216 | ROS_INFO("Land success!");
217 | }
218 | }
219 |
220 | ros::spinOnce();
221 | loop_rate.sleep();
222 | }
223 | }
224 | else {
225 | ROS_INFO("should set mode Land!");
226 | }
227 |
228 | return 0;
229 |
230 | }
231 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/follower.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: leader.cpp
6 | *
7 | * Purpose: Formation control of leaders with collision avoidance using releative position.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2016/4/06
11 | ******************************************************************************/
12 |
13 | #include "ros/ros.h"
14 | #include
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 | px4ros::gpsPosition neigGlobalPos_2;
31 |
32 | #define R 6371000 //meter
33 | #define PI 3.1415926535898
34 | #define T 0.1
35 |
36 | /*******************************************************************************
37 | * Callback function on the gps of the copter
38 | *
39 | * @param gpsPositionConstPtr& the gps callback pointer
40 | ******************************************************************************/
41 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
42 | selfGlobalPos = *msg;
43 | }
44 |
45 | /*******************************************************************************
46 | * Callback function on the gps of the neighbour copter
47 | *
48 | * @param gpsPositionConstPtr& the gps callback pointer
49 | ******************************************************************************/
50 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
51 | {
52 | neigGlobalPos = *msg;
53 | }
54 |
55 | /*******************************************************************************
56 | * Callback function on the gps of the neighbour copter
57 | *
58 | * @param gpsPositionConstPtr& the gps callback pointer
59 | ******************************************************************************/
60 | void neigGpsSubCb2(const px4ros::gpsPositionConstPtr& msg)
61 | {
62 | neigGlobalPos_2 = *msg;
63 | }
64 |
65 | /*******************************************************************************
66 | * Main function
67 | *
68 | * @param
69 | ******************************************************************************/
70 | int main(int argc, char **argv) {
71 | ros::init(argc, argv, "spiri_go_client");
72 | ros::NodeHandle nh;
73 |
74 | ros::Rate loop_rate(10.0);
75 |
76 | //velocity to publish
77 | geometry_msgs::TwistStamped vel;
78 | vel.twist.linear.x = 0.0;
79 | vel.twist.linear.y = 0.0;
80 | vel.header.stamp = ros::Time::now();
81 |
82 | //variables definition
83 | float x_0 = 0.0;
84 | float y_0 = 0.0;
85 | float x_1 = 0.0;
86 | float y_1 = 0.0;
87 | float x_2 = 0.0;
88 | float y_2 = 0.0;
89 | float d01 = 10; //meter
90 | float d02 = 10;
91 | float r = 1.0; // the region that collision avoidance algorithm will take effect
92 | float r1 = 5.0; // the region that collision avoidance algorithm will take effect
93 | float vx0 = 0.0;
94 | float vy0 = 0.0;
95 | float distancePow_01 = 0.0;
96 | float distancePow_02 = 0.0;
97 | float diff_theta_x = 0.0;
98 | float diff_theta_y = 0.0;
99 | float theta_x = 0.0;
100 | float theta_y = 0.0;
101 | float last_theta_x = 0.0;
102 | float last_theta_y = 0.0;
103 |
104 | float x_offset = 0.0;
105 | float y_offset = 0.0;
106 | float x_offset_ = 0.0;
107 | float y_offset_ = 0.0;
108 |
109 | ofstream ofile;
110 | float begin_time = ros::Time::now().toSec();
111 | ROS_INFO("begin_time,%6.4f",begin_time);
112 |
113 | //takeoff action object
114 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
115 | //land action object
116 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
117 |
118 | // Subscriber to the Copter gps
119 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
120 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
121 |
122 | // Subscriber to the neighbour gps
123 | string neigGps_ = nh.resolveName("neighbour_position");
124 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
125 |
126 | // Subscriber to the neighbour gps
127 | string neigGps2_ = nh.resolveName("neighbour_position_2");
128 | ros::Subscriber neigGps2 = nh.subscribe(neigGps2_, 5, neigGpsSubCb2);
129 |
130 | //Publisher to the gps(toString)
131 | string gps_string_pub_ = nh.resolveName("serial_data_send");
132 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
133 |
134 | //Publisher to the velocity of the copter
135 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
136 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
137 |
138 | ROS_INFO("Waiting for action server(takeOff) to start.");
139 |
140 | ac.waitForServer();
141 |
142 | ROS_INFO("Action server started--Taking off!");
143 |
144 | spiri_go::TakeoffGoal goal;
145 |
146 | //set the target height to take off!
147 | goal.height = 3;
148 |
149 | ac.sendGoal(goal);
150 |
151 | //wait for action(takeOff) to return
152 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
153 | ros::Duration(5).sleep();
154 | if(is_takeOff_finished ) {
155 | ROS_INFO("reached target height!");
156 | ofile.open("./log/data.log", ios::trunc);
157 |
158 | while(nh.ok()) {
159 | //1.publish self gps(toString)
160 | std_msgs::String gps_string;
161 | std::stringstream ss;
162 | ss << "x3o"<= 1) {
239 | vel.twist.linear.x = 1;
240 | }else if(vel.twist.linear.x <= -1) {
241 | vel.twist.linear.x = -1;
242 | }
243 | if(vel.twist.linear.y >= 1) {
244 | vel.twist.linear.y = 1;
245 | }else if(vel.twist.linear.y <= -1) {
246 | vel.twist.linear.y = -1;
247 | }
248 |
249 |
250 | vel.header.stamp = ros::Time::now();
251 |
252 | //4.publish velocity to mavros
253 | vel_pub.publish(vel);
254 | //ROS_INFO("velocity_x:%f", vel.twist.linear.x);
255 | //ROS_INFO("velocity_y:%f", vel.twist.linear.y);
256 | ofile << vel.twist.linear.x << " " << vel.twist.linear.y << x_0 << y_0 << x_1 << y_1 << std::endl;
257 |
258 | // if fly for 4 minutes
259 | if( (ros::Time::now().toSec() - begin_time) > 4*60 ) {
260 | //land
261 | ROS_INFO("Waiting for action server(land) to start.");
262 | ac1.waitForServer();
263 | ROS_INFO("Start to land!.");
264 |
265 | spiri_go::LandHereGoal goal_1;
266 | goal_1.height = 0;
267 | ac1.sendGoal(goal_1);
268 |
269 | //wait for action(land) to return
270 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
271 | if(is_land_finished ) {
272 | ROS_INFO("Land success!");
273 | }
274 | }
275 |
276 | ros::spinOnce();
277 | loop_rate.sleep();
278 | }
279 | }
280 | else {
281 | ROS_INFO("should set mode Land!");
282 | }
283 |
284 | return 0;
285 |
286 | }
287 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/follower.cpp~:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: leader.cpp
6 | *
7 | * Purpose: Formation control of leaders with collision avoidance using releative position.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2016/4/06
11 | ******************************************************************************/
12 |
13 | #include "ros/ros.h"
14 | #include
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 | px4ros::gpsPosition neigGlobalPos_2;
31 |
32 | #define R 6371000 //meter
33 | #define PI 3.1415926535898
34 | #define T 0.1
35 |
36 | /*******************************************************************************
37 | * Callback function on the gps of the copter
38 | *
39 | * @param gpsPositionConstPtr& the gps callback pointer
40 | ******************************************************************************/
41 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
42 | selfGlobalPos = *msg;
43 | }
44 |
45 | /*******************************************************************************
46 | * Callback function on the gps of the neighbour copter
47 | *
48 | * @param gpsPositionConstPtr& the gps callback pointer
49 | ******************************************************************************/
50 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
51 | {
52 | neigGlobalPos = *msg;
53 | }
54 |
55 | /*******************************************************************************
56 | * Callback function on the gps of the neighbour copter
57 | *
58 | * @param gpsPositionConstPtr& the gps callback pointer
59 | ******************************************************************************/
60 | void neigGpsSubCb2(const px4ros::gpsPositionConstPtr& msg)
61 | {
62 | neigGlobalPos_2 = *msg;
63 | }
64 |
65 | /*******************************************************************************
66 | * Main function
67 | *
68 | * @param
69 | ******************************************************************************/
70 | int main(int argc, char **argv) {
71 | ros::init(argc, argv, "spiri_go_client");
72 | ros::NodeHandle nh;
73 |
74 | ros::Rate loop_rate(10.0);
75 |
76 | //velocity to publish
77 | geometry_msgs::TwistStamped vel;
78 | vel.twist.linear.x = 0.0;
79 | vel.twist.linear.y = 0.0;
80 | vel.header.stamp = ros::Time::now();
81 |
82 | //variables definition
83 | float x_0 = 0.0;
84 | float y_0 = 0.0;
85 | float x_1 = 0.0;
86 | float y_1 = 0.0;
87 | float x_2 = 0.0;
88 | float y_2 = 0.0;
89 | float d01 = 10; //meter
90 | float d02 = 10;
91 | float r = 1.0; // the region that collision avoidance algorithm will take effect
92 | float r1 = 5.0; // the region that collision avoidance algorithm will take effect
93 | float vx0 = 0.0;
94 | float vy0 = 0.0;
95 | float distancePow_01 = 0.0;
96 | float distancePow_02 = 0.0;
97 | float diff_theta_x = 0.0;
98 | float diff_theta_y = 0.0;
99 | float theta_x = 0.0;
100 | float theta_y = 0.0;
101 | float last_theta_x = 0.0;
102 | float last_theta_y = 0.0;
103 |
104 | float x_offset = 0.0;
105 | float y_offset = 0.0;
106 |
107 | ofstream ofile;
108 | float begin_time = ros::Time::now().toSec();
109 | ROS_INFO("begin_time,%6.4f",begin_time);
110 |
111 | //takeoff action object
112 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
113 | //land action object
114 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
115 |
116 | // Subscriber to the Copter gps
117 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
118 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
119 |
120 | // Subscriber to the neighbour gps
121 | string neigGps_ = nh.resolveName("neighbour_position");
122 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
123 |
124 | // Subscriber to the neighbour gps
125 | string neigGps2_ = nh.resolveName("neighbour_position_2");
126 | ros::Subscriber neigGps2 = nh.subscribe(neigGps2_, 5, neigGpsSubCb2);
127 |
128 | //Publisher to the gps(toString)
129 | string gps_string_pub_ = nh.resolveName("serial_data_send");
130 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
131 |
132 | //Publisher to the velocity of the copter
133 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
134 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
135 |
136 | ROS_INFO("Waiting for action server(takeOff) to start.");
137 |
138 | ac.waitForServer();
139 |
140 | ROS_INFO("Action server started--Taking off!");
141 |
142 | spiri_go::TakeoffGoal goal;
143 |
144 | //set the target height to take off!
145 | goal.height = 3;
146 |
147 | ac.sendGoal(goal);
148 |
149 | //wait for action(takeOff) to return
150 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
151 | ros::Duration(5).sleep();
152 | if(is_takeOff_finished ) {
153 | ROS_INFO("reached target height!");
154 | ofile.open("./log/data.log", ios::trunc);
155 |
156 | while(nh.ok()) {
157 | //1.publish self gps(toString)
158 | std_msgs::String gps_string;
159 | std::stringstream ss;
160 | ss << "01o"<= 1) {
225 | vel.twist.linear.x = 1;
226 | }else if(vel.twist.linear.x <= -1) {
227 | vel.twist.linear.x = -1;
228 | }
229 | if(vel.twist.linear.y >= 1) {
230 | vel.twist.linear.y = 1;
231 | }else if(vel.twist.linear.y <= -1) {
232 | vel.twist.linear.y = -1;
233 | }
234 |
235 |
236 | vel.header.stamp = ros::Time::now();
237 |
238 | //4.publish velocity to mavros
239 | vel_pub.publish(vel);
240 | //ROS_INFO("velocity_x:%f", vel.twist.linear.x);
241 | //ROS_INFO("velocity_y:%f", vel.twist.linear.y);
242 | ofile << vel.twist.linear.x << " " << vel.twist.linear.y << x_0 << y_0 << x_1 << y_1 << std::endl;
243 |
244 | // if fly for 4 minutes
245 | if( (ros::Time::now().toSec() - begin_time) > 4*60 ) {
246 | //land
247 | ROS_INFO("Waiting for action server(land) to start.");
248 | ac1.waitForServer();
249 | ROS_INFO("Start to land!.");
250 |
251 | spiri_go::LandHereGoal goal_1;
252 | goal_1.height = 0;
253 | ac1.sendGoal(goal_1);
254 |
255 | //wait for action(land) to return
256 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
257 | if(is_land_finished ) {
258 | ROS_INFO("Land success!");
259 | }
260 | }
261 |
262 | ros::spinOnce();
263 | loop_rate.sleep();
264 | }
265 | }
266 | else {
267 | ROS_INFO("should set mode Land!");
268 | }
269 |
270 | return 0;
271 |
272 | }
273 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/leader.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: leader.cpp
6 | *
7 | * Purpose: Formation control of leaders with collision avoidance using releative position.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2016/4/06
11 | ******************************************************************************/
12 |
13 | #include "ros/ros.h"
14 | #include
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 |
31 | #define R 6371000 //meter
32 | #define PI 3.1415926535898
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
40 | selfGlobalPos = *msg;
41 | }
42 |
43 | /*******************************************************************************
44 | * Callback function on the gps of the neighbour copter
45 | *
46 | * @param gpsPositionConstPtr& the gps callback pointer
47 | ******************************************************************************/
48 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
49 | {
50 | neigGlobalPos = *msg;
51 | }
52 |
53 | /*******************************************************************************
54 | * Main function
55 | *
56 | * @param
57 | ******************************************************************************/
58 | int main(int argc, char **argv) {
59 | ros::init(argc, argv, "spiri_go_client");
60 | ros::NodeHandle nh;
61 |
62 | ros::Rate loop_rate(10.0);
63 |
64 | //velocity to publish
65 | geometry_msgs::TwistStamped vel;
66 | vel.twist.linear.x = 0.0;
67 | vel.twist.linear.y = 0.0;
68 | vel.header.stamp = ros::Time::now();
69 |
70 | //variables definition
71 | float x_0 = 0.0;
72 | float y_0 = 0.0;
73 | float x_1 = 0.0;
74 | float y_1 = 0.0;
75 | float d12 = 10; //meter,two leaders mantain the distance
76 | float r = 1.0; // the region that collision avoidance algorithm will take effect
77 | float r1 = 5.0; // the region that collision avoidance algorithm will take effect
78 | float vx0 = 0.0;
79 | float vy0 = 0.0;
80 | float currentDisPow = 0.0;
81 | float x_offset = 0.0;
82 | float y_offset = 0.0;
83 |
84 | ofstream ofile;
85 | float begin_time = ros::Time::now().toSec();
86 | ROS_INFO("begin_time,%6.4f",begin_time);
87 |
88 | //takeoff action object
89 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
90 | //land action object
91 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
92 |
93 | // Subscriber to the Copter gps
94 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
95 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
96 |
97 | // Subscriber to the neighbour gps
98 | string neigGps_ = nh.resolveName("neighbour_position");
99 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
100 |
101 | //Publisher to the gps(toString)
102 | string gps_string_pub_ = nh.resolveName("serial_data_send");
103 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
104 |
105 | //Publisher to the velocity of the copter
106 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
107 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
108 |
109 | ROS_INFO("Waiting for action server(takeOff) to start.");
110 |
111 | ac.waitForServer();
112 |
113 | ROS_INFO("Action server started--Taking off!");
114 |
115 | spiri_go::TakeoffGoal goal;
116 |
117 | //set the target height to take off!
118 | goal.height = 3;
119 |
120 | ac.sendGoal(goal);
121 |
122 | //wait for action(takeOff) to return
123 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
124 | ros::Duration(5).sleep();
125 | if(is_takeOff_finished ) {
126 | ROS_INFO("reached target height!");
127 | ofile.open("./log/data.log", ios::trunc);
128 |
129 | while(nh.ok()) {
130 | //1.publish self gps(toString)
131 | std_msgs::String gps_string;
132 | std::stringstream ss;
133 | ss << "x1o"<= 1) {
183 | vel.twist.linear.x = 1;
184 | }else if(vel.twist.linear.x <= -1) {
185 | vel.twist.linear.x = -1;
186 | }
187 | if(vel.twist.linear.y >= 1) {
188 | vel.twist.linear.y = 1;
189 | }else if(vel.twist.linear.y <= -1) {
190 | vel.twist.linear.y = -1;
191 | }
192 |
193 |
194 | vel.header.stamp = ros::Time::now();
195 |
196 | //4.publish velocity to mavros
197 | vel_pub.publish(vel);
198 | //ROS_INFO("velocity_x:%f", vel.twist.linear.x);
199 | //ROS_INFO("velocity_y:%f", vel.twist.linear.y);
200 | ofile << vel.twist.linear.x << " " << vel.twist.linear.y << x_0 << y_0 << x_1 << y_1 << std::endl;
201 |
202 | // if fly for 4 minutes
203 | if( (ros::Time::now().toSec() - begin_time) > 4*60 ) {
204 | //land
205 | ROS_INFO("Waiting for action server(land) to start.");
206 | ac1.waitForServer();
207 | ROS_INFO("Start to land!.");
208 |
209 | spiri_go::LandHereGoal goal_1;
210 | goal_1.height = 0;
211 | ac1.sendGoal(goal_1);
212 |
213 | //wait for action(land) to return
214 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
215 | if(is_land_finished ) {
216 | ROS_INFO("Land success!");
217 | }
218 | }
219 |
220 | ros::spinOnce();
221 | loop_rate.sleep();
222 | }
223 | }
224 | else {
225 | ROS_INFO("should set mode Land!");
226 | }
227 |
228 | return 0;
229 |
230 | }
231 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/leader.cpp~:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: leader.cpp
6 | *
7 | * Purpose: Formation control of leaders with collision avoidance using releative position.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2016/4/06
11 | ******************************************************************************/
12 |
13 | #include "ros/ros.h"
14 | #include
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 |
31 | #define R 6371000 //meter
32 | #define PI 3.1415926535898
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
40 | selfGlobalPos = *msg;
41 | }
42 |
43 | /*******************************************************************************
44 | * Callback function on the gps of the neighbour copter
45 | *
46 | * @param gpsPositionConstPtr& the gps callback pointer
47 | ******************************************************************************/
48 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
49 | {
50 | neigGlobalPos = *msg;
51 | }
52 |
53 | /*******************************************************************************
54 | * Main function
55 | *
56 | * @param
57 | ******************************************************************************/
58 | int main(int argc, char **argv) {
59 | ros::init(argc, argv, "spiri_go_client");
60 | ros::NodeHandle nh;
61 |
62 | ros::Rate loop_rate(10.0);
63 |
64 | //velocity to publish
65 | geometry_msgs::TwistStamped vel;
66 | vel.twist.linear.x = 0.0;
67 | vel.twist.linear.y = 0.0;
68 | vel.header.stamp = ros::Time::now();
69 |
70 | //variables definition
71 | float x_0 = 0.0;
72 | float y_0 = 0.0;
73 | float x_1 = 0.0;
74 | float y_1 = 0.0;
75 | float d12 = 10; //meter,two leaders mantain the distance
76 | float r = 1.0; // the region that collision avoidance algorithm will take effect
77 | float r1 = 5.0; // the region that collision avoidance algorithm will take effect
78 | float vx0 = 0.0;
79 | float vy0 = 0.0;
80 | float currentDisPow = 0.0;
81 | float x_offset = 0.0;
82 | float y_offset = 0.0;
83 |
84 | ofstream ofile;
85 | float begin_time = ros::Time::now().toSec();
86 | ROS_INFO("begin_time,%6.4f",begin_time);
87 |
88 | //takeoff action object
89 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
90 | //land action object
91 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
92 |
93 | // Subscriber to the Copter gps
94 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
95 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
96 |
97 | // Subscriber to the neighbour gps
98 | string neigGps_ = nh.resolveName("neighbour_position");
99 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
100 |
101 | //Publisher to the gps(toString)
102 | string gps_string_pub_ = nh.resolveName("serial_data_send");
103 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
104 |
105 | //Publisher to the velocity of the copter
106 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
107 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
108 |
109 | ROS_INFO("Waiting for action server(takeOff) to start.");
110 |
111 | ac.waitForServer();
112 |
113 | ROS_INFO("Action server started--Taking off!");
114 |
115 | spiri_go::TakeoffGoal goal;
116 |
117 | //set the target height to take off!
118 | goal.height = 3;
119 |
120 | ac.sendGoal(goal);
121 |
122 | //wait for action(takeOff) to return
123 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
124 | ros::Duration(5).sleep();
125 | if(is_takeOff_finished ) {
126 | ROS_INFO("reached target height!");
127 | ofile.open("./log/data.log", ios::trunc);
128 |
129 | while(nh.ok()) {
130 | //1.publish self gps(toString)
131 | std_msgs::String gps_string;
132 | std::stringstream ss;
133 | ss << "x1o"<= 1) {
183 | vel.twist.linear.x = 1;
184 | }else if(vel.twist.linear.x <= -1) {
185 | vel.twist.linear.x = -1;
186 | }
187 | if(vel.twist.linear.y >= 1) {
188 | vel.twist.linear.y = 1;
189 | }else if(vel.twist.linear.y <= -1) {
190 | vel.twist.linear.y = -1;
191 | }
192 |
193 |
194 | vel.header.stamp = ros::Time::now();
195 |
196 | //4.publish velocity to mavros
197 | vel_pub.publish(vel);
198 | //ROS_INFO("velocity_x:%f", vel.twist.linear.x);
199 | //ROS_INFO("velocity_y:%f", vel.twist.linear.y);
200 | ofile << vel.twist.linear.x << " " << vel.twist.linear.y << x_0 << y_0 << x_1 << y_1 << std::endl;
201 |
202 | // if fly for 4 minutes
203 | if( (ros::Time::now().toSec() - begin_time) > 4*60 ) {
204 | //land
205 | ROS_INFO("Waiting for action server(land) to start.");
206 | ac1.waitForServer();
207 | ROS_INFO("Start to land!.");
208 |
209 | spiri_go::LandHereGoal goal_1;
210 | goal_1.height = 0;
211 | ac1.sendGoal(goal_1);
212 |
213 | //wait for action(land) to return
214 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
215 | if(is_land_finished ) {
216 | ROS_INFO("Land success!");
217 | }
218 | }
219 |
220 | ros::spinOnce();
221 | loop_rate.sleep();
222 | }
223 | }
224 | else {
225 | ROS_INFO("should set mode Land!");
226 | }
227 |
228 | return 0;
229 |
230 | }
231 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/leader_control.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * leader adaptive control
3 | */
4 |
5 | #include "ros/ros.h"
6 | #include
7 | #include
8 | #include
9 | #include "spiri_go.h"
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 |
18 | //global variables
19 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
20 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
21 |
22 | #define R 6371000 //meter
23 | #define PI 3.1415926535898
24 |
25 | /*******************************************************************************
26 | * Callback function on the gps of the copter
27 | *
28 | * @param gpsPositionConstPtr& the gps callback pointer
29 | ******************************************************************************/
30 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
31 | selfGlobalPos = *msg;
32 | }
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the neighbour copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
40 | {
41 | neigGlobalPos = *msg;
42 | }
43 |
44 | /*******************************************************************************
45 | * Main function
46 | *
47 | * @param
48 | ******************************************************************************/
49 | int main(int argc, char **argv) {
50 | ros::init(argc, argv, "spiri_go_client");
51 | ros::NodeHandle nh;
52 |
53 | ros::Rate loop_rate(10.0);
54 |
55 | //velocity to publish
56 | geometry_msgs::TwistStamped vel;
57 | vel.twist.linear.x = 0.0;
58 | vel.twist.linear.y = 0.0;
59 | vel.header.stamp = ros::Time::now();
60 |
61 | //variables definition
62 | float x_0 = 0.0;
63 | float y_0 = 0.0;
64 | float x_1 = 0.0;
65 | float y_1 = 0.0;
66 | float d12 = 10; //meter,two leaders mantain the distance
67 | float vx0 = 0.0;
68 | float vy0 = 0.0;
69 | float currentDisPow = 0.0;
70 |
71 | //takeoff action object
72 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
73 |
74 | // Subscriber to the Copter gps
75 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
76 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
77 |
78 | // Subscriber to the neighbour gps
79 | string neigGps_ = nh.resolveName("neighbour_position");
80 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
81 |
82 | //Publisher to the gps(toString)
83 | string gps_string_pub_ = nh.resolveName("serial_data_send");
84 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
85 |
86 | //Publisher to the velocity of the copter
87 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
88 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
89 |
90 | ROS_INFO("Waiting for action server(takeOff) to start.");
91 |
92 | ac.waitForServer();
93 |
94 | ROS_INFO("Action server started--Taking off!");
95 |
96 | spiri_go::TakeoffGoal goal;
97 |
98 | //set the target height to take off!
99 | goal.height = 3;
100 |
101 | ac.sendGoal(goal);
102 |
103 | //wait for action(takeOff) to return
104 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
105 | ros::Duration(10).sleep();
106 | if(is_takeOff_finished ) {
107 | ROS_INFO("reached target height!");
108 |
109 | while(nh.ok()) {
110 | //1.publish self gps(toString)
111 | std_msgs::String gps_string;
112 | std::stringstream ss;
113 | ss << "o"<= 1) {
145 | vel.twist.linear.x = 1;
146 | }else if(vel.twist.linear.x <= -1) {
147 | vel.twist.linear.x = -1;
148 | }
149 | if(vel.twist.linear.y >= 1) {
150 | vel.twist.linear.y = 1;
151 | }else if(vel.twist.linear.y <= -1) {
152 | vel.twist.linear.y = -1;
153 | }
154 |
155 |
156 | vel.header.stamp = ros::Time::now();
157 |
158 | //4.publish velocity to mavros
159 | vel_pub.publish(vel);
160 | ROS_INFO("velocity_x:%f", vel.twist.linear.x);
161 | ROS_INFO("velocity_y:%f", vel.twist.linear.y);
162 |
163 | ros::spinOnce();
164 | loop_rate.sleep();
165 | }
166 | }
167 | else {
168 | ROS_INFO("should set mode Land!");
169 | }
170 |
171 | return 0;
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/leader_control.cpp~:
--------------------------------------------------------------------------------
1 | /**
2 | * leader adaptive control
3 | */
4 |
5 | #include "ros/ros.h"
6 | #include
7 | #include
8 | #include
9 | #include "spiri_go.h"
10 | #include
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 |
17 |
18 | //global variables
19 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
20 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
21 |
22 | #define R 6371000 //meter
23 | #define PI 3.1415926535898
24 |
25 | /*******************************************************************************
26 | * Callback function on the gps of the copter
27 | *
28 | * @param gpsPositionConstPtr& the gps callback pointer
29 | ******************************************************************************/
30 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
31 | selfGlobalPos = *msg;
32 | }
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the neighbour copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
40 | {
41 | neigGlobalPos = *msg;
42 | }
43 |
44 | /*******************************************************************************
45 | * Main function
46 | *
47 | * @param
48 | ******************************************************************************/
49 | int main(int argc, char **argv) {
50 | ros::init(argc, argv, "spiri_go_client");
51 | ros::NodeHandle nh;
52 |
53 | ros::Rate loop_rate(10.0);
54 |
55 | //velocity to publish
56 | geometry_msgs::TwistStamped vel;
57 | vel.twist.linear.x = 0.0;
58 | vel.twist.linear.y = 0.0;
59 | vel.header.stamp = ros::Time::now();
60 |
61 | //variables definition
62 | float x_0 = 0.0;
63 | float y_0 = 0.0;
64 | float x_1 = 0.0;
65 | float y_1 = 0.0;
66 | float d12 = 10; //meter,two leaders mantain the distance
67 | float vx0 = 0.0;
68 | float vy0 = 0.0;
69 | float currentDisPow = 0.0;
70 |
71 | //takeoff action object
72 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
73 |
74 | // Subscriber to the Copter gps
75 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
76 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
77 |
78 | // Subscriber to the neighbour gps
79 | string neigGps_ = nh.resolveName("neighbour_position");
80 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
81 |
82 | //Publisher to the gps(toString)
83 | string gps_string_pub_ = nh.resolveName("serial_data_send");
84 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
85 |
86 | //Publisher to the velocity of the copter
87 | string vel_pub_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
88 | ros::Publisher vel_pub = nh.advertise(vel_pub_, 5);
89 |
90 | ROS_INFO("Waiting for action server(takeOff) to start.");
91 |
92 | ac.waitForServer();
93 |
94 | ROS_INFO("Action server started--Taking off!");
95 |
96 | spiri_go::TakeoffGoal goal;
97 |
98 | //set the target height to take off!
99 | goal.height = 3;
100 |
101 | ac.sendGoal(goal);
102 |
103 | //wait for action(takeOff) to return
104 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
105 | ros::Duration(10).sleep();
106 | if(is_takeOff_finished ) {
107 | ROS_INFO("reached target height!");
108 |
109 | while(nh.ok()) {
110 | //1.publish self gps(toString)
111 | std_msgs::String gps_string;
112 | std::stringstream ss;
113 | ss << "o"<= 1) {
145 | vel.twist.linear.x = 1;
146 | }else if(vel.twist.linear.x <= -1) {
147 | vel.twist.linear.x = -1;
148 | }
149 | if(vel.twist.linear.y >= 1) {
150 | vel.twist.linear.y = 1;
151 | }else if(vel.twist.linear.y <= -1) {
152 | vel.twist.linear.y = -1;
153 | }
154 |
155 |
156 | vel.header.stamp = ros::Time::now();
157 |
158 | //4.publish velocity to mavros
159 | vel_pub.publish(vel);
160 | ROS_INFO("velocity_x:%f", vel.twist.linear.x);
161 | ROS_INFO("velocity_y:%f", vel.twist.linear.y);
162 |
163 | ros::spinOnce();
164 | loop_rate.sleep();
165 | }
166 | }
167 | else {
168 | ROS_INFO("should set mode Land!");
169 | }
170 |
171 | return 0;
172 |
173 | }
174 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/leader_go.cpp~:
--------------------------------------------------------------------------------
1 | // -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
2 |
3 | /*******************************************************************************
4 | * The Spiri Project
5 | *
6 | * File: spiri_go.cpp
7 | *
8 | * Purpose: Sets up the ROS node that serves as the service
9 | * and action server for autonomous flights.
10 | *
11 | * @author Skyler Olson
12 | * @author John Lian
13 | * @version 0.1.0 27/11/15
14 | ******************************************************************************/
15 |
16 | #include "ros/ros.h"
17 | #include "ros/package.h"
18 | #include "geometry_msgs/Twist.h"
19 | #include "geometry_msgs/PoseStamped.h"
20 | #include "std_msgs/Empty.h"
21 | #include "std_srvs/Empty.h"
22 | #include "mavros_msgs/State.h"
23 | #include "mavros_msgs/SetMode.h"
24 | #include "mavros_msgs/CommandTOL.h"
25 | #include "mavros_msgs/CommandBool.h"
26 | #include "mavros_msgs/CommandLong.h"
27 | #include "mavros_msgs/OverrideRCIn.h"
28 | #include "mavros_msgs/CommandLong.h"
29 | #include "mavros_msgs/CommandBool.h"
30 | #include "std_msgs/String.h"
31 | #include "spiri_go.h"
32 | #include
33 | #include
34 |
35 | /*******************************************************************************
36 | * The SpiriGo constructor. The constructor will set up subscribers and
37 | * publishers to mavros.
38 | ******************************************************************************/
39 | SpiriGo::SpiriGo():
40 | takeoff_as(nh, "spiri_take_off", boost::bind(&SpiriGo::armAndTakeOff, this, _1), false),
41 | land_here_as(nh, "spiri_land_here", boost::bind(&SpiriGo::landHere, this, _1), false)
42 | {
43 | ROS_INFO("Constructing Go");
44 |
45 | // Subscriber to the position of the copter centered on the home location
46 | string local_ = nh.resolveName("/mavros/local_position/pose");
47 | local = nh.subscribe(local_, 1, &SpiriGo::localSubCb, this);
48 |
49 | // Subscriber to the states of the copter
50 | string state_ = nh.resolveName("/mavros/state");
51 | state = nh.subscribe(state_, 1, &SpiriGo::stateSubCb, this);
52 |
53 | // Control the velocity of the copter
54 | string vel_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
55 | vel = nh.advertise(vel_,1);
56 |
57 | // Set the mode
58 | string set_mode_ = nh.resolveName("/mavros/set_mode");
59 | set_mode = nh.serviceClient(set_mode_);
60 |
61 | // Arming
62 | string arm_ = nh.resolveName("/mavros/cmd/arming");
63 | arm = nh.serviceClient(arm_);
64 |
65 | // Tell the copter to take off autonomously
66 | string takeoff_ = nh.resolveName("/mavros/cmd/takeoff");
67 | takeoff = nh.serviceClient(takeoff_);
68 |
69 | // MAVLink commander for yaw because setAttitude doesn't work in APM
70 | string mavlink_cmd_srv_ = nh.resolveName("/mavros/cmd/command");
71 | mavlink_cmd_srv = nh.serviceClient(mavlink_cmd_srv_);
72 |
73 | // Create the services and actions that other nodes can interact with spiri_go through
74 | getLocalPositionService = nh.advertiseService("spiri_local_position", &SpiriGo::getLocalPositionSCB, this);
75 | getLastStateService = nh.advertiseService("spiri_state", &SpiriGo::getLastStateSCB, this);
76 |
77 | // State variables
78 | last_state.armed = false;
79 | last_state.connected = false;
80 | last_state.guided = false;
81 | last_state.mode = "STABILIZE";
82 | taking_off = false;
83 | flying = false;
84 |
85 | // location z has to start here so you don't set flying too soon
86 | location.position.z = 0;
87 |
88 | // set the velocity to 0 all around
89 | velocity.linear.x = 0;
90 | velocity.linear.y = 0;
91 | velocity.linear.z = 0;
92 |
93 | ROS_INFO("Constructed Go");
94 |
95 | }
96 |
97 | /*******************************************************************************
98 | * The SpiriGo destructor
99 | ******************************************************************************/
100 | SpiriGo::~SpiriGo()
101 | {
102 |
103 | }
104 |
105 | ////////////////////////////////////////////////////////////////////////////////
106 | // Callback functions
107 | ////////////////////////////////////////////////////////////////////////////////
108 |
109 | /*******************************************************************************
110 | * Callback function on the local position of the copter
111 | *
112 | * @param loalPtr the location callback pointer
113 | ******************************************************************************/
114 | void SpiriGo::localSubCb(const geometry_msgs::PoseStamped localPtr)
115 | {
116 | location = localPtr.pose;
117 | last_location = localPtr.pose;
118 | }
119 |
120 | /*******************************************************************************
121 | * Callback function on the state of the copter
122 | *
123 | * @param statePtr the state callback pointer
124 | ******************************************************************************/
125 | void SpiriGo::stateSubCb(const mavros_msgs::State statePtr)
126 | {
127 | last_state = statePtr;
128 | }
129 |
130 | /*******************************************************************************
131 | * Service callback function on the local position of the copter
132 | *
133 | * @return True if the service is successfully called
134 | ******************************************************************************/
135 | bool SpiriGo::getLocalPositionSCB(spiri_go::LocalPosition::Request &req,
136 | spiri_go::LocalPosition::Response &rsp){
137 | rsp.x = location.position.x;
138 | rsp.y = location.position.y;
139 | rsp.z = location.position.z;
140 | return true;
141 | }
142 |
143 | /*******************************************************************************
144 | * Service callback function on the state of the copter
145 | *
146 | * @return True if the service is successfully called
147 | ******************************************************************************/
148 | bool SpiriGo::getLastStateSCB(spiri_go::LastState::Request &req,
149 | spiri_go::LastState::Response &rsp){
150 | rsp.armed = last_state.armed;
151 | rsp.connected = last_state.connected;
152 | rsp.guided = last_state.guided;
153 | rsp.mode = last_state.guided;
154 | return true;
155 | }
156 |
157 | ////////////////////////////////////////////////////////////////////////////////
158 | // Spiri control methods
159 | ////////////////////////////////////////////////////////////////////////////////
160 |
161 | /*******************************************************************************
162 | * A function to set the desired mode of the copter
163 | *
164 | * @param targetMode is a string for the name of the desired mode
165 | * Note: the function will fail if the targetMode name is not valid
166 | *
167 | * @return True if the mode set is successfully called
168 | ******************************************************************************/
169 | bool SpiriGo::setMode(const char* targetMode)
170 | {
171 | mavros_msgs::SetMode modeCmd;
172 |
173 | modeCmd.request.base_mode = 0;
174 | modeCmd.request.custom_mode = targetMode;
175 |
176 | if(set_mode.call(modeCmd)){
177 | ROS_INFO("Set to %s Mode.", targetMode);
178 | return modeCmd.response.success;
179 | }else{
180 | ROS_INFO("Failed to set to %s Mode. Currently in %s mode", targetMode, last_state.mode.c_str());
181 | return false;
182 | }
183 | }
184 |
185 | /*******************************************************************************
186 | * A function to the copter to GUIDED mode
187 | *
188 | * @return True if the the copter has been successfully set to GUIDED mode
189 | ******************************************************************************/
190 | bool SpiriGo::setGuided()
191 | {
192 | return setMode("GUIDED");
193 | }
194 |
195 | /*******************************************************************************
196 | * A function to arm the motors of the copter
197 | *
198 | * @return True if the the copter has been successfully armed
199 | ******************************************************************************/
200 | bool SpiriGo::setArmed()
201 | {
202 | mavros_msgs::CommandBool set_armed;
203 | set_armed.request.value = true;
204 |
205 | if(arm.call(set_armed)){
206 | ROS_INFO("Set Armed.");
207 | return set_armed.response.success;
208 | }else{
209 | ROS_INFO("Failed to set to Armed.");
210 | return false;
211 | }
212 | }
213 |
214 | /*******************************************************************************
215 | * Make the copter takeoff to a specified height
216 | *
217 | * @param targetAlt a float value of the target altitude (relative to the ground)
218 | * @return True if the takeoff command has been successfully issued to the copter
219 | ******************************************************************************/
220 | void SpiriGo::takeOff(float targetAlt = 5)
221 | {
222 | // try to take off
223 | mavros_msgs::CommandTOL to_cmd;
224 |
225 | to_cmd.request.altitude = targetAlt;
226 |
227 | // TODO: make this a bool function based on the success of the call
228 | if(takeoff.call(to_cmd)){
229 | ROS_INFO("Taking off");
230 | taking_off = true;
231 | }else{
232 | ROS_INFO("Failed to initiate take off");
233 | }
234 | }
235 |
236 | /*******************************************************************************
237 | * Tell the copter to go to specified heading
238 | *
239 | * @param targetYaw angle (in degrees) of the desired heading (from north = 0 degrees)
240 | * @param targetYawRate angular velocity in deg/s of the desired yaw rate
241 | * @return True if the yaw command has been successfully issued to the copter
242 | ******************************************************************************/
243 | void SpiriGo::conditionYaw(float targetYaw, float targetYawRate)
244 | {
245 | mavros_msgs::CommandLong yawCmd;
246 |
247 | yawCmd.request.command = 155; // MAVLink command ID for MAV_CMD_CONDITION_YAW
248 | yawCmd.request.confirmation = 0; // 0 is default for confirmation
249 | yawCmd.request.param1 = targetYaw; // target heading/yaw in degrees from north (0 to 360)
250 | yawCmd.request.param2 = targetYawRate; // target yaw rate in deg/s
251 | yawCmd.request.param3 = 1; // direction; -1 ccw, 1 cw TODO: make this automatic
252 | yawCmd.request.param4 = 0; // relative offset 1, absolute angle 0
253 |
254 | // TODO: return true if the call was a success
255 | if(mavlink_cmd_srv.call(yawCmd)){
256 | ROS_INFO("Controlling yaw");
257 | }else{
258 | ROS_INFO("Condition yaw command rejected");
259 | }
260 | }
261 |
262 | // TODO: @ssorl what is your plan with this
263 | void SpiriGo::setENUVelocity(/*double eastwardVelocity, double northwardVelocity */)
264 | {
265 | geometry_msgs::TwistStamped control_msg;
266 |
267 | control_msg.twist.linear.x = velocity.linear.x;
268 | control_msg.twist.linear.y = velocity.linear.y;
269 |
270 | vel.publish(control_msg);
271 | }
272 |
273 | ////////////////////////////////////////////////////////////////////////////////
274 | // Action-specific methods - these will sleep until finished!!!
275 | ////////////////////////////////////////////////////////////////////////////////
276 |
277 | /*******************************************************************************
278 | * Full autonomous takeoff action
279 | *
280 | * This will ask the copter to go to GUIDED
281 | *
282 | * @param TakeoffGoalConstPtr the takeoff action goal object
283 | ******************************************************************************/
284 | void SpiriGo::armAndTakeOff(const spiri_go::TakeoffGoalConstPtr& goal)
285 | {
286 | if(!takeoff_as.isActive()||takeoff_as.isPreemptRequested()) return;
287 | ros::Rate takeoff_rate(5);
288 | bool success = true;
289 |
290 | // Set to guided mode and THEN arm the copter
291 | bool armed_ = setArmed();
292 | while(not last_state.armed)
293 | {
294 | if(not last_state.guided){
295 | setGuided();
296 | }else{
297 | bool armed_ = setArmed();
298 | }
299 | takeoff_rate.sleep();
300 | }
301 |
302 | // Sleep the method until the takeoff is complete
303 | taking_off = false;
304 | while(not taking_off)
305 | {
306 | takeOff(goal->height);
307 | takeoff_rate.sleep();
308 | }
309 | while(location.position.z < goal->height*0.96)
310 | {
311 | // Only wait to reach 96% of the target altitude to handle undershoot
312 | takeoff_rate.sleep();
313 | ROS_INFO("height: %f", location.position.z);
314 | }
315 | ROS_INFO("took off");
316 | flying = true;
317 |
318 | if(ros::ok()){
319 | takeoff_as.setSucceeded();
320 | ROS_INFO("Takeoff finished");
321 | } else {
322 | takeoff_as.setAborted();
323 | ROS_INFO("Takeoff aborted");
324 | }
325 | }
326 |
327 | /*******************************************************************************
328 | * Full autonomous land action
329 | *
330 | * This will ask the copter to go to LAND mode
331 | *
332 | * @param LandHereGoalConstPtr the land_here action goal object
333 | ******************************************************************************/
334 | void SpiriGo::landHere(const spiri_go::LandHereGoalConstPtr& goal)
335 | {
336 | if(!land_here_as.isActive()||land_here_as.isPreemptRequested()) return;
337 | ros::Rate land_rate(5);
338 | bool success = true;
339 |
340 | ROS_INFO("Attempting to land in place");
341 |
342 | // Change the mode to LAND in APM, which is autonomous landing
343 | while(last_state.mode != "LAND")
344 | {
345 | setMode("LAND");
346 | land_rate.sleep();
347 | }
348 |
349 | // Sleep until for the robot to think it's 5cm off the ground
350 | while(location.position.z > 0.05)
351 | {
352 | land_rate.sleep();
353 | }
354 |
355 | if(ros::ok()){
356 | land_here_as.setSucceeded();
357 | ROS_INFO("Landing finished");
358 | } else {
359 | land_here_as.setAborted();
360 | ROS_INFO("Landing finished");
361 | }
362 | }
363 |
364 |
365 | ////////////////////////////////////////////////////////////////////////////////
366 | // Getter functions
367 | ////////////////////////////////////////////////////////////////////////////////
368 |
369 | /*******************************************************************************
370 | * @return The latest information on whether the copter is armed
371 | ******************************************************************************/
372 | bool SpiriGo::isArmed(){
373 | return last_state.armed;
374 | }
375 |
376 | /*******************************************************************************
377 | * @return The latest information on whether the copter is in GUIDED mode
378 | ******************************************************************************/
379 | bool SpiriGo::isControllable(){
380 | return last_state.guided;
381 | }
382 |
383 | /*******************************************************************************
384 | * @return The latest information the mode of the copter
385 | ******************************************************************************/
386 | std::string SpiriGo::getMode(){
387 | return last_state.mode;
388 | }
389 |
390 |
391 | ////////////////////////////////////////////////////////////////////////////////
392 | // Utility Methods
393 | ////////////////////////////////////////////////////////////////////////////////
394 |
395 | /*******************************************************************************
396 | * Make a best guess as to the current location
397 | * since the real value is provided fairly often
398 | * don't need to be too precise about it
399 | *
400 | * @param dt_dur how long since the last update
401 | ******************************************************************************/
402 | void SpiriGo::updateLocation(ros::Duration dt_dur){
403 | float dt = dt_dur.toSec();
404 | location.position.x += velocity.linear.x*dt;
405 | location.position.y += velocity.linear.y*dt;
406 | location.position.z += velocity.linear.z*dt;
407 | // TODO: deal with the angular part too
408 | }
409 |
410 | ////////////////////////////////////////////////////////////////////////////////
411 | // Main loop
412 | ////////////////////////////////////////////////////////////////////////////////
413 |
414 | void SpiriGo::Loop()
415 | {
416 | ros::Rate pub_rate(10);
417 |
418 | ros::Time last_time = ros::Time::now();
419 | while (nh.ok()){
420 | ros::spinOnce();
421 | if(flying){
422 | ros::Duration dt = ros::Time::now() - last_time;
423 | last_time = ros::Time::now();
424 | updateLocation(dt);
425 | setENUVelocity();
426 | }
427 |
428 | pub_rate.sleep();
429 | }
430 |
431 | }
432 |
433 | int main(int argc, char **argv)
434 | {
435 |
436 | ros::init(argc, argv, "spiri_go");
437 |
438 | SpiriGo go_thing;
439 |
440 | // start action servers
441 | go_thing.takeoff_as.start();
442 | go_thing.land_here_as.start();
443 |
444 | go_thing.Loop();
445 |
446 | return 0;
447 | }
448 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/read me.txt:
--------------------------------------------------------------------------------
1 | *********Server***********
2 | spiri_go.cpp *the original file, takeoff and land server
3 | *********Client***********
4 | arm_and_takeoff.cpp *arm and takeoff
5 | leader_control.cpp *leader adaptive control
6 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/read me.txt~:
--------------------------------------------------------------------------------
1 | *********Server***********
2 | spiri_go.cpp *the original file, takeoff and land server
3 | *********Client***********
4 | arm_and_takeoff.cpp *arm and takeoff
5 | leader_control.cpp *leader adaptive control
6 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/spiri_data_classes.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a collection of classes that are used in spiri_go and that
3 | * are exposed by boost in spiri_boost so that they can be read and written
4 | * in stand-alone python scripts as well as ROS.
5 | */
6 |
7 | #include
8 |
9 | SpiriAttitude::SpiriAttitude(){
10 | roll = 0;
11 | pitch = 0;
12 | yaw = 0;
13 | }
14 |
15 | SpiriAttitude::SpiriAttitude(double roll, double pitch, double yaw){
16 | this->roll = roll;
17 | this->pitch = pitch;
18 | this->yaw = yaw;
19 | }
20 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/spiri_go.cpp:
--------------------------------------------------------------------------------
1 | // -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
2 |
3 | /*******************************************************************************
4 | * The Spiri Project
5 | *
6 | * File: spiri_go.cpp
7 | *
8 | * Purpose: Sets up the ROS node that serves as the service
9 | * and action server for autonomous flights.
10 | *
11 | * @author Skyler Olson
12 | * @author John Lian
13 | * @author Peng Cheng
14 | * @version 0.1.0 27/11/15
15 | * @version 0.1.1 2016/03/16
16 | ******************************************************************************/
17 |
18 | #include "ros/ros.h"
19 | #include "ros/package.h"
20 | #include "geometry_msgs/Twist.h"
21 | #include "geometry_msgs/PoseStamped.h"
22 | #include "std_msgs/Empty.h"
23 | #include "std_srvs/Empty.h"
24 | #include "mavros_msgs/State.h"
25 | #include "mavros_msgs/SetMode.h"
26 | #include "mavros_msgs/StreamRate.h"
27 | #include "mavros_msgs/CommandTOL.h"
28 | #include "mavros_msgs/CommandBool.h"
29 | #include "mavros_msgs/CommandLong.h"
30 | #include "mavros_msgs/OverrideRCIn.h"
31 | #include "mavros_msgs/CommandLong.h"
32 | #include "mavros_msgs/CommandBool.h"
33 | #include "std_msgs/String.h"
34 | #include "spiri_go.h"
35 | #include
36 | #include
37 |
38 | /*******************************************************************************
39 | * The SpiriGo constructor. The constructor will set up subscribers and
40 | * publishers to mavros.
41 | ******************************************************************************/
42 | SpiriGo::SpiriGo():
43 | takeoff_as(nh, "spiri_take_off", boost::bind(&SpiriGo::armAndTakeOff, this, _1), false),
44 | land_here_as(nh, "spiri_land_here", boost::bind(&SpiriGo::landHere, this, _1), false)
45 | {
46 | ROS_INFO("Constructing Go");
47 |
48 | // Subscriber to the position of the copter centered on the home location
49 | string local_ = nh.resolveName("/mavros/local_position/pose");
50 | local = nh.subscribe(local_, 1, &SpiriGo::localSubCb, this);
51 |
52 | // Subscriber to the states of the copter
53 | string state_ = nh.resolveName("/mavros/state");
54 | state = nh.subscribe(state_, 1, &SpiriGo::stateSubCb, this);
55 |
56 | // Subscriber to gps of copter, I add
57 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
58 | gps = nh.subscribe(gps_, 1, &SpiriGo::gpsSubCb, this);
59 |
60 | // Subscriber to height of copter, I add
61 | string alt_ = nh.resolveName("/mavros/global_position/global");
62 | alt = nh.subscribe(alt_, 1, &SpiriGo::altSubCb, this);
63 |
64 | //Subscriber to the mavlink/from of the copter, I add
65 | string connect_state_ = nh.resolveName("/mavlink/from");
66 | connect_state = nh.subscribe(connect_state_, 1, &SpiriGo::connectSubCb, this);
67 |
68 | // Control the velocity of the copter
69 | string vel_ = nh.resolveName("/mavros/setpoint_velocity/cmd_vel");
70 | vel = nh.advertise(vel_,1);
71 |
72 | // Set the mode
73 | string set_mode_ = nh.resolveName("/mavros/set_mode");
74 | set_mode = nh.serviceClient(set_mode_);
75 |
76 | // Set the stream rate
77 | string set_stream_rate_ = nh.resolveName("/mavros/set_stream_rate");
78 | set_stream_rate = nh.serviceClient(set_stream_rate_);
79 |
80 | // Arming
81 | string arm_ = nh.resolveName("/mavros/cmd/arming");
82 | arm = nh.serviceClient(arm_);
83 |
84 | // Tell the copter to take off autonomously
85 | string takeoff_ = nh.resolveName("/mavros/cmd/takeoff");
86 | takeoff = nh.serviceClient(takeoff_);
87 |
88 | // MAVLink commander for yaw because setAttitude doesn't work in APM
89 | string mavlink_cmd_srv_ = nh.resolveName("/mavros/cmd/command");
90 | mavlink_cmd_srv = nh.serviceClient(mavlink_cmd_srv_);
91 |
92 | // Create the services and actions that other nodes can interact with spiri_go through
93 | getLocalPositionService = nh.advertiseService("spiri_local_position", &SpiriGo::getLocalPositionSCB, this);
94 | getLastStateService = nh.advertiseService("spiri_state", &SpiriGo::getLastStateSCB, this);
95 |
96 | // State variables
97 | last_state.armed = false;
98 | last_state.connected = false;
99 | last_state.guided = false;
100 | last_state.mode = "STABILIZE";
101 | taking_off = false;
102 | flying = false;
103 |
104 | // location z has to start here so you don't set flying too soon
105 | location.position.z = 0;
106 |
107 | // set the velocity to 0 all around
108 | velocity.linear.x = 0;
109 | velocity.linear.y = 0;
110 | velocity.linear.z = 0;
111 |
112 | ROS_INFO("Constructed Go");
113 |
114 | }
115 |
116 | /*******************************************************************************
117 | * The SpiriGo destructor
118 | ******************************************************************************/
119 | SpiriGo::~SpiriGo()
120 | {
121 |
122 | }
123 |
124 | ////////////////////////////////////////////////////////////////////////////////
125 | // Callback functions
126 | ////////////////////////////////////////////////////////////////////////////////
127 |
128 | /*******************************************************************************
129 | * Callback function on the local position of the copter
130 | *
131 | * @param loalPtr the location callback pointer
132 | ******************************************************************************/
133 | void SpiriGo::localSubCb(const geometry_msgs::PoseStamped localPtr)
134 | {
135 | location = localPtr.pose;
136 | last_location = localPtr.pose;
137 | }
138 |
139 | /*******************************************************************************
140 | * Callback function on the state of the copter
141 | *
142 | * @param statePtr the state callback pointer
143 | ******************************************************************************/
144 | void SpiriGo::stateSubCb(const mavros_msgs::State statePtr)
145 | {
146 | last_state = statePtr;
147 | }
148 |
149 | /*******************************************************************************
150 | * Callback function on the gps of the copter
151 | *
152 | * @param NavSatFixConstPtr the state callback pointer
153 | ******************************************************************************/
154 | void SpiriGo::gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg)
155 | {
156 | last_gps = *msg;
157 | }
158 |
159 | /*******************************************************************************
160 | * Callback function on the height of the copter
161 | *
162 | * @param NavSatFixConstPtr the state callback pointer
163 | ******************************************************************************/
164 | void SpiriGo::altSubCb(const sensor_msgs::NavSatFixConstPtr& msg)
165 | {
166 | last_alt = *msg;
167 | ROS_INFO("altitude is %f", last_alt.altitude);
168 | }
169 |
170 | /*******************************************************************************
171 | * Callback function on the /mavlink/from of the copter
172 | *
173 | * @param NavSatFixConstPtr the state callback pointer
174 | ******************************************************************************/
175 | void SpiriGo::connectSubCb(const mavros_msgs::MavlinkPtr& fromPtr)
176 | {
177 | last_connect_state = *fromPtr;
178 | //ROS_INFO("is_valid:%d",last_connect_state.is_valid);
179 | //ROS_INFO("seq:%d",last_connect_state.seq);
180 | }
181 |
182 | /*******************************************************************************
183 | * Service callback function on the local position of the copter
184 | *
185 | * @return True if the service is successfully called
186 | ******************************************************************************/
187 | bool SpiriGo::getLocalPositionSCB(spiri_go::LocalPosition::Request &req,
188 | spiri_go::LocalPosition::Response &rsp){
189 | rsp.x = location.position.x;
190 | rsp.y = location.position.y;
191 | rsp.z = location.position.z;
192 | return true;
193 | }
194 |
195 | /*******************************************************************************
196 | * Service callback function on the state of the copter
197 | *
198 | * @return True if the service is successfully called
199 | ******************************************************************************/
200 | bool SpiriGo::getLastStateSCB(spiri_go::LastState::Request &req,
201 | spiri_go::LastState::Response &rsp){
202 | rsp.armed = last_state.armed;
203 | rsp.connected = last_state.connected;
204 | rsp.guided = last_state.guided;
205 | rsp.mode = last_state.guided;
206 | return true;
207 | }
208 |
209 | ////////////////////////////////////////////////////////////////////////////////
210 | // Spiri control methods
211 | ////////////////////////////////////////////////////////////////////////////////
212 |
213 | /*******************************************************************************
214 | * A function to set the desired mode of the copter
215 | *
216 | * @param targetMode is a string for the name of the desired mode
217 | * Note: the function will fail if the targetMode name is not valid
218 | *
219 | * @return True if the mode set is successfully called
220 | ******************************************************************************/
221 | bool SpiriGo::setMode(const char* targetMode)
222 | {
223 | mavros_msgs::SetMode modeCmd;
224 |
225 | modeCmd.request.base_mode = 0;
226 | modeCmd.request.custom_mode = targetMode;
227 |
228 | if(set_mode.call(modeCmd)){
229 | ROS_INFO("Set to %s Mode.", targetMode);
230 | return modeCmd.response.success;
231 | }else{
232 | ROS_INFO("Failed to set to %s Mode. Currently in %s mode", targetMode, last_state.mode.c_str());
233 | return false;
234 | }
235 | }
236 |
237 | /*******************************************************************************
238 | * A function to set the desired mode of the copter
239 | *
240 | * @param streamID is a string for the name of the desired stream
241 | * rate is the desired stream rate
242 | * Note: the function will fail if the targetMode name is not valid
243 | *
244 | * @return True if the mode set is successfully called
245 | ******************************************************************************/
246 | bool SpiriGo::setStreamRate(unsigned char streamID, int rate)
247 | {
248 | mavros_msgs::StreamRate streamRateCmd;
249 |
250 | streamRateCmd.request.stream_id = streamID;
251 | streamRateCmd.request.message_rate = rate;
252 | streamRateCmd.request.on_off = (rate!=0);
253 |
254 | if(set_stream_rate.call(streamRateCmd)){
255 | ROS_INFO("Set stream rate success!");
256 | return true;
257 | }
258 | else
259 | {
260 | ROS_INFO("Set stream rate failed!");
261 | return false;
262 | }
263 | }
264 |
265 | /*******************************************************************************
266 | * A function to the copter to GUIDED mode
267 | *
268 | * @return True if the the copter has been successfully set to GUIDED mode
269 | ******************************************************************************/
270 | bool SpiriGo::setGuided()
271 | {
272 | return setMode("GUIDED");
273 | }
274 |
275 | /*******************************************************************************
276 | * A function to arm the motors of the copter
277 | *
278 | * @return True if the the copter has been successfully armed
279 | ******************************************************************************/
280 | bool SpiriGo::setArmed()
281 | {
282 | mavros_msgs::CommandBool set_armed;
283 | set_armed.request.value = true;
284 |
285 | if(arm.call(set_armed)){
286 | ROS_INFO("Set Armed.");
287 | return set_armed.response.success;
288 | }else{
289 | ROS_INFO("Failed to set to Armed.");
290 | return false;
291 | }
292 | }
293 |
294 | /*******************************************************************************
295 | * Make the copter takeoff to a specified height
296 | *
297 | * @param targetAlt a float value of the target altitude (relative to the ground)
298 | * @return True if the takeoff command has been successfully issued to the copter
299 | ******************************************************************************/
300 | void SpiriGo::takeOff(float targetAlt = 5)
301 | {
302 | // try to take off
303 | mavros_msgs::CommandTOL to_cmd;
304 |
305 | to_cmd.request.altitude = targetAlt;
306 |
307 | // TODO: make this a bool function based on the success of the call
308 | if(takeoff.call(to_cmd)){
309 | ROS_INFO("Taking off");
310 | taking_off = true;
311 | }else{
312 | ROS_INFO("Failed to initiate take off");
313 | }
314 | }
315 |
316 | /*******************************************************************************
317 | * Tell the copter to go to specified heading
318 | *
319 | * @param targetYaw angle (in degrees) of the desired heading (from north = 0 degrees)
320 | * @param targetYawRate angular velocity in deg/s of the desired yaw rate
321 | * @return True if the yaw command has been successfully issued to the copter
322 | ******************************************************************************/
323 | void SpiriGo::conditionYaw(float targetYaw, float targetYawRate)
324 | {
325 | mavros_msgs::CommandLong yawCmd;
326 |
327 | yawCmd.request.command = 155; // MAVLink command ID for MAV_CMD_CONDITION_YAW
328 | yawCmd.request.confirmation = 0; // 0 is default for confirmation
329 | yawCmd.request.param1 = targetYaw; // target heading/yaw in degrees from north (0 to 360)
330 | yawCmd.request.param2 = targetYawRate; // target yaw rate in deg/s
331 | yawCmd.request.param3 = 1; // direction; -1 ccw, 1 cw TODO: make this automatic
332 | yawCmd.request.param4 = 0; // relative offset 1, absolute angle 0
333 |
334 | // TODO: return true if the call was a success
335 | if(mavlink_cmd_srv.call(yawCmd)){
336 | ROS_INFO("Controlling yaw");
337 | }else{
338 | ROS_INFO("Condition yaw command rejected");
339 | }
340 | }
341 |
342 | // TODO: @ssorl what is your plan with this
343 | void SpiriGo::setENUVelocity(/*double eastwardVelocity, double northwardVelocity */)
344 | {
345 | geometry_msgs::TwistStamped control_msg;
346 |
347 | control_msg.twist.linear.x = velocity.linear.x;
348 | control_msg.twist.linear.y = velocity.linear.y;
349 |
350 | vel.publish(control_msg);
351 | }
352 |
353 | ////////////////////////////////////////////////////////////////////////////////
354 | // Action-specific methods - these will sleep until finished!!!
355 | ////////////////////////////////////////////////////////////////////////////////
356 |
357 | /*******************************************************************************
358 | * Full autonomous takeoff action
359 | *
360 | * This will ask the copter to go to GUIDED
361 | *
362 | * @param TakeoffGoalConstPtr the takeoff action goal object
363 | ******************************************************************************/
364 | void SpiriGo::armAndTakeOff(const spiri_go::TakeoffGoalConstPtr& goal)
365 | {
366 | ROS_INFO("server excuteCB!");
367 | if(!takeoff_as.isActive()||takeoff_as.isPreemptRequested()) return;
368 | ros::Rate takeoff_rate(5);
369 | bool success = true;
370 |
371 | // Set to guided mode and THEN arm the copter
372 | bool armed_ = setArmed();
373 | while(not last_state.armed)
374 | {
375 | if(not last_state.guided){
376 | setGuided();
377 | }else{
378 | bool armed_ = setArmed();
379 | }
380 | takeoff_rate.sleep();
381 | }
382 |
383 | // Sleep the method until the takeoff is complete
384 | taking_off = false;
385 | while(not taking_off)
386 | {
387 | takeOff(goal->height);
388 | takeoff_rate.sleep();
389 | }
390 | while(last_alt.altitude < goal->height*0.96)
391 | {
392 | // Only wait to reach 96% of the target altitude to handle undershoot
393 | takeoff_rate.sleep();
394 | ROS_INFO("height: %f", last_alt.altitude);
395 | }
396 | ROS_INFO("took off");
397 | flying = true;
398 |
399 | if(ros::ok()){
400 | takeoff_as.setSucceeded();
401 | ROS_INFO("Takeoff finished");
402 | } else {
403 | takeoff_as.setAborted();
404 | ROS_INFO("Takeoff aborted");
405 | }
406 | }
407 |
408 | /*******************************************************************************
409 | * Full autonomous land action
410 | *
411 | * This will ask the copter to go to LAND mode
412 | *
413 | * @param LandHereGoalConstPtr the land_here action goal object
414 | ******************************************************************************/
415 | void SpiriGo::landHere(const spiri_go::LandHereGoalConstPtr& goal)
416 | {
417 | ROS_INFO("server excuteCB!");
418 | if(!land_here_as.isActive()||land_here_as.isPreemptRequested()) return;
419 | ros::Rate land_rate(5);
420 | bool success = true;
421 |
422 | ROS_INFO("Attempting to land in place");
423 |
424 | // Change the mode to LAND in APM, which is autonomous landing
425 | while(last_state.mode != "LAND")
426 | {
427 | setMode("LAND");
428 | land_rate.sleep();
429 | }
430 |
431 | // Sleep until for the robot to think it's 5cm off the ground
432 | while(location.position.z > 0.05)
433 | {
434 | land_rate.sleep();
435 | }
436 |
437 | if(ros::ok()){
438 | land_here_as.setSucceeded();
439 | ROS_INFO("Landing finished");
440 | } else {
441 | land_here_as.setAborted();
442 | ROS_INFO("Landing finished");
443 | }
444 | }
445 |
446 |
447 | ////////////////////////////////////////////////////////////////////////////////
448 | // Getter functions
449 | ////////////////////////////////////////////////////////////////////////////////
450 |
451 | /*******************************************************************************
452 | * @return The latest information on whether the copter is armed
453 | ******************************************************************************/
454 | bool SpiriGo::isArmed(){
455 | return last_state.armed;
456 | }
457 |
458 | /*******************************************************************************
459 | * @return The latest information on whether the copter is in GUIDED mode
460 | ******************************************************************************/
461 | bool SpiriGo::isControllable(){
462 | return last_state.guided;
463 | }
464 |
465 | /*******************************************************************************
466 | * @return The latest information on whether the copter has connected to mavros
467 | ******************************************************************************/
468 | bool SpiriGo::isValid() {
469 | return last_connect_state.is_valid;
470 | }
471 |
472 | /*******************************************************************************
473 | * @return The latest information the mode of the copter
474 | ******************************************************************************/
475 | std::string SpiriGo::getMode(){
476 | return last_state.mode;
477 | }
478 |
479 |
480 | ////////////////////////////////////////////////////////////////////////////////
481 | // Utility Methods
482 | ////////////////////////////////////////////////////////////////////////////////
483 |
484 | /*******************************************************************************
485 | * Make a best guess as to the current location
486 | * since the real value is provided fairly often
487 | * don't need to be too precise about it
488 | *
489 | * @param dt_dur how long since the last update
490 | ******************************************************************************/
491 | void SpiriGo::updateLocation(ros::Duration dt_dur){
492 | float dt = dt_dur.toSec();
493 | location.position.x += velocity.linear.x*dt;
494 | location.position.y += velocity.linear.y*dt;
495 | location.position.z += velocity.linear.z*dt;
496 | // TODO: deal with the angular part too
497 | }
498 |
499 | ////////////////////////////////////////////////////////////////////////////////
500 | // Main loop
501 | ////////////////////////////////////////////////////////////////////////////////
502 |
503 | void SpiriGo::Loop()
504 | {
505 | ros::Rate pub_rate(10);
506 |
507 | ros::Time last_time = ros::Time::now();
508 | while (nh.ok()){
509 | ros::spinOnce();
510 | if(flying){
511 | ros::Duration dt = ros::Time::now() - last_time;
512 | last_time = ros::Time::now();
513 | //updateLocation(dt);
514 | //setENUVelocity();
515 | }
516 |
517 | pub_rate.sleep();
518 | }
519 |
520 | }
521 |
522 | int main(int argc, char **argv)
523 | {
524 |
525 | ros::init(argc, argv, "spiri_go");
526 |
527 | SpiriGo go_thing;
528 |
529 | //wait until apm has connected to mavros
530 | /*while(!go_thing.isValid()) {
531 | ;
532 | }
533 | ROS_INFO("connected to mavros");*/
534 | //I found that the nodes not run in order has no effect
535 |
536 | //It's better to wait some time
537 | ros::Duration(2).sleep();
538 |
539 | //change stream rate, important
540 | while(!go_thing.setStreamRate(0, 10)) { //-all
541 | }
542 |
543 | ROS_INFO("set action server!");
544 |
545 | // start action servers
546 | go_thing.takeoff_as.start();
547 | go_thing.land_here_as.start();
548 |
549 | go_thing.Loop();
550 |
551 | return 0;
552 | }
553 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/spiri_go_client.cpp~:
--------------------------------------------------------------------------------
1 | /**
2 | * simpely takeoff and land
3 | */
4 |
5 | #include "ros/ros.h"
6 | #include
7 | #include
8 | #include
9 |
10 | int main(int argc, char **argv) {
11 | ros::init(argc, argv, "spiri_go_client");
12 |
13 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name
14 |
15 | ROS_INFO("Waiting for action server(takeOff) to start.");
16 |
17 | ac.waitForServer();
18 |
19 | ROS_INFO("Action server started--Taking off!");
20 |
21 | spiri_go::TakeoffGoal goal;
22 |
23 | //set the target height to take off!
24 | goal.height = 10;
25 | ac.sendGoal(goal);
26 |
27 | //wait for action(takeOff) to return
28 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
29 |
30 | if(is_takeOff_finished ) {
31 | ROS_INFO("reached target height!");
32 | }
33 | else {
34 | ROS_INFO("should set mode Land!");
35 | }
36 |
37 | return 0;
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/takeoff_and_land.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: takeoff_and_land.cpp
6 | *
7 | * Purpose: simpely takeoff and land for autonomous flights.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2015/12/24
11 | * @version 0.1.1 2016/03/16
12 | ******************************************************************************/
13 |
14 | #include "ros/ros.h"
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | int main(int argc, char **argv) {
21 | ros::init(argc, argv, "spiri_go_client");
22 |
23 | //It's better to wait sonme time, for this file has no NodeHandle, we should add ros::Time::init()
24 | ros::Time::init();
25 | ros::Duration(3).sleep();
26 |
27 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name, second param: true means a new thread
28 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
29 |
30 | ROS_INFO("Waiting for action server(takeOff) to start.");
31 |
32 | ac.waitForServer();
33 |
34 | ROS_INFO("Action server started--Taking off!");
35 |
36 | spiri_go::TakeoffGoal goal;
37 |
38 | //set the target height to take off!
39 | goal.height = 3;
40 | ac.sendGoal(goal);
41 |
42 | //wait for action(takeOff) to return
43 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
44 |
45 | if(is_takeOff_finished ) {
46 | ROS_INFO("reached target height!");
47 |
48 | //do something
49 | ros::Duration(20).sleep();
50 | }
51 | else {
52 | ROS_INFO("should set mode Land!");
53 | }
54 |
55 | //land
56 | ROS_INFO("Waiting for action server(land) to start.");
57 | ac1.waitForServer();
58 | ROS_INFO("Start to land!.");
59 |
60 | spiri_go::LandHereGoal goal_1;
61 | goal_1.height = 0;
62 | ac1.sendGoal(goal_1);
63 |
64 | //wait for action(land) to return
65 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
66 | if(is_land_finished ) {
67 | ROS_INFO("Land success!");
68 | }
69 |
70 | return 0;
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/takeoff_and_land.cpp~:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: takeoff_and_land.cpp
6 | *
7 | * Purpose: simpely takeoff and land for autonomous flights.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2015/12/24
11 | * @version 0.1.1 2016/03/16
12 | ******************************************************************************/
13 |
14 | #include "ros/ros.h"
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | int main(int argc, char **argv) {
21 | ros::init(argc, argv, "spiri_go_client");
22 |
23 | //It's better to wait sonme time, for this file has no NodeHandle, we should add ros::Time::init()
24 | ros::Time::init();
25 | ros::Duration(3).sleep();
26 |
27 | actionlib::SimpleActionClient ac("spiri_take_off", true); //first param: server name, second param: true means a new thread
28 | actionlib::SimpleActionClient ac1("spiri_land_here", true); //first param: server name, second param: false means not to use threads
29 |
30 | ROS_INFO("Waiting for action server(takeOff) to start.");
31 |
32 | ac.waitForServer();
33 |
34 | ROS_INFO("Action server started--Taking off!");
35 |
36 | spiri_go::TakeoffGoal goal;
37 |
38 | //set the target height to take off!
39 | goal.height = 3;
40 | ac.sendGoal(goal);
41 |
42 | //wait for action(takeOff) to return
43 | bool is_takeOff_finished = ac.waitForResult(ros::Duration(60.0));
44 |
45 | if(is_takeOff_finished ) {
46 | ROS_INFO("reached target height!");
47 |
48 | //do something
49 | ros::Duration(30).sleep();
50 | }
51 | else {
52 | ROS_INFO("should set mode Land!");
53 | }
54 |
55 | //land
56 | ROS_INFO("Waiting for action server(land) to start.");
57 | ac1.waitForServer();
58 | ROS_INFO("Start to land!.");
59 |
60 | spiri_go::LandHereGoal goal_1;
61 | goal_1.height = 0;
62 | ac1.sendGoal(goal_1);
63 |
64 | //wait for action(land) to return
65 | bool is_land_finished = ac1.waitForResult(ros::Duration(60.0));
66 | if(is_land_finished ) {
67 | ROS_INFO("Land success!");
68 | }
69 |
70 | return 0;
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/test/spiri_go_test.cpp:
--------------------------------------------------------------------------------
1 | // Bring in spiri_go's API
2 | #include "spiri_go.h"
3 | // Bring in gtest
4 | #include
5 |
6 | TEST(SpiriGoTests, Takeoff){
7 |
8 | }
9 |
10 | // Run all the tests that were declared with TEST()
11 | int main(int argc, char **argv){
12 | testing::InitGoogleTest(&argc, argv);
13 | return RUN_ALL_TESTS();
14 | }
15 |
--------------------------------------------------------------------------------
/multiDrone-ROS/spiri_go/src/test/test_com.cpp:
--------------------------------------------------------------------------------
1 |
2 | /*******************************************************************************
3 | * The Spiri Project
4 | *
5 | * File: leader.cpp
6 | *
7 | * Purpose: Formation control of leaders with collision avoidance using releative position.
8 | *
9 | * @author Peng Cheng
10 | * @version 0.1.0 2016/4/06
11 | ******************************************************************************/
12 |
13 | #include "ros/ros.h"
14 | #include
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 |
31 | #define R 6371000 //meter
32 | #define PI 3.1415926535898
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
40 | selfGlobalPos = *msg;
41 | }
42 |
43 | /*******************************************************************************
44 | * Callback function on the gps of the neighbour copter
45 | *
46 | * @param gpsPositionConstPtr& the gps callback pointer
47 | ******************************************************************************/
48 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
49 | {
50 | neigGlobalPos = *msg;
51 | }
52 |
53 | /*******************************************************************************
54 | * Main function
55 | *
56 | * @param
57 | ******************************************************************************/
58 | int main(int argc, char **argv) {
59 | ros::init(argc, argv, "spiri_go_client");
60 | ros::NodeHandle nh;
61 |
62 | ros::Rate loop_rate(10.0);
63 |
64 | // Subscriber to the Copter gps
65 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
66 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
67 |
68 | // Subscriber to the neighbour gps
69 | string neigGps_ = nh.resolveName("neighbour_position");
70 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
71 |
72 | //Publisher to the gps(toString)
73 | string gps_string_pub_ = nh.resolveName("serial_data_send");
74 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
75 |
76 | while(nh.ok()) {
77 | //1.publish self gps(toString)
78 | std_msgs::String gps_string;
79 | std::stringstream ss;
80 | //ss << "01o"<
15 | #include
16 | #include
17 | #include "spiri_go.h"
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 |
27 | //global variables
28 | sensor_msgs::NavSatFix selfGlobalPos; //self gps subscribed from mavros
29 | px4ros::gpsPosition neigGlobalPos; //neighbour gps subscribed from leader_control_decode.py
30 |
31 | #define R 6371000 //meter
32 | #define PI 3.1415926535898
33 |
34 | /*******************************************************************************
35 | * Callback function on the gps of the copter
36 | *
37 | * @param gpsPositionConstPtr& the gps callback pointer
38 | ******************************************************************************/
39 | void gpsSubCb(const sensor_msgs::NavSatFixConstPtr& msg){
40 | selfGlobalPos = *msg;
41 | }
42 |
43 | /*******************************************************************************
44 | * Callback function on the gps of the neighbour copter
45 | *
46 | * @param gpsPositionConstPtr& the gps callback pointer
47 | ******************************************************************************/
48 | void neigGpsSubCb(const px4ros::gpsPositionConstPtr& msg)
49 | {
50 | neigGlobalPos = *msg;
51 | }
52 |
53 | /*******************************************************************************
54 | * Main function
55 | *
56 | * @param
57 | ******************************************************************************/
58 | int main(int argc, char **argv) {
59 | ros::init(argc, argv, "spiri_go_client");
60 | ros::NodeHandle nh;
61 |
62 | ros::Rate loop_rate(10.0);
63 |
64 | // Subscriber to the Copter gps
65 | string gps_ = nh.resolveName("/mavros/global_position/raw/fix");
66 | ros::Subscriber gps = nh.subscribe(gps_, 5, gpsSubCb);
67 |
68 | // Subscriber to the neighbour gps
69 | string neigGps_ = nh.resolveName("neighbour_position");
70 | ros::Subscriber neigGps = nh.subscribe(neigGps_, 5, neigGpsSubCb);
71 |
72 | //Publisher to the gps(toString)
73 | string gps_string_pub_ = nh.resolveName("serial_data_send");
74 | ros::Publisher gps_string_pub = nh.advertise(gps_string_pub_, 5);
75 |
76 | while(nh.ok()) {
77 | //1.publish self gps(toString)
78 | std_msgs::String gps_string;
79 | std::stringstream ss;
80 | //ss << "01o"<
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 |
--------------------------------------------------------------------------------