ROS_node.cpp
Go to the documentation of this file.
1 
9 #include <ros/ros.h>
10 #include <geometry_msgs/Twist.h> // Publication format
11 #include <sstream>
12 #include <model/ROS_node.hpp>
13 
14 
15 // Stops ROS if it has been started.
16 // See ROS Namespace, QThread.
17 void ROSnode::end() {
18  if ( connected() ) {
20  if ( ros::isStarted() ) {
21  ros::shutdown(); // stops ROS, and thus the run() method
22  ros::waitForShutdown(); // waits for ROS to stop
23  }
24  wait(); // waits for the run() method (other thread) to stop
25  motion_ctrl = NULL;
26  } // end of if (connected)
27 } // end of ROSnode::~ROSnode() --------------------------------------
28 
29 /* Common part of the two initialisation methods
30  * Parameter: ctrl the motion controller.
31  * See ROS Namespace, ROS::Publisher, QThread,
32  * init(), init(const std::string&, const std::string&).
33  */
35  if ( ros::master::check() ) {
36  motion_ctrl = &ctrl;
37  ros::NodeHandle nh;
38  // explicitly needed since our nodehandle is going out of scope
39  ros::start(); /* DOES NOT WORK (started too late)
40  // getting param values does not work well (yet)
41  nh.param<std::string>("void_world_cmd", world_command_file[0],
42  "launch_empty_world.sh");
43  nh.param<std::string>("other_world_cmd", world_command_file[1],
44  "launch_world.sh");
45  world_command_file[0] = "launch_empty_world.sh";
46  world_command_file[1] = "launch_world.sh";
47  log(Info, "=== Got '" + world_command_file[0] +
48  "' as void world command ===");
49  log(Info, "=== Got '" + world_command_file[1] +
50  "' as other world command ==="); */
51  // set the publisher used to send the commands (velocities)
52  cmd_publisher = nh.advertise<geometry_msgs::Twist>("vel_cmd", 10);
53  // subscrive to the odometry topic,
54  // and start new_odom method with each new data
55  odom_subscriber = nh.subscribe("odometry", 1000,
56  &ROSnode::newOdometry, this);
57  start(); // starts the process, and calls run()
58  } // end of if (is_connected)
59 } // end of void ROSnode::ROSsetup() ---------------------------------
60 
61 // Sends the odometry data to the controller.
62 // Parameter: odom the new odometry data.
63 // See Controller::newState().
64 void ROSnode::newOdometry(const nav_msgs::Odometry::ConstPtr& odom) {
65  const ros::Time& t = odom->header.stamp;
66  const double date = t.sec + 1E-9 * t.nsec;
67  static const double initial_date = date;
68  const geometry_msgs::Pose& pose = odom->pose.pose;
69  const geometry_msgs::Point& point = pose.position;
70  const geometry_msgs::Quaternion& orient = pose.orientation;
71  const tf::Quaternion tfQuat(orient.x, orient.y, orient.z, orient.w);
72  const tf::Matrix3x3 tfMatrix(tfQuat);
73  const geometry_msgs::Twist& twist = odom->twist.twist;
74  double roll, pitch, yaw;
75  tfMatrix.getRPY(roll, pitch, yaw);
76  const State
77  state(date - initial_date,
78  iSeeML::rob::OrPtConfig(iSeeML::geom::Point(point.x, point.y),
79  yaw), twist.linear.x, twist.angular.z);
80  motion_ctrl->newState(state);
81 } // end of void ROSnode::newOdometry(const nav_msgs:...:ConstPtr&) --
82 
83 /* Main loop of the process (in a separate thread).
84  *
85  * See QThread, ROS::Rate, stop(), geometry_msgs::Twist,
86  * ROS Namespace, log(const LogLevel&, const std::string&),
87  * ROS::Publisher, ROSshutdown().
88  */
89 void ROSnode::run() {
90  if ( connected() ) {
91  const double loop_frequ = 1 / motion_ctrl->timeStep();
92  // defined from input stream, if any
93  ros::Rate loop_rate(loop_frequ);
94  geometry_msgs::Twist vel;
95 
96  motion_ctrl->stopMotion(); // Sets the velocities to zero.
97  while ( ros::ok() ) {
98  std::ostringstream log_msg;
99  motion_ctrl->chooseVelocities(vel.linear.x, vel.angular.z,
100  log_msg);
101  log( Info, log_msg.str() );
102  cmd_publisher.publish(vel); // publish the commands
103  // spin ROS once, and wait for next time step
104  ros::spinOnce();
105  loop_rate.sleep();
106  } // end of while (ROS OK)
107  } // end of if (connected)
108 } // end of void ROSnode::run() --------------------------------------
109 
110 /* Connects to ROS server with parameters.
111  *
112  * Parameters: master_url the URI of the ROS master,
113  * host_url the URI of the host,
114  * ctrl the motion controller.
115  *
116  * See ROS Namespace, ROSsetup().
117  */
118 void ROSnode::init(const std::string &master_url,
119  const std::string &host_url, Controller& ctrl) {
120  std::map<std::string,std::string> remappings;
121  remappings["__master"] = master_url;
122  remappings["__hostname"] = host_url;
123  ros::init(remappings,"qt_ctrl");
124  ROSsetup(ctrl);
125 } // end of void ROSnode::init(const std::string&, ..., Controller&) -
126 
127 /* Writes a message at given level in the log.
128  *
129  * Parameters: level the log's severity level,
130  * msg the message.
131  *
132  * See ROS::console, ROS::Time, QStringListModel,
133  * connected(), loggingModel(), loggingUpdated().
134  */
135 void ROSnode::log(const LogLevel &level, const std::string &msg) {
136  static const char* levelName[Count] =
137  {"DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
138  std::stringstream log_model_msg;
139 
140  if ( connected() && (level < Count) && ( !msg.empty() ) ) {
141  // fills ROS log at the requested level
142  ROS_LOG_STREAM(level, ROSCONSOLE_DEFAULT_NAME, msg);
143  // change the GUI log: insert a line in the GUI log
144  log_model.insertRows(log_model.rowCount(),1);
145  // write the formated (add level and date) message
146  log_model_msg << "[" << levelName[(int)(level)] << "] ["
147  << ros::Time::now() << "]: " << msg;
148  // transform the string stream into a QVariant (= union)
149  QVariant new_row( QString( log_model_msg.str().c_str() ) );
150  // add it as the last line of the log
151  log_model.setData(log_model.index(log_model.rowCount()-1), new_row);
152  Q_EMIT loggingUpdated(); // ask the GUI to show its log
153  } // end of if (connected, valid level & message non empty)
154 } // end of void ROSnode::log(const LogLevel&, const std::string &) --
ros::Subscriber odom_subscriber
ROS object used to get the odometry.
Definition: ROS_node.hpp:71
void stopMotion()
Stops the robot (i.e. sets both velocities to zero).
Definition: controller.hpp:99
Controller is the abstract class inherited by all the implemented controllers.
Definition: controller.hpp:28
ROS communication node.
::ros::console::Level LogLevel
Log severity levels, comming from ROS::console.
Definition: ROS_node.hpp:112
void init(Controller &ctrl)
Connects to ROS server with main arguments.
Definition: ROS_node.hpp:141
void loggingUpdated()
Signals the GUI for log&#39;s update.
QStringListModel log_model
Qt object used to show the logs in the GUI.
Definition: ROS_node.hpp:78
void newOdometry(const nav_msgs::Odometry::ConstPtr &odom)
Sends the odometry data to the controller.
Definition: ROS_node.cpp:64
virtual void newState(const State &state)
Handles new state of the robot.
Definition: controller.cpp:16
const double & timeStep() const
Stops the robot (i.e. sets both velocities to zero).
Definition: controller.hpp:88
This class defines a state, i.e. a configuration and its (translation and rotation) velocities...
Definition: state.hpp:22
Controller * motion_ctrl
A pointer to the controller of the motion.
Definition: ROS_node.hpp:54
bool connected() const
Indicates whether the node is connected to ROS.
Definition: ROS_node.hpp:135
void ROSsetup(Controller &ctrl)
Common part of the two initialisation methods.
Definition: ROS_node.cpp:34
virtual void chooseVelocities(double &trans_vel, double &rot_vel, std::ostream &log_str)=0
Computes new velocities for ROS node.
void log(const LogLevel &level, const std::string &msg)
Writes a message at given level in the log.
Definition: ROS_node.cpp:135
void run()
Main loop of the process (on a separate thread).
Definition: ROS_node.cpp:89
ros::Publisher cmd_publisher
ROS object used to send the velocities.
Definition: ROS_node.hpp:60
void end()
Stops ROS if it has been started.
Definition: ROS_node.cpp:17


qt_ctrl
Author(s): Alexis Scheuer
autogenerated on Wed Dec 16 2020 15:51:32