WATANABE Aoi 2022-12-14
Merge pull request #21 from HarvestX/fix/twist-node
add watchdog and fix format
@c1457a97955f00de7463938cc450bc4f686e0e50
 
.vscode/cmake-format (deleted)
--- .vscode/cmake-format
@@ -1,70 +0,0 @@
-# -----------------------------
-# Options effecting formatting.
-# -----------------------------
-with section("format"):
-    line_width = 80
-    tab_size = 2
-    use_tabchars = False
-    fractional_tab_policy = 'round-up'
-    separate_ctrl_name_with_space = False
-    separate_fn_name_with_space = False
-    dangle_parens = True
-    dangle_align = 'prefix'
-    enable_sort = True
-
-# ----------------------------
-# Options affecting the linter
-# ----------------------------
-with section("lint"):
-
-    # a list of lint codes to disable
-    disabled_codes = ['C0113']
-
-    # regular expression pattern describing valid function names
-    function_pattern = '[0-9a-z_]+'
-
-    # regular expression pattern describing valid macro names
-    macro_pattern = '[0-9A-Z_]+'
-
-    # regular expression pattern describing valid names for variables with global
-    # (cache) scope
-    global_var_pattern = '[A-Z][0-9A-Z_]+'
-
-    # regular expression pattern describing valid names for variables with global
-    # scope (but internal semantic)
-    internal_var_pattern = '_[A-Z][0-9A-Z_]+'
-
-    # regular expression pattern describing valid names for variables with local
-    # scope
-    local_var_pattern = '[a-z][a-z0-9_]+'
-
-    # regular expression pattern describing valid names for privatedirectory
-    # variables
-    private_var_pattern = '_[0-9a-z_]+'
-
-    # regular expression pattern describing valid names for public directory
-    # variables
-    public_var_pattern = '[A-Z][0-9A-Z_]+'
-
-    # regular expression pattern describing valid names for function/macro
-    # arguments and loop variables.
-    argument_var_pattern = '[a-z][a-z0-9_]+'
-
-    # regular expression pattern describing valid names for keywords used in
-    # functions or macros
-    keyword_pattern = '[A-Z][0-9A-Z_]+'
-
-    # In the heuristic for C0201, how many conditionals to match within a loop in
-    # before considering the loop a parser.
-    max_conditionals_custom_parser = 2
-
-    # Require at least this many newlines between statements
-    min_statement_spacing = 1
-
-    # Require no more than this many newlines between statements
-    max_statement_spacing = 2
-    max_returns = 6
-    max_branches = 12
-    max_arguments = 5
-    max_localvars = 15
-    max_statements = 50
.vscode/cspell.json
--- .vscode/cspell.json
+++ .vscode/cspell.json
@@ -12,6 +12,7 @@
     "rclcpp",
     "roboteq",
     "rosdistro",
+    "rosidl",
     "rviz",
     "teleop",
     "urdf",
.vscode/settings.json
--- .vscode/settings.json
+++ .vscode/settings.json
@@ -18,87 +18,6 @@
   "uncrustify.configPath.linux": ".vscode/uncrustify.cfg",
   "xml.format.splitAttributes": true,
   "editor.formatOnSave": true,
-  "cmakeFormat.args": [
-    "--config-file",
-    ".vscode/cmake-format"
-  ],
   "python.linting.enabled": true,
   "python.linting.flake8Enabled": true,
-  "files.associations": {
-    "*.ui": "xml",
-    "qapplication": "cpp",
-    "chrono": "cpp",
-    "cctype": "cpp",
-    "clocale": "cpp",
-    "cmath": "cpp",
-    "csignal": "cpp",
-    "cstddef": "cpp",
-    "cstdio": "cpp",
-    "cstdlib": "cpp",
-    "cstring": "cpp",
-    "ctime": "cpp",
-    "cwchar": "cpp",
-    "array": "cpp",
-    "atomic": "cpp",
-    "*.tcc": "cpp",
-    "condition_variable": "cpp",
-    "cstdint": "cpp",
-    "list": "cpp",
-    "unordered_map": "cpp",
-    "unordered_set": "cpp",
-    "vector": "cpp",
-    "exception": "cpp",
-    "algorithm": "cpp",
-    "functional": "cpp",
-    "iterator": "cpp",
-    "map": "cpp",
-    "memory": "cpp",
-    "memory_resource": "cpp",
-    "optional": "cpp",
-    "random": "cpp",
-    "ratio": "cpp",
-    "set": "cpp",
-    "string": "cpp",
-    "string_view": "cpp",
-    "system_error": "cpp",
-    "tuple": "cpp",
-    "type_traits": "cpp",
-    "utility": "cpp",
-    "future": "cpp",
-    "initializer_list": "cpp",
-    "iosfwd": "cpp",
-    "iostream": "cpp",
-    "istream": "cpp",
-    "limits": "cpp",
-    "mutex": "cpp",
-    "new": "cpp",
-    "ostream": "cpp",
-    "shared_mutex": "cpp",
-    "sstream": "cpp",
-    "stdexcept": "cpp",
-    "streambuf": "cpp",
-    "thread": "cpp",
-    "cinttypes": "cpp",
-    "typeindex": "cpp",
-    "typeinfo": "cpp",
-    "variant": "cpp",
-    "bit": "cpp",
-    "cstdarg": "cpp",
-    "cwctype": "cpp",
-    "bitset": "cpp",
-    "codecvt": "cpp",
-    "complex": "cpp",
-    "deque": "cpp",
-    "forward_list": "cpp",
-    "numeric": "cpp",
-    "fstream": "cpp",
-    "iomanip": "cpp",
-    "*.ipp": "cpp",
-    "core": "cpp",
-    "strstream": "cpp",
-    "cfenv": "cpp",
-    "valarray": "cpp",
-    "any": "cpp",
-    "regex": "cpp"
-  }
 }
(파일 끝에 줄바꿈 문자 없음)
p9n_node/CMakeLists.txt
--- p9n_node/CMakeLists.txt
+++ p9n_node/CMakeLists.txt
@@ -10,16 +10,14 @@
 
 # Display Node ======================================================
 set(TARGET teleop_twist_joy_node)
-ament_auto_add_library(
-  ${TARGET}
-    SHARED
-      src/${TARGET}.cpp)
+set(MY_LIB_NAME ${PROJECT_NAME}_${TARGET})
+ament_auto_add_library(${MY_LIB_NAME} SHARED src/${TARGET}.cpp)
 rclcpp_components_register_node(
-  ${TARGET}
-    PLUGIN "p9n_node::TeleopTwistJoyNode"
-    EXECUTABLE ${TARGET}_exec)
-# End Display Node ==================================================
+  ${MY_LIB_NAME}
+  PLUGIN "${PROJECT_NAME}::TeleopTwistJoyNode"
+  EXECUTABLE ${TARGET}_exec)
 
+# Testing ===========================================================
 if(BUILD_TESTING)
   find_package(ament_lint_auto REQUIRED)
   set(ament_cmake_copyright_FOUND TRUE)
p9n_node/include/p9n_node/teleop_twist_joy_node.hpp
--- p9n_node/include/p9n_node/teleop_twist_joy_node.hpp
+++ p9n_node/include/p9n_node/teleop_twist_joy_node.hpp
@@ -27,20 +27,29 @@
 {
 class TeleopTwistJoyNode : public rclcpp::Node
 {
+public:
+  using Twist = geometry_msgs::msg::Twist;
+  using Joy = sensor_msgs::msg::Joy;
+
 private:
   float speed_factor_ = 1.0;
+  double linear_max_speed_, angular_max_speed_;
 
   p9n_interface::HW_TYPE hw_type_;
   std::unique_ptr<p9n_interface::PlayStationInterface> p9n_if_;
 
-  rclcpp::Subscription<sensor_msgs::msg::Joy>::SharedPtr joy_sub_;
-  rclcpp::Publisher<geometry_msgs::msg::Twist>::SharedPtr twist_pub_;
+  rclcpp::Subscription<Joy>::SharedPtr joy_sub_;
+  rclcpp::Publisher<Twist>::SharedPtr twist_pub_;
+
+  rclcpp::TimerBase::SharedPtr timer_watchdog_;
 
 public:
-  TeleopTwistJoyNode(const rclcpp::NodeOptions & options);
-  void onJoy(sensor_msgs::msg::Joy::ConstSharedPtr joy_msg);
+  TeleopTwistJoyNode() = delete;
+  explicit TeleopTwistJoyNode(const rclcpp::NodeOptions & options);
+  void onJoy(Joy::ConstSharedPtr joy_msg);
+  void onWatchdog();
 };
-}
+}  // namespace p9n_node
 
 #include "rclcpp_components/register_node_macro.hpp"
 RCLCPP_COMPONENTS_REGISTER_NODE(p9n_node::TeleopTwistJoyNode)
p9n_node/src/teleop_twist_joy_node.cpp
--- p9n_node/src/teleop_twist_joy_node.cpp
+++ p9n_node/src/teleop_twist_joy_node.cpp
@@ -17,85 +17,78 @@
 
 namespace p9n_node
 {
-
 TeleopTwistJoyNode::TeleopTwistJoyNode(const rclcpp::NodeOptions & options)
 : rclcpp::Node("teleop_twist_joy_node", options)
 {
-
   const std::string hw_name = this->declare_parameter<std::string>(
     "hw_type", p9n_interface::HW_NAME::DUALSENSE);
+  this->linear_max_speed_ =
+    this->declare_parameter<double>("linear_speed", 0.2);
+  this->angular_max_speed_ =
+    this->declare_parameter<double>("angular_speed", 0.6);
 
   try {
     this->hw_type_ = p9n_interface::getHwType(hw_name);
   } catch (std::runtime_error & e) {
+    RCLCPP_ERROR(this->get_logger(), e.what());
     RCLCPP_ERROR(
-      this->get_logger(),
-      e.what());
-    RCLCPP_ERROR(
-      this->get_logger(),
-      "Please select hardware from %s",
+      this->get_logger(), "Please select hardware from %s",
       p9n_interface::getAllHwName().c_str());
-    rclcpp::shutdown();
+    exit(EXIT_FAILURE);
     return;
   }
 
   this->p9n_if_ =
     std::make_unique<p9n_interface::PlayStationInterface>(this->hw_type_);
 
-  this->joy_sub_ = this->create_subscription<sensor_msgs::msg::Joy>(
-    "joy", rclcpp::SensorDataQoS(rclcpp::KeepLast(1)),
-    std::bind(&TeleopTwistJoyNode::onJoy, this, std::placeholders::_1));
+  using namespace std::placeholders;  // NOLINT
+  this->joy_sub_ = this->create_subscription<Joy>(
+    "joy", rclcpp::SensorDataQoS().keep_last(1),
+    std::bind(&TeleopTwistJoyNode::onJoy, this, _1));
 
-  this->twist_pub_ = this->create_publisher<geometry_msgs::msg::Twist>(
-    "cmd_vel", rclcpp::QoS(10));
+  this->twist_pub_ = this->create_publisher<Twist>(
+    "cmd_vel", rclcpp::QoS(10).reliable().durability_volatile());
 
+
+  using namespace std::chrono_literals; // NOLINT
+  this->timer_watchdog_ = this->create_wall_timer(
+    1s, std::bind(&TeleopTwistJoyNode::onWatchdog, this));
 
   if (this->joy_sub_->get_publisher_count() == 0) {
-    RCLCPP_WARN(
-      this->get_logger(),
-      "Joy node not launched");
+    RCLCPP_WARN(this->get_logger(), "Joy node not launched");
   }
 }
 
-void TeleopTwistJoyNode::onJoy(sensor_msgs::msg::Joy::ConstSharedPtr joy_msg)
+void TeleopTwistJoyNode::onJoy(Joy::ConstSharedPtr joy_msg)
 {
+  this->timer_watchdog_->reset();
   this->p9n_if_->setJoyMsg(joy_msg);
 
-  if (this->p9n_if_->pressedR1()) {
-    speed_factor_ = speed_factor_ * 1.1;
-    RCLCPP_INFO(
-      this->get_logger(),
-      "Max speed: %.3f", speed_factor_);
+  static bool stopped = true;
+  if (this->p9n_if_->isTiltedStickL()) {
+    auto twist_msg = std::make_unique<Twist>();
+    twist_msg->linear.set__x(this->linear_max_speed_ * this->p9n_if_->tiltedStickLY());
+    twist_msg->angular.set__z(this->angular_max_speed_ * this->p9n_if_->tiltedStickLX());
+    this->twist_pub_->publish(std::move(twist_msg));
+
+    stopped = false;
+  } else if (!stopped) {
+    // Stop cart
+    auto twist_msg = std::make_unique<Twist>(rosidl_runtime_cpp::MessageInitialization::ZERO);
+    this->twist_pub_->publish(std::move(twist_msg));
+
+    stopped = true;
   }
-  if (this->p9n_if_->pressedL1()) {
-    speed_factor_ = speed_factor_ * 0.9;
-    RCLCPP_INFO(
-      this->get_logger(),
-      "Max speed: %.3f", speed_factor_);
-  }
+}
 
-  auto twist = geometry_msgs::msg::Twist();
-  if (
-    std::abs(this->p9n_if_->tiltedStickLX()) > 1e-2 ||
-    std::abs(this->p9n_if_->tiltedStickLY()) > 1e-2)
-  {
-    float l_y = this->p9n_if_->tiltedStickLY();
-    float l_x = this->p9n_if_->tiltedStickLX();
+void TeleopTwistJoyNode::onWatchdog()
+{
+  RCLCPP_WARN(this->get_logger(), "Couldn't subscribe joy topic before timeout");
 
-    twist.linear.x = speed_factor_ * l_y;
-    twist.angular.z = M_PI * speed_factor_ * l_x;
+  // Publish zero velocity to stop vehicle
+  auto twist_msg = std::make_unique<Twist>(rosidl_runtime_cpp::MessageInitialization::ZERO);
+  this->twist_pub_->publish(std::move(twist_msg));
 
-    this->twist_pub_->publish(twist);
-
-    // never wait for chattering for this scheme
-    return;
-  } else {
-    twist.linear.x = 0.0;
-    twist.angular.z = 0.0;
-    this->twist_pub_->publish(twist);
-  }
-
-  using namespace std::chrono_literals;
-  rclcpp::sleep_for(200ms);
+  this->timer_watchdog_->cancel();
 }
 }  // namespace p9n_node
Add a comment
List