panoramic_view_recorder.cpp
Go to the documentation of this file.
1 // Copyright 1996-2020 Cyberbotics Ltd.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include <signal.h>
16 #include "ros/ros.h"
17 
18 #include <webots_ros/get_bool.h>
19 #include <webots_ros/get_int.h>
20 #include <webots_ros/get_uint64.h>
21 #include <webots_ros/set_int.h>
22 
23 #include <webots_ros/field_get_node.h>
24 #include <webots_ros/field_get_rotation.h>
25 #include <webots_ros/field_get_type_name.h>
26 #include <webots_ros/field_get_vec3f.h>
27 #include <webots_ros/field_set_rotation.h>
28 #include <webots_ros/field_set_vec3f.h>
29 #include <webots_ros/node_get_field.h>
30 #include <webots_ros/supervisor_movie_start_recording.h>
31 #include <webots_ros/supervisor_set_label.h>
32 
33 #include <std_msgs/String.h>
34 
35 #define TIME_STEP 32
36 
37 static int controllerCount;
38 static std::vector<std::string> controllerList;
39 
41 webots_ros::set_int timeStepSrv;
42 
43 // catch names of the controllers available on ROS network
44 void controllerNameCallback(const std_msgs::String::ConstPtr &name) {
46  controllerList.push_back(name->data);
47  ROS_INFO("Controller #%d: %s.", controllerCount, controllerList.back().c_str());
48 }
49 
50 void quit(int sig) {
51  timeStepSrv.request.value = 0;
52  timeStepClient.call(timeStepSrv);
53  ROS_INFO("User stopped the 'panoramic_view_recorder' node.");
54  ros::shutdown();
55  exit(0);
56 }
57 
58 int main(int argc, char **argv) {
59  std::string controllerName;
60 
61  // create a node named 'panoramic_view_recorder' on ROS network
62  ros::init(argc, argv, "panoramic_view_recorder", ros::init_options::AnonymousName);
64 
65  signal(SIGINT, quit);
66 
67  // subscribe to the topic model_name to get the list of availables controllers
68  ros::Subscriber nameSub = n.subscribe("model_name", 100, controllerNameCallback);
69  while (controllerCount == 0 || controllerCount < nameSub.getNumPublishers()) {
70  ros::spinOnce();
71  ros::spinOnce();
72  ros::spinOnce();
73  }
74  ros::spinOnce();
75 
76  // if there is more than one controller available, let the user choose
77  if (controllerCount == 1)
78  controllerName = controllerList[0];
79  else {
80  int wantedController = 0;
81  std::cout << "Choose the # of the controller you want to use:\n";
82  std::cin >> wantedController;
83  if (1 <= wantedController && wantedController <= controllerCount)
84  controllerName = controllerList[wantedController - 1];
85  else {
86  ROS_ERROR("Invalid number for controller choice.");
87  return 1;
88  }
89  }
90  // leave topic once it's not necessary anymore
91  nameSub.shutdown();
92 
93  timeStepClient = n.serviceClient<webots_ros::set_int>(controllerName + "/robot/time_step");
94  timeStepSrv.request.value = TIME_STEP;
95 
96  ROS_INFO("Welcome to the panoramic_view_recorder example.");
97  ROS_INFO("This node will connect to a supervisor in Webots and access world to record a panoramic movie around a nao robot.");
98 
99  // get world node
100  ros::ServiceClient getWorldClient = n.serviceClient<webots_ros::get_uint64>(controllerName + "/supervisor/get_root");
101  webots_ros::get_uint64 getWorldSrv;
102  getWorldClient.call(getWorldSrv);
103 
104  // get children list
105  ros::ServiceClient getWorldChildrenClient =
106  n.serviceClient<webots_ros::node_get_field>(controllerName + "/supervisor/node/get_field");
107  webots_ros::node_get_field getWorldChildrenSrv;
108  getWorldChildrenSrv.request.node = getWorldSrv.response.value;
109  getWorldChildrenSrv.request.fieldName = "children";
110  getWorldChildrenClient.call(getWorldChildrenSrv);
111 
112  // get POV(Point Of View) node
113  ros::ServiceClient getPovClient = n.serviceClient<webots_ros::field_get_node>(controllerName + "/supervisor/field/get_node");
114  webots_ros::field_get_node getPovSrv;
115  getPovSrv.request.field = getWorldChildrenSrv.response.field;
116  getPovSrv.request.index = 1;
117  getPovClient.call(getPovSrv);
118 
119  // get POV position and orientation
120  ros::ServiceClient getPovPositionFieldClient =
121  n.serviceClient<webots_ros::node_get_field>(controllerName + "/supervisor/node/get_field");
122  webots_ros::node_get_field getPovPositionFieldSrv;
123  getPovPositionFieldSrv.request.node = getPovSrv.response.node;
124  getPovPositionFieldSrv.request.fieldName = "position";
125  getPovPositionFieldClient.call(getPovPositionFieldSrv);
126 
127  ros::ServiceClient getPositionClient =
128  n.serviceClient<webots_ros::field_get_vec3f>(controllerName + "/supervisor/field/get_vec3f");
129  webots_ros::field_get_vec3f getPovPositionSrv;
130  getPovPositionSrv.request.field = getPovPositionFieldSrv.response.field;
131  getPositionClient.call(getPovPositionSrv);
132  geometry_msgs::Vector3 initialPovPosition = getPovPositionSrv.response.value;
133 
134  ros::ServiceClient getPovOrientationFieldClient =
135  n.serviceClient<webots_ros::node_get_field>(controllerName + "/supervisor/node/get_field");
136  webots_ros::node_get_field getPovOrientationFieldSrv;
137  getPovOrientationFieldSrv.request.node = getPovSrv.response.node;
138  getPovOrientationFieldSrv.request.fieldName = "orientation";
139  getPovOrientationFieldClient.call(getPovOrientationFieldSrv);
140 
141  ros::ServiceClient getPovOrientationClient =
142  n.serviceClient<webots_ros::field_get_rotation>(controllerName + "/supervisor/field/get_rotation");
143  webots_ros::field_get_rotation getPovOrientationSrv;
144  getPovOrientationSrv.request.field = getPovOrientationFieldSrv.response.field;
145  getPovOrientationClient.call(getPovOrientationSrv);
146  geometry_msgs::Quaternion povOrientation = getPovOrientationSrv.response.value;
147 
148  ROS_INFO("Initial position of point of view is %f %f %f and its orientation is %f %f %f %f.", initialPovPosition.x,
149  initialPovPosition.y, initialPovPosition.z, povOrientation.x, povOrientation.y, povOrientation.z, povOrientation.w);
150 
151  timeStepClient.call(timeStepSrv);
152 
153  // initialize services to update POV position and orientation
154  ros::ServiceClient setPositionClient =
155  n.serviceClient<webots_ros::field_set_vec3f>(controllerName + "/supervisor/field/set_vec3f");
156  webots_ros::field_set_vec3f setPovPositionSrv;
157  setPovPositionSrv.request.field = getPovPositionFieldSrv.response.field;
158  setPovPositionSrv.request.value = initialPovPosition;
159 
160  ros::ServiceClient setPovOrientationClient =
161  n.serviceClient<webots_ros::field_set_rotation>(controllerName + "/supervisor/field/set_rotation");
162  webots_ros::field_set_rotation setPovOrientationSrv;
163  setPovOrientationSrv.request.field = getPovOrientationFieldSrv.response.field;
164  setPovOrientationSrv.request.value = povOrientation;
165 
166  // set label to 'Recording'
167  ros::ServiceClient supervisorSetLabelClient;
168  webots_ros::supervisor_set_label supervisorSetLabelSrv;
169  supervisorSetLabelClient = n.serviceClient<webots_ros::supervisor_set_label>(controllerName + "/supervisor/set_label");
170 
171  supervisorSetLabelSrv.request.id = 1;
172  supervisorSetLabelSrv.request.label = "Recording";
173  supervisorSetLabelSrv.request.xpos = 0.02;
174  supervisorSetLabelSrv.request.ypos = 0.1;
175  supervisorSetLabelSrv.request.size = 0.2;
176  supervisorSetLabelSrv.request.color = 0XFF0000;
177  supervisorSetLabelSrv.request.transparency = 0;
178  supervisorSetLabelSrv.request.font = "Tahoma";
179  if (!supervisorSetLabelClient.call(supervisorSetLabelSrv) || supervisorSetLabelSrv.response.success != 1)
180  ROS_ERROR("Failed to call service set_label.");
181 
182  // start_movie
183  ros::ServiceClient supervisorMovieStartClient;
184  webots_ros::supervisor_movie_start_recording supervisorMovieStartSrv;
185  supervisorMovieStartClient =
186  n.serviceClient<webots_ros::supervisor_movie_start_recording>(controllerName + "/supervisor/movie_start_recording");
187 
188  supervisorMovieStartSrv.request.filename = std::string(getenv("HOME")) + std::string("/supervisor_movie.mp4");
189  supervisorMovieStartSrv.request.width = 480;
190  supervisorMovieStartSrv.request.height = 360;
191  supervisorMovieStartSrv.request.codec = 1337;
192  supervisorMovieStartSrv.request.quality = 100;
193  supervisorMovieStartSrv.request.acceleration = 1;
194  supervisorMovieStartSrv.request.caption = false;
195  if (supervisorMovieStartClient.call(supervisorMovieStartSrv) && supervisorMovieStartSrv.response.success == 1)
196  ROS_INFO("Movie started recording.");
197  else
198  ROS_ERROR("Failed to call service movie_start_recording.");
199 
200  double angle = 0.0;
201  while (angle < 6.28) { // we start at angle 0 and end at angle 2*pi
202  angle += 0.05;
203  setPovOrientationSrv.request.value.w = cos(0.5 * angle);
204  setPovOrientationSrv.request.value.y = sin(0.5 * angle);
205  double cosAngle = cos(angle);
206  double sinAngle = sin(angle);
207  if (setPovOrientationClient.call(setPovOrientationSrv) && setPovOrientationSrv.response.success == 1) {
208  setPovPositionSrv.request.value.x = initialPovPosition.z * sinAngle;
209  setPovPositionSrv.request.value.z = initialPovPosition.z * cosAngle;
210  if (setPositionClient.call(setPovPositionSrv) && setPovPositionSrv.response.success == 1) {
211  if (!timeStepClient.call(timeStepSrv) || !timeStepSrv.response.success)
212  ROS_ERROR("Couldn't update robot step.");
213  } else
214  ROS_ERROR("Failed to send new point of view position.");
215  } else
216  ROS_ERROR("Failed to send new point of view orientation.");
217  }
218 
219  // stop_movie
220  ros::ServiceClient supervisorMovieStopClient;
221  webots_ros::get_bool supervisorMovieStopSrv;
222  supervisorMovieStopClient = n.serviceClient<webots_ros::get_bool>(controllerName + "/supervisor/movie_stop_recording");
223 
224  if (supervisorMovieStopClient.call(supervisorMovieStopSrv) && supervisorMovieStopSrv.response.value)
225  ROS_INFO("Movie stopped recording.");
226  else
227  ROS_ERROR("Failed to call service movie_stop_recording.");
228 
229  supervisorSetLabelSrv.request.label = "";
230  supervisorSetLabelClient.call(supervisorSetLabelSrv);
231 
232  timeStepSrv.request.value = 0;
233  timeStepClient.call(timeStepSrv);
234 }
ServiceClient serviceClient(const std::string &service_name, bool persistent=false, const M_string &header_values=M_string())
#define TIME_STEP
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
ros::ServiceClient timeStepClient
ROSCPP_DECL void init(int &argc, char **argv, const std::string &name, uint32_t options=0)
bool call(MReq &req, MRes &res)
static std::string controllerName
void quit(int sig)
void controllerNameCallback(const std_msgs::String::ConstPtr &name)
TFSIMD_FORCE_INLINE tfScalar angle(const Quaternion &q1, const Quaternion &q2)
ros::NodeHandle * n
Definition: pioneer3at.cpp:40
static std::vector< std::string > controllerList
static int controllerCount
#define ROS_INFO(...)
uint32_t getNumPublishers() const
int main(int argc, char **argv)
ROSCPP_DECL void shutdown()
ROSCPP_DECL void spinOnce()
#define ROS_ERROR(...)
webots_ros::set_int timeStepSrv


webots_ros
Author(s): Cyberbotics
autogenerated on Fri Sep 4 2020 03:55:03