arduino stuffs
Diffstat (limited to 'car_driver/arduino/infared.h')
| -rw-r--r-- | car_driver/arduino/infared.h | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/car_driver/arduino/infared.h b/car_driver/arduino/infared.h new file mode 100644 index 0000000..b445561 --- /dev/null +++ b/car_driver/arduino/infared.h @@ -0,0 +1,140 @@ +/* + * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv + * An IR detector/demodulator must be connected to the input RECV_PIN. + * Version 0.1 July, 2009 + * Copyright 2009 Ken Shirriff + * http://arcfn.com + */ + +#include <IRremote.h> +#include <Streaming.h> + +namespace Infared { +#define RECV_PIN 2 +struct { + +} ir_map; +#define NO_INPUT 0x00 + +#define ESTOP 0xFFF807 +#define STOP 0xFF32CD +#define UP 0xFF0AF5 +#define LEFT 0xFF22DD +#define RIGHT 0xFF1AE5 +#define DOWN 0xFFF00F + +#define UP_LEFT 0xFF12ED +#define UP_RIGHT 0xFF2AD5 +#define DOWN_LEFT 0xFFE01F +#define DOWN_RIGHT 0xFF9A65 + +#pragma region math +inline void lerp(float &from, const float to, const float weight) { from = from + (to - from) * weight; } +inline float lerpr(const float from, const float to, const float weight) { return from + (to - from) * weight; } +static int clamp(long value, long minv, long maxv) { + if (value < minv) + return minv; + else if (value > maxv) + return maxv; + return value; +} +void kinda_round(float &n) { + if (n > .9) + n = 1; + else if (n < -.9) + n = -1; + else if (n > -.1 and n < .1) + n = 0; +} +inline int8_t mult(const float n) { return round(clamp(n * 100, -100, 100)); } +#pragma endregion + +int8_t motors[2] = {0, 0}; + +void map(const unsigned long cmd) { + static float forces = 0, torque = 0; + + const float large_weight = .8, weight = .5, low_weight = .3, speed = 1; + + switch (cmd) { + case ESTOP: + torque = 0; + forces = 0; + case NO_INPUT: + lerp(forces, 0, large_weight); + lerp(torque, 0, large_weight); + break; + case UP: + lerp(forces, +speed, weight); + break; + case LEFT: + lerp(torque, +speed, weight); + break; + case RIGHT: + lerp(torque, -speed, weight); + break; + case UP_LEFT: + lerp(forces, +speed, low_weight); + lerp(torque, -speed, low_weight); + break; + case UP_RIGHT: + lerp(forces, +speed, low_weight); + lerp(torque, +speed, low_weight); + break; + case DOWN: + lerp(forces, -speed, weight); + break; + case DOWN_LEFT: + lerp(forces, -speed, low_weight); + lerp(torque, -speed / 2, low_weight); + break; + case DOWN_RIGHT: + lerp(forces, -speed, low_weight); + lerp(torque, +speed / 2, low_weight); + break; + + default: + break; + } + kinda_round(forces); + kinda_round(torque); + const float turn_amount = abs(torque) / 2.5; + const int8_t a = mult(lerpr(forces, torque, turn_amount)), b = mult(lerpr(forces, -torque, turn_amount)); + + if (forces > 0) { + motors[0] = a; + motors[1] = b; + } else { + motors[1] = a; + motors[0] = b; + } +} + +IRrecv irrecv(RECV_PIN); + +decode_results results; +unsigned long last_result_time = 0, last_real_result = 0; + +void begin() { + Serial.begin(9600); + irrecv.enableIRIn(); // Start the receiver +} + +void loop() { + if (irrecv.decode(&results)) { + if (results.value == REPEAT) + results.value = last_real_result; + else + last_real_result = results.value; + map(results.value); + last_result_time = millis(); + irrecv.resume(); + } else if (not(motors[0] == 0 and motors[1] == 0) and millis() - last_result_time > 200) + // no results in a while (.2 seconds), lerpit down + map(NO_INPUT); +} + +inline int8_t motor_a() { return motors[0]; } +inline int8_t motor_b() { return motors[1]; } + +} // namespace Infared
\ No newline at end of file |