DIT168 Group9  0.9
Miniature remote-controlled vehicle using OpenDavinci and Libcluon
PS4Controller.cpp
1 #include <cmath>
2 #include "includes/PS4Controller.hpp"
3 #include "../V2V/includes/V2VService.hpp"
4 
5 int main(int argc, char** argv) {
6  int retVal = 0;
7  auto commandlineArguments = cluon::getCommandlineArguments(argc, argv);
8  if (0 == commandlineArguments.count("dev") || 0 == commandlineArguments.count("freq") ||
9  0 == commandlineArguments.count("cid")) {
10  std::cerr << argv[0] << " reads the PS4Controller Wireless Controller inputs and sends it to the car's components"
11  << std::endl;
12  std::cerr << "Usage: " << argv[0] << " --dev=<path Controller> --freq=<int Frequency> --cid=<OD4Session Session>"
13  << std::endl;
14  std::cerr << "Example: " << argv[0] << " --dev=/dev/input/js0 --freq=100 --cid=200" << std::endl;
15  retVal = 1;
16  }
17  else {
18  const std::string DEV = commandlineArguments["dev"];
19  const uint16_t FREQ = (uint16_t) std::stoi(commandlineArguments["freq"]);
20  const uint16_t CID = (uint16_t) std::stoi(commandlineArguments["cid"]);
21 
22  const float m_OFFSET = std::stof(commandlineArguments["offset"]);
23  const uint16_t m_MAX_STEERING_ANGLE_LEFT = (uint16_t) std::stoi(commandlineArguments["leftAngle"]);
24  const uint16_t m_MAX_STEERING_ANGLE_RIGHT = (uint16_t) std::stoi(commandlineArguments["rightAngle"]);
25 
26  cluon::OD4Session od4(CID, [](cluon::data::Envelope /*&&envelope*/) noexcept {});
27  auto atFrequency{[&od4, &DEV, &FREQ, &CID, &m_MAX_STEERING_ANGLE_LEFT, &m_MAX_STEERING_ANGLE_RIGHT,
28  m_OFFSET]() -> bool {
29  FILE* file = fopen(DEV.c_str(), "rb");
30  if (file != nullptr) {
31  auto event = (PS4Event* )malloc(sizeof(PS4Event));
32  while (!feof(file)) {
33  if (fread(event, sizeof(PS4Event), 1, file)) {
34  if ((event->type &0x0F) == 1) {
35  sendButtonPressed(findButton(event), &od4);
36  }
37  else if ((event->type &0x0F) == 2) {
38  switch (event->id) {
39  case LStickX: {
40  steeringReading.groundSteering(m_OFFSET);
41  float value = 0;
42  if (event->data < 0) {
43  value = event->data / MIN_AXES_VALUE * m_MAX_STEERING_ANGLE_LEFT *
44  static_cast<float>(M_PI) / 180.0f + m_OFFSET;
45  roundValue(&value);
46  steeringReading.groundSteering(value);
47  }
48  else if (event->data >= 0) {
49  value = event->data / MIN_AXES_VALUE * m_MAX_STEERING_ANGLE_RIGHT *
50  static_cast<float>(M_PI) / 180.0f + m_OFFSET;
51  roundValue(&value);
52  steeringReading.groundSteering(value);
53  }
54 
55  od4.send(steeringReading);
56  std::cout << "Sending Angle: " << steeringReading.groundSteering() << std::endl;
57  }
58  break;
59  case LStickY: break;
60  case L2Y: break;
61  case RStickX: break;
62  case RStickY: {
63  float value = 0;
64  pedalPositionReading.position(value);
65  if(event->data < 0) {
66  value = event->data / MIN_AXES_VALUE * m_MAX_ACCELERATION;
67  roundValue(&value);
68  pedalPositionReading.position(value);
69  }
70  else if (event->data >= 0) {
71  value = event->data / MAX_AXES_VALUE * m_MAX_DECELERATION;
72  roundValue(&value);
73  pedalPositionReading.position(value);
74  }
75  od4.send(pedalPositionReading);
76  std::cout << "Sending speed: " << value << std::endl;
77  }
78  break;
79  case R2Y: break;
80  case PadX: break;
81  case PadY: break;
82  default: break;
83  }
84  }
85  }
86  else if (ferror(file)) {
87  std::cout << "Error: FREAD failed with error number'" << errno << std::endl;
88  }
89  else if (feof(file)) {
90  std::cout << "Error: EOF reached!" << std::endl;
91  }
92  }
93  free(event);
94  }
95  else {
96  std::cout << "Error: input file at '" << DEV << "' cannot be accessed!" << std::endl;
97  }
98  return true;
99  }};
100  od4.timeTrigger(FREQ, atFrequency);
101  }
102  return retVal;
103 }
104 
105 uint16_t findButton(PS4Event* event) {
106  switch (event->id) {
107  case Square:
108  if (event->data == 1) {
109  std::cout << "Square pressed." << std::endl;
110  return {0};
111  }
112  break;
113  case X:
114  if (event->data == 1) {
115  return {1};
116  }
117  break;
118  case Circle:
119  if (event->data == 1) {
120  return {2};
121  }
122  break;
123  case Triangle:
124  if (event->data == 1) {
125  return {3};
126  }
127  break;
128  case L1:
129  if (event->data == 1) {
130  return {4};
131  }
132  break;
133  case R1:
134  if (event->data == 1) {
135  return {5};
136  }
137  break;
138  case L2:
139  if (event->data == 1) {
140  return {6};
141  }
142  break;
143  case R2:
144  if (event->data == 1) {
145  return {7};
146  }
147  break;
148  case Share:
149  if (event->data == 1) {
150  return {8};
151  }
152  break;
153  case Options:
154  if (event->data == 1) {
155  return {9};
156  }
157  break;
158  case LStick:
159  if (event->data == 1) {
160  return {10};
161  }
162  break;
163  case RStick:
164  if (event->data == 1) {
165  return {11};
166  }
167  break;
168  case PS:
169  if (event->data == 1) {
170  return {12};
171  }
172  break;
173  default:
174  break;
175  }
176 }
177 
178 void sendButtonPressed(uint16_t button, cluon::OD4Session* od4Session) {
179  buttonPressed.buttonNumber(button);
180  od4Session->send(buttonPressed);
181 }
182 
183 void roundValue(float* number) {
184  *number = roundf(*number * 100) / 100.0f;
185 }