vulp  2.3.0
Joystick.cpp
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright 2022 Stéphane Caron
3 
5 
7 
8 Joystick::Joystick(const std::string& device_path) {
9  fd_ = ::open(device_path.c_str(), O_RDONLY | O_NONBLOCK);
10  if (fd_ < 0) {
11  spdlog::warn("[Joystick] Observer disabled: no joystick found at {}",
12  device_path);
13  }
14 }
15 
17  if (fd_ >= 0) {
18  ::close(fd_);
19  }
20 }
21 
22 void Joystick::read_event() {
23  if (fd_ < 0) {
24  return;
25  }
26 
27  ssize_t bytes = ::read(fd_, &event_, sizeof(event_));
28  if (bytes != sizeof(event_)) { // no input
29  return;
30  }
31 
32  double normalized_value = static_cast<double>(event_.value) / 32767;
33  if (std::abs(normalized_value) < kJoystickDeadband) {
34  normalized_value = 0.0;
35  }
36 
37  switch (event_.type) {
38  case JS_EVENT_BUTTON:
39  switch (event_.number) {
40  case 0: // PS4: cross, Xbox: A
41  cross_button_ = event_.value;
42  break;
43  case 1: // PS4: circle, Xbox: B
44  throw std::runtime_error(event_.value ? "Stop button pressed"
45  : "Stop button released");
46  break;
47  case 2: // PS4: triangle, Xbox: X
48  triangle_button_ = event_.value;
49  break;
50  case 3: // PS4: square, Xbox: Y
51  square_button_ = event_.value;
52  break;
53  case 4: // PS4: L1, Xbox: L
54  left_button_ = event_.value;
55  break;
56  case 5: // PS4: R1, Xbox: R
57  right_button_ = event_.value;
58  break;
59  case 6: // PS4: L2, Xbox: back
60  break;
61  case 7: // PS4: R2, Xbox: start
62  break;
63  case 8: // PS4: share, Xbox: Xbox button
64  break;
65  case 9: // PS4: options, Xbox: left stick button
66  break;
67  case 10: // PS4: PS, Xbox: right stick button
68  break;
69  case 11: // PS4: L3, Xbox: N/A
70  break;
71  case 12: // PS4: R3, Xbox: N/A
72  break;
73  default:
74  spdlog::warn("Button number {} is out of range", event_.number);
75  break;
76  }
77  break;
78  case JS_EVENT_AXIS:
79  switch (event_.number) {
80  case 0:
81  left_axis_.x() = normalized_value;
82  break;
83  case 1:
84  left_axis_.y() = normalized_value;
85  break;
86  case 2:
87  left_trigger_ = normalized_value;
88  break;
89  case 3:
90  right_axis_.x() = normalized_value;
91  break;
92  case 4:
93  right_axis_.y() = normalized_value;
94  break;
95  case 5:
96  right_trigger_ = normalized_value;
97  break;
98  case 6:
99  pad_axis_.x() = normalized_value;
100  break;
101  case 7:
102  pad_axis_.y() = normalized_value;
103  break;
104  default:
105  spdlog::warn("Axis number {} is out of range", event_.number);
106  break;
107  }
108  break;
109  default:
110  // initialization events
111  break;
112  }
113 }
114 
115 void Joystick::write(Dictionary& observation) {
116  read_event();
117  auto& output = observation(prefix());
118  output("cross_button") = cross_button_;
119  output("left_axis") = left_axis_;
120  output("left_button") = left_button_;
121  output("left_trigger") = left_trigger_;
122  output("pad_axis") = pad_axis_;
123  output("right_axis") = right_axis_;
124  output("right_button") = right_button_;
125  output("right_trigger") = right_trigger_;
126  output("square_button") = square_button_;
127  output("triangle_button") = triangle_button_;
128 }
129 
130 } // namespace vulp::observation::sources
std::string prefix() const noexcept final
Prefix of output in the observation dictionary.
Definition: Joystick.h:42
~Joystick() override
Close device file.
Definition: Joystick.cpp:16
void write(Dictionary &output) final
Write output to a dictionary.
Definition: Joystick.cpp:115
Joystick(const std::string &device_path="/dev/input/js0")
Open the device file.
Definition: Joystick.cpp:8
constexpr double kJoystickDeadband
Deadband between 0.0 and 1.0.
Definition: Joystick.h:18