Revision 7a6ed02d
ID | 7a6ed02d47f49de02afc7e0e8cc97db92054f38c |
Major changes in mikrokopter for lost connection
-In nav_lib.cpp, added main_loop, so we don't have to keep rewriting it
:). Also, this now publishes to /mk_wrapper/control, which should be
used from now on. However, old publish_on still works as it did.
-Changed turn_to_target and joystick_control (but not any others yet) to
use new nav_lib main_loop.
-Added mk_wrapper, which simply copies messages from /mk_wrapper/control
to /mikrokopter/req_set_control. After recieving the first message, if
it receives no message for a period of 200ms (rosparam max_quiet_time),
it will instead publish 0's and a thrust of 60, ignoring all future
input until restarted.
-Added launch files onboard.launch and joystick.launch, so that we
remember what should run where and can easily set some parameters.
mikrokopter/CMakeLists.txt | ||
---|---|---|
30 | 30 |
target_link_libraries(keyboard_control ncurses) |
31 | 31 |
rosbuild_add_executable(joystick_control src/joystick_control.cpp src/nav_lib.cpp) |
32 | 32 |
rosbuild_add_executable(turn_to_target src/turn_to_target.cpp src/nav_lib.cpp) |
33 |
rosbuild_add_executable(mk_wrapper src/mk_wrapper.cpp) |
mikrokopter/launch/joystick.launch | ||
---|---|---|
1 |
<launch> |
|
2 |
<node name="joy" pkg="joy" type="joy"> |
|
3 |
<param name="/dev/ttyACM0" /> |
|
4 |
</node> |
|
5 |
<node name="joystick_control" pkg="mikrokopter" type="joystick_control"> |
|
6 |
<!-- rate in Hz to publish Control messages --> |
|
7 |
<param name="publish_rate" value="20" /> |
|
8 |
</node> |
|
9 |
</launch> |
|
10 |
|
|
11 |
|
mikrokopter/launch/onboard.launch | ||
---|---|---|
1 |
<launch> |
|
2 |
<include file="$(find mikrokopter)/launch/mikrokopter.launch" /> |
|
3 |
<node name="mk_wrapper" pkg="mikrokopter" type="mk_wrapper"> |
|
4 |
<!-- if no Control message is received in this time in ms, go dead--> |
|
5 |
<param name="max_quiet_time" value="200" /> |
|
6 |
</node> |
|
7 |
</launch> |
mikrokopter/src/joystick_control.cpp | ||
---|---|---|
27 | 27 |
|
28 | 28 |
JoystickControl::JoystickControl() |
29 | 29 |
{ |
30 |
pub = n.advertise<mikrokopter::Control>("/mikrokopter/req_set_control", 100); |
|
31 | 30 |
sub = n.subscribe<sensor_msgs::Joy>("joy", 100, |
32 | 31 |
&JoystickControl::joyCallback, this); |
33 | 32 |
} |
34 | 33 |
|
35 | 34 |
void JoystickControl::joyLoop() |
36 | 35 |
{ |
37 |
ros::Rate loop_rate(25); |
|
38 |
while(ros::ok()) |
|
39 |
{ |
|
40 |
ros::spinOnce(); // if joyCallback is called, it will be in here |
|
41 |
control.publish_on(pub); |
|
42 |
loop_rate.sleep(); |
|
43 |
} |
|
44 |
return; |
|
36 |
control.main_loop(); |
|
45 | 37 |
} |
46 | 38 |
|
47 | 39 |
void JoystickControl::joyCallback(const sensor_msgs::Joy::ConstPtr& joy) |
mikrokopter/src/mk_wrapper.cpp | ||
---|---|---|
1 |
#include <ros/ros.h> |
|
2 |
#include <mikrokopter/Control.h> |
|
3 |
|
|
4 |
class MKWrapper |
|
5 |
{ |
|
6 |
public: |
|
7 |
MKWrapper(); |
|
8 |
void main_loop(); |
|
9 |
void control_callback(const mikrokopter::Control& control); |
|
10 |
|
|
11 |
private: |
|
12 |
ros::Publisher pub; |
|
13 |
ros::Subscriber sub; |
|
14 |
ros::NodeHandle nh; |
|
15 |
ros::Duration max_quiet_time; |
|
16 |
ros::Time last_time_recv; |
|
17 |
bool started, dead; |
|
18 |
}; |
|
19 |
|
|
20 |
MKWrapper::MKWrapper() |
|
21 |
{ |
|
22 |
pub = nh.advertise<mikrokopter::Control>("/mikrokopter/req_set_control", |
|
23 |
100); |
|
24 |
sub = nh.subscribe("/mk_wrapper/control", 100, &MKWrapper::control_callback, |
|
25 |
this); |
|
26 |
int max_quiet_time_ms; |
|
27 |
ros::param::param<int>("max_quiet_time", max_quiet_time_ms, 100); |
|
28 |
max_quiet_time.fromSec(max_quiet_time_ms / 1000.); |
|
29 |
started = false; |
|
30 |
dead = false; |
|
31 |
} |
|
32 |
|
|
33 |
void MKWrapper::main_loop() |
|
34 |
{ |
|
35 |
mikrokopter::Control control_dead; |
|
36 |
control_dead.pitch = 0; |
|
37 |
control_dead.roll = 0; |
|
38 |
control_dead.yaw = 0; |
|
39 |
control_dead.thrust = 60; |
|
40 |
|
|
41 |
ros::Rate loop_rate(20); |
|
42 |
while (ros::ok()) |
|
43 |
{ |
|
44 |
if (started) |
|
45 |
{ |
|
46 |
if (dead) |
|
47 |
{ |
|
48 |
pub.publish(control_dead); |
|
49 |
} |
|
50 |
else if (ros::Time::now() - last_time_recv > max_quiet_time) |
|
51 |
{ |
|
52 |
dead = true; |
|
53 |
ROS_ERROR("Lost connection: mk_wrapper must be restarted"); |
|
54 |
} |
|
55 |
} |
|
56 |
loop_rate.sleep(); |
|
57 |
ros::spinOnce(); |
|
58 |
} |
|
59 |
} |
|
60 |
|
|
61 |
void MKWrapper::control_callback(const mikrokopter::Control& control) |
|
62 |
{ |
|
63 |
started = true; |
|
64 |
if (!dead) |
|
65 |
{ |
|
66 |
pub.publish(control); |
|
67 |
last_time_recv = ros::Time::now(); |
|
68 |
} |
|
69 |
} |
|
70 |
|
|
71 |
int main(int argc, char **argv) |
|
72 |
{ |
|
73 |
ros::init(argc, argv, "mk_wrapper"); |
|
74 |
MKWrapper wrapper; |
|
75 |
wrapper.main_loop(); |
|
76 |
return 0; |
|
77 |
} |
mikrokopter/src/nav_lib.cpp | ||
---|---|---|
1 | 1 |
#include "nav_lib.h" |
2 | 2 |
|
3 |
|
|
4 | 3 |
MikrokopterControl::MikrokopterControl() |
5 | 4 |
{ |
6 | 5 |
control.digital[0] = 0; |
... | ... | |
70 | 69 |
pub.publish(control); |
71 | 70 |
} |
72 | 71 |
|
72 |
void MikrokopterControl::main_loop() |
|
73 |
{ |
|
74 |
ros::Publisher pub = nh.advertise< ::mikrokopter::Control>( |
|
75 |
"/mk_wrapper/control", 200); |
|
76 |
|
|
77 |
int publish_rate; |
|
78 |
ros::param::param<int>("publish_rate", publish_rate, 20); |
|
79 |
ros::Rate loop_rate(publish_rate); |
|
80 |
|
|
81 |
while (ros::ok()) |
|
82 |
{ |
|
83 |
ros::spinOnce(); |
|
84 |
pub.publish(control); |
|
85 |
loop_rate.sleep(); |
|
86 |
} |
|
87 |
|
|
88 |
} |
mikrokopter/src/nav_lib.h | ||
---|---|---|
13 | 13 |
void set_thrust(float thrust); |
14 | 14 |
void set_yaw(float yaw); |
15 | 15 |
void publish_on(ros::Publisher& pub); |
16 |
void main_loop(); |
|
16 | 17 |
private: |
17 | 18 |
mikrokopter::Control control; |
19 |
ros::NodeHandle nh; |
|
18 | 20 |
}; |
mikrokopter/src/turn_to_target.cpp | ||
---|---|---|
18 | 18 |
|
19 | 19 |
TurnToTarget::TurnToTarget() |
20 | 20 |
{ |
21 |
pub = n.advertise<mikrokopter::Control>("/mikrokopter/req_set_control", 100); |
|
21 |
//pub = n.advertise<mikrokopter::Control>("/mikrokopter/req_set_control", 100);
|
|
22 | 22 |
sub = n.subscribe<geometry_msgs::Point>("/v2v3_converter/target_3d", 100, |
23 | 23 |
&TurnToTarget::pointCallback, this); |
24 | 24 |
} |
25 | 25 |
|
26 | 26 |
void TurnToTarget::mainLoop() |
27 | 27 |
{ |
28 |
ros::Rate loop_rate(25); |
|
28 |
/*ros::Rate loop_rate(25);
|
|
29 | 29 |
while(ros::ok()) |
30 | 30 |
{ |
31 | 31 |
ros::spinOnce(); |
32 | 32 |
control.publish_on(pub); |
33 | 33 |
loop_rate.sleep(); |
34 |
} |
|
34 |
}*/ |
|
35 |
control.main_loop(); |
|
35 | 36 |
} |
36 | 37 |
|
37 | 38 |
void TurnToTarget::pointCallback(const geometry_msgs::Point::ConstPtr& p) |
Also available in: Unified diff