View difference between Paste ID: VtfpM6Yk and CTCJtdvK
SHOW: | | - or go back to the newest paste.
1
Send goal to robot 
2
----------------
3
#include <ros/ros.h>
4
#include <move_base_msgs/MoveBaseAction.h>
5
#include <actionlib/client/simple_action_client.h>
6
#include <trsimcpp/threadsafe_stack_wrapper.h>
7
#include <future>         // std::async, std::future
8
// Initialize stack with -1 error value
9
threadsafe_stack<int> mystack(-1,1);
10
11
typedef actionlib::SimpleActionClient<move_base_msgs::MoveBaseAction> MoveBaseClient;
12
13
void sendgoal(std::string robot_name)
14
{
15
    //tell the action client that we want to spin a thread by default
16
17
    MoveBaseClient ac("/" +  robot_name + "/move_base", true);
18
19
    //wait for the action server to come up
20
    while(!ac.waitForServer(ros::Duration(5.0))){
21
      ROS_INFO("Waiting for the move_base action server to come up");
22
    }
23
24
    move_base_msgs::MoveBaseGoal goal;
25
26
    //we'll send a goal to the robot to move 1 meter forward
27
    goal.target_pose.header.frame_id = "map";
28
    goal.target_pose.header.stamp = ros::Time::now();
29
30
    goal.target_pose.pose.position.x = 3.0;
31
    goal.target_pose.pose.orientation.w = 1.0;
32
33
    ROS_INFO("Sending goal");
34
    ac.sendGoal(goal);
35
36
    ac.waitForResult();
37
38
    if(ac.getState() == actionlib::SimpleClientGoalState::SUCCEEDED)
39
      ROS_INFO("Status:1");
40
    else
41
      ROS_INFO("Status:0");
42
43
}
44
45
46
int main(int argc, char** argv){
47
  ros::init(argc, argv, "simple_navigation_goals");
48
  // Hold an election
49
  auto f1 = std::async(std::launch::async,pop);
50
  auto f2 = std::async(std::launch::async,pop);
51
52
53
      if(f1.get() != -1)
54
      {
55
           std::cout <<"robot 1 won!\n";
56
           sendgoal("robot1");
57
      }
58
      else
59
      {
60
          std::cout<<"robot 2 won!\n";
61
          sendgoal("robot2");
62
      }
63
64
65
66
  return 0;
67-
}
67+
68
69
70
===========
71
72
#ifndef THREADSAFE_STACK_H
73
#define THREADSAFE_STACK_H
74
#include <stack>
75
#include <mutex>
76
#include <memory>
77
#include <algorithm>
78
#include <cassert>
79
80
/*
81
This stack can contain at max 1 element, pushed at the time of creation.
82
One item can be popped, after which EMPTY_STACK error is returned. 
83
*/
84
85
86
template<typename T>
87
class threadsafe_stack
88
{
89
	public:
90
	
91
	threadsafe_stack(T EMPTY_STACK_, T initval):EMPTY_STACK(EMPTY_STACK_) 
92
	{ 
93
		std::lock_guard<std::mutex> lock(m);		
94
		data.push(initval);
95
	}
96
97
	threadsafe_stack(const threadsafe_stack &other): EMPTY_STACK(other.EMPTY_STACK)
98
	{
99
		// From Williams' book
100
		std::lock_guard<std::mutex> lock2(other.m);
101
		assert (other.data.size() == 1);
102
		data.push(other.data.top());		
103
	}
104
	
105
	threadsafe_stack& operator = (const threadsafe_stack&) = delete;
106
107
	T pop()
108
	{
109
		std::lock_guard<std::mutex> lock(m);
110
		T rv = EMPTY_STACK;
111
		if(!data.empty())
112
		{
113
			rv = data.top();		
114
			data.pop();
115
		}
116
		return rv;		
117
	}	
118
119
120
121
	private:
122
	std::stack<T> data;
123
	mutable std::mutex m;	
124
	const T EMPTY_STACK;
125
};