backend_controller.hpp
Go to the documentation of this file.
1 #ifndef RADIAL_MENU_BACKEND_BACKEND_CONTROLLER_HPP
2 #define RADIAL_MENU_BACKEND_BACKEND_CONTROLLER_HPP
3 
4 #include <cmath>
5 #include <limits>
6 #include <memory>
7 
10 #include <radial_menu_msgs/State.h>
11 #include <sensor_msgs/Joy.h>
12 
13 namespace radial_menu_backend {
14 
16 typedef std::shared_ptr< BackendController > BackendControllerPtr;
17 typedef std::shared_ptr< const BackendController > BackendControllerConstPtr;
18 
20 public:
22  : model_(model), enable_was_pressed_(false), select_was_pressed_(false),
23  ascend_was_pressed_(false), config_(config) {}
24 
25  virtual ~BackendController() {}
26 
27  radial_menu_msgs::StatePtr update(const sensor_msgs::Joy &joy) {
28  // reset the menu based on enable/disable state if required
29  const bool enable_is_pressed(buttonValue(joy, config_.enable_button) > 0);
30  if ((config_.reset_on_enabling && !enable_was_pressed_ && enable_is_pressed) ||
31  (config_.reset_on_disabling && enable_was_pressed_ && !enable_is_pressed)) {
32  model_->resetState();
33  }
34 
35  // enable/disable the menu
36  // (resetState() disables the menu so setEnabled() must be called after resetState())
37  model_->setEnabled(enable_is_pressed);
38 
39  // unpoint if possible
40  const radial_menu_model::ItemConstPtr last_pointed_item(model_->pointed());
41  if (model_->canUnpoint(last_pointed_item)) {
42  model_->unpoint(last_pointed_item);
43  }
44 
45  // do remaining operations if the menu is enabled
46  const bool select_is_pressed(buttonValue(joy, config_.select_button) > 0);
47  const bool ascend_is_pressed(buttonValue(joy, config_.ascend_button) > 0);
48  if (enable_is_pressed) {
49  // update the pointing item
50  const double pointing_angle(pointingAngle(joy));
51  if (!std::isnan(pointing_angle)) {
52  const radial_menu_model::ItemConstPtr item_to_point(
53  model_->sibilingByAngle(pointing_angle));
54  if (model_->canPoint(item_to_point)) {
55  model_->point(item_to_point);
56  }
57  }
58 
59  // if an item is pointed and the select button is newly pressed, select the pointed item,
60  // else if auto-select is enabled and no item is pointed, select the last pointed item
61  const radial_menu_model::ItemConstPtr pointed_item(model_->pointed());
62  if (pointed_item && select_is_pressed && !select_was_pressed_) {
63  adaptiveSelect(pointed_item);
64  } else if (config_.auto_select && std::isnan(pointing_angle) && last_pointed_item) {
65  adaptiveSelect(last_pointed_item);
66  }
67 
68  // if the ascend button is newly pressed, ascend from the current level
69  if (ascend_is_pressed && !ascend_was_pressed_) {
70  if (model_->canAscend()) {
71  model_->ascend();
72  }
73  }
74  }
75 
76  // update memos
77  enable_was_pressed_ = enable_is_pressed;
78  select_was_pressed_ = select_is_pressed;
79  ascend_was_pressed_ = ascend_is_pressed;
80 
81  return model_->exportState(joy.header.stamp);
82  }
83 
84 protected:
85  // utility functions
86 
87  double pointingAngle(const sensor_msgs::Joy &joy) const {
88  const double value_v(config_.invert_pointing_axis_v ? -axisValue(joy, config_.pointing_axis_v)
90  const double value_h(config_.invert_pointing_axis_h ? -axisValue(joy, config_.pointing_axis_h)
92  return (value_v * value_v + value_h * value_h >=
94  ? std::atan2(value_h, value_v)
95  : std::numeric_limits< double >::quiet_NaN();
96  }
97 
99  if (model_->canSelect(item)) {
100  model_->select(item, config_.allow_multi_selection);
101  } else if (model_->canDeselect(item)) {
102  model_->deselect(item);
103  } else if (model_->canDescend(item)) {
104  model_->descend(item, config_.allow_multi_selection);
105  }
106  }
107 
108  // return button value without id range error
109  static int buttonValue(const sensor_msgs::Joy &joy, const int bid) {
110  return (bid >= 0 && bid < joy.buttons.size()) ? joy.buttons[bid] : 0;
111  }
112 
113  // return axis value without id range error
114  static double axisValue(const sensor_msgs::Joy &joy, const int aid) {
115  return (aid >= 0 && aid < joy.axes.size()) ? joy.axes[aid] : 0.;
116  }
117 
118 protected:
120 
121  // memo
123 
125 };
126 } // namespace radial_menu_backend
127 
128 #endif
std::shared_ptr< const Item > ItemConstPtr
BackendController(const radial_menu_model::ModelPtr &model, const BackendConfig &config)
void adaptiveSelect(const radial_menu_model::ItemConstPtr &item)
static int buttonValue(const sensor_msgs::Joy &joy, const int bid)
std::shared_ptr< const BackendController > BackendControllerConstPtr
std::shared_ptr< Model > ModelPtr
radial_menu_msgs::StatePtr update(const sensor_msgs::Joy &joy)
double pointingAngle(const sensor_msgs::Joy &joy) const
std::shared_ptr< BackendController > BackendControllerPtr
static double axisValue(const sensor_msgs::Joy &joy, const int aid)


radial_menu_backend
Author(s):
autogenerated on Mon Feb 28 2022 23:22:01