Initial logic for avoiding obstacles
This commit is contained in:
parent
6dac67f5a9
commit
e62c361970
@ -5,5 +5,7 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
void convert_data_to_raw(data_packet_t *in, uint8_t *out);
|
void convert_data_to_raw(data_packet_t *in, uint8_t *out);
|
||||||
|
void send_sensor_data(const int32_t *distance_in_cm);
|
||||||
|
void decide_movement(const int32_t *distance_in_cm);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
110
robot/src/main.c
110
robot/src/main.c
@ -14,16 +14,18 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
#define OBSTACLE_THRESHOLD 10
|
||||||
|
|
||||||
|
uint8_t tx_raw[sizeof(data_packet_t)];
|
||||||
|
data_packet_t tx_data;
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
uint8_t *tx_raw;
|
int32_t distance_in_cm;
|
||||||
data_packet_t *tx_data;
|
|
||||||
|
|
||||||
// Data packet is too large, should split in multiple packets
|
// Data packet is too large, should split in multiple packets
|
||||||
if (sizeof(data_packet_t) > MAX_PAYLOAD_SIZE)
|
if (sizeof(data_packet_t) > MAX_PAYLOAD_SIZE)
|
||||||
return R_PACKAGE_SIZE;
|
return R_PACKAGE_SIZE;
|
||||||
tx_data = malloc(sizeof(data_packet_t));
|
|
||||||
tx_raw = malloc(sizeof(data_packet_t));
|
|
||||||
|
|
||||||
init_leds();
|
init_leds();
|
||||||
init_servos();
|
init_servos();
|
||||||
@ -41,35 +43,85 @@ int main(void)
|
|||||||
|
|
||||||
sei();
|
sei();
|
||||||
|
|
||||||
run_servos();
|
servo_full_forw();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
uint16_t distance_int_cm = read_sonar();
|
// Distance is measured early so the same value gets sent to the base
|
||||||
double temp = ds18b20_gettemp();
|
// station and gets used to decide movement. Needs to be done in order
|
||||||
|
// for base station to receive meaningful distance value.
|
||||||
|
distance_in_cm = read_sonar();
|
||||||
|
decide_movement(&distance_in_cm);
|
||||||
|
|
||||||
if (distance_int_cm <= 10 && distance_int_cm != SONAR_ERROR) {
|
// Update base station
|
||||||
SET(LED_PORT, LED_BLUE_BIT);
|
send_sensor_data(&distance_in_cm);
|
||||||
} else {
|
|
||||||
CLR(LED_PORT, LED_BLUE_BIT);
|
|
||||||
}
|
|
||||||
if (temp >= 23) {
|
|
||||||
SET(LED_PORT, LED_GREEN_BIT);
|
|
||||||
} else {
|
|
||||||
CLR(LED_PORT, LED_GREEN_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(tx_data, 0, sizeof(data_packet_t));
|
|
||||||
tx_data->distance = distance_int_cm;
|
|
||||||
tx_data->temp = temp;
|
|
||||||
|
|
||||||
memcpy(tx_raw, tx_data, sizeof(data_packet_t));
|
|
||||||
nrf24_send(tx_raw);
|
|
||||||
// TODO: prevent transmission to block the main loop
|
|
||||||
while (nrf24_isSending()); // Wait for transmission to finish
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tx_data);
|
cli();
|
||||||
free(tx_raw);
|
|
||||||
|
|
||||||
return R_OK;
|
return R_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_sensor_data(const int32_t *distance_in_cm)
|
||||||
|
{
|
||||||
|
double temp;
|
||||||
|
|
||||||
|
temp = ds18b20_gettemp();
|
||||||
|
/* if (temp >= 23) */
|
||||||
|
|
||||||
|
|
||||||
|
// Prepare the data to be sent
|
||||||
|
memset(&tx_data, 0, sizeof(data_packet_t));
|
||||||
|
tx_data.distance = *distance_in_cm;
|
||||||
|
tx_data.temp = temp;
|
||||||
|
memcpy(tx_raw, &tx_data, sizeof(data_packet_t));
|
||||||
|
|
||||||
|
nrf24_send(tx_raw);
|
||||||
|
|
||||||
|
// Indicate package sending with a signal LED
|
||||||
|
SET(LED_PORT, LED_GREEN_BIT);
|
||||||
|
while (nrf24_isSending());
|
||||||
|
CLR(LED_PORT, LED_GREEN_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Control servos based on received distance data
|
||||||
|
void decide_movement(const int32_t *distance_in_cm)
|
||||||
|
{
|
||||||
|
uint8_t avoid_obstacle = 0;
|
||||||
|
int32_t distance_to_obstacle = *distance_in_cm;
|
||||||
|
|
||||||
|
// No obstacle found
|
||||||
|
if (distance_to_obstacle == ECHO_TIMEOUT) return;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (distance_to_obstacle == ECHO_TIMEOUT) {
|
||||||
|
// No obstacle found
|
||||||
|
servo_full_forw();
|
||||||
|
avoid_obstacle = 0;
|
||||||
|
} else if (distance_to_obstacle >= 0
|
||||||
|
&& distance_to_obstacle <= MIN_SONAR_RANGE) {
|
||||||
|
// Obstacle is right in front, can't make a turn
|
||||||
|
servo_full_backw();
|
||||||
|
avoid_obstacle = 1;
|
||||||
|
_delay_ms(SONAR_DELAY);
|
||||||
|
} else if (distance_to_obstacle > MIN_SONAR_RANGE
|
||||||
|
&& distance_to_obstacle <= OBSTACLE_THRESHOLD) {
|
||||||
|
// Obstacle is close and in front, make a turn backwards
|
||||||
|
servo_turn_backw_r();
|
||||||
|
avoid_obstacle = 1;
|
||||||
|
_delay_ms(SONAR_DELAY);
|
||||||
|
} else {
|
||||||
|
// TODO: factor this in decision making about maneuvers
|
||||||
|
// Obstacle is in front, but a safe distance away
|
||||||
|
servo_full_forw();
|
||||||
|
avoid_obstacle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avoid_obstacle == 1) {
|
||||||
|
SET(LED_PORT, LED_BLUE_BIT);
|
||||||
|
} else {
|
||||||
|
CLR(LED_PORT, LED_BLUE_BIT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
distance_to_obstacle = read_sonar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user