Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
304d62a
added height control to c based controller
knmcguire Apr 21, 2023
94f5db4
new proto with fast helix
knmcguire Apr 21, 2023
054ee50
added a new controller with wall following
knmcguire Apr 26, 2023
1082b38
added new environment with an apartement
knmcguire Apr 26, 2023
08a81cd
fix the autonomy toggle
knmcguire Apr 26, 2023
8924df5
tracking shot for apartement
knmcguire Apr 26, 2023
04be146
changed extern proto url
knmcguire Apr 26, 2023
180ab02
Merge branch 'develop' into improvements-crazyflie
omichel Apr 26, 2023
915ac52
add description
knmcguire Apr 26, 2023
8666172
change wbt name from typo
knmcguire Apr 26, 2023
de11049
Merge branch 'develop' into improvements-crazyflie
omichel Apr 26, 2023
be06426
Update projects/robots/bitcraze/crazyflie/protos/Crazyflie.proto
knmcguire Apr 26, 2023
7d5cd93
remove fast helix of crazyflie proto
knmcguire Apr 27, 2023
d902958
move fast helix to default texture file
knmcguire Apr 27, 2023
274f96a
formated python with pep8
knmcguire Apr 27, 2023
46b4d15
clang format
knmcguire Apr 28, 2023
92de77d
Remove unnessesary imports
knmcguire Apr 28, 2023
2ec5315
Remove switch cases to ifelse
knmcguire Apr 28, 2023
39703a5
return format of c controllers
knmcguire Apr 28, 2023
c00cc18
revert c files to former clang
knmcguire Apr 28, 2023
727534b
manual clang pid_controller.c
knmcguire Apr 28, 2023
7adcbd0
manual clang pid_controller.c
knmcguire Apr 28, 2023
e05d62f
manual clang pid_controller.c
knmcguire Apr 28, 2023
31eca66
manual clang crazyflie, pid_controller.h
knmcguire Apr 28, 2023
d5c7c1f
manual clang crazyflie.c
knmcguire Apr 28, 2023
c14b265
manual clang crazyflie.c pid_controller.h
knmcguire Apr 28, 2023
f462a3d
manual clang pid_controller.h
knmcguire Apr 29, 2023
83c26eb
Merge branch 'develop' into improvements-crazyflie
knmcguire Apr 29, 2023
697c3d9
update apartement file
knmcguire May 1, 2023
20625f0
Fixed indentation
omichel May 1, 2023
4afdaf8
Merge branch 'develop' into improvements-crazyflie
omichel May 2, 2023
bd1fd3c
Merge branch 'develop' into improvements-crazyflie
knmcguire May 2, 2023
dd26625
update wall following class
knmcguire May 3, 2023
3d59860
intergrated omichel comments
knmcguire May 3, 2023
76d5081
fixed small name change in controller
knmcguire May 3, 2023
5e031ce
address rest of omichel comments
knmcguire May 3, 2023
54ab7bc
clang and pep8
knmcguire May 3, 2023
370a9a2
remove switch case again
knmcguire May 3, 2023
ac30df6
Merge branch 'develop' into improvements-crazyflie
knmcguire May 5, 2023
c672c8f
Update projects/robots/bitcraze/crazyflie/controllers/crazyflie/pid_c…
omichel May 5, 2023
ca23b9a
Update projects/robots/bitcraze/crazyflie/controllers/crazyflie_py_wa…
omichel May 5, 2023
966f650
Update projects/robots/bitcraze/crazyflie/controllers/crazyflie/pid_c…
omichel May 5, 2023
f19ae1e
Update projects/robots/bitcraze/crazyflie/controllers/crazyflie/pid_c…
omichel May 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
// Add external controller
#include "pid_controller.h"

#define FLYING_ALTITUDE 1.0

int main(int argc, char **argv) {
wb_robot_init();

Expand Down Expand Up @@ -102,14 +104,15 @@ int main(int argc, char **argv) {
gains_pid.kp_vel_xy = 2;
gains_pid.kd_vel_xy = 0.5;
gains_pid.kp_z = 10;
gains_pid.ki_z = 50;
gains_pid.ki_z = 5;
gains_pid.kd_z = 5;
init_pid_attitude_fixed_height_controller();

double height_desired = FLYING_ALTITUDE;

// Initialize struct for motor power
motor_power_t motor_power;

printf(" Take off! \n");
printf("\n");

printf("====== Controls =======\n");
Expand All @@ -118,6 +121,7 @@ int main(int argc, char **argv) {
printf(" All controllable movement is in body coordinates\n");
printf("- Use the up, back, right and left button to move in the horizontal plane\n");
printf("- Use Q and E to rotate around yaw\n ");
printf("- Use W and S to go up and down\n");

while (wb_robot_step(timestep) != -1) {
const double dt = wb_robot_get_time() - past_time;
Expand Down Expand Up @@ -150,33 +154,42 @@ int main(int argc, char **argv) {
double forward_desired = 0;
double sideways_desired = 0;
double yaw_desired = 0;
double height_diff_desired = 0;

// Control altitude
int key = wb_keyboard_get_key();
while (key > 0) {
switch (key) {
case WB_KEYBOARD_UP:
forward_desired = +0.2;
forward_desired = +0.5;
break;
case WB_KEYBOARD_DOWN:
forward_desired = -0.2;
forward_desired = -0.5;
break;
case WB_KEYBOARD_RIGHT:
sideways_desired = -0.2;
sideways_desired = -0.5;
break;
case WB_KEYBOARD_LEFT:
sideways_desired = +0.2;
sideways_desired = +0.5;
break;
case 'Q':
yaw_desired = 0.5;
yaw_desired = 1.0;
break;
case 'E':
yaw_desired = -0.5;
yaw_desired = -1.0;
break;
case 'W':
height_diff_desired = 0.1;
break;
case 'S':
height_diff_desired = -0.1;
break;
}
key = wb_keyboard_get_key();
}

height_desired += height_diff_desired * dt;

// Example how to get sensor data
// range_front_value = wb_distance_sensor_get_value(range_front));
// const unsigned char *image = wb_camera_get_image(camera);
Expand All @@ -186,6 +199,7 @@ int main(int argc, char **argv) {
// PID velocity controller with fixed height
desired_state.vy = sideways_desired;
desired_state.vx = forward_desired;
desired_state.altitude = height_desired;
pid_velocity_fixed_height_controller(actual_state, &desired_state, gains_pid, dt, &motor_power);

// Setting motorspeed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ float constrain(float value, const float minVal, const float maxVal) {

double pastAltitudeError, pastPitchError, pastRollError, pastYawRateError;
double pastVxError, pastVyError;
double altitudeIntegrator;

void init_pid_attitude_fixed_height_controller() {
pastAltitudeError = 0;
Expand All @@ -49,6 +50,7 @@ void init_pid_attitude_fixed_height_controller() {
pastRollError = 0;
pastVxError = 0;
pastVyError = 0;
altitudeIntegrator = 0;
}

void pid_attitude_fixed_height_controller(actual_state_t actual_state, desired_state_t *desired_state, gains_pid_t gains_pid,
Expand All @@ -74,6 +76,10 @@ void pid_fixed_height_controller(actual_state_t actual_state, desired_state_t *d
double altitudeDerivativeError = (altitudeError - pastAltitudeError) / dt;
control_commands->altitude =
gains_pid.kp_z * constrain(altitudeError, -1, 1) + gains_pid.kd_z * altitudeDerivativeError + gains_pid.ki_z;

altitudeIntegrator += altitudeError * dt;
control_commands->altitude = gains_pid.kp_z * constrain(altitudeError, -1, 1) + gains_pid.kd_z * altitudeDerivativeError +
gains_pid.ki_z * altitudeIntegrator + 48;
pastAltitudeError = altitudeError;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# -*- coding: utf-8 -*-
#
# ........... ____ _ __
# | ,-^-, | / __ )(_) /_______________ _____ ___
# | ( O ) | / __ / / __/ ___/ ___/ __ `/_ / / _ \
# | / ,..´ | / /_/ / / /_/ /__/ / / /_/ / / /_/ __/
# +....... /_____/_/\__/\___/_/ \__,_/ /___/\___/

# MIT License

# Copyright (c) 2023 Bitcraze


"""
file: crazyflie_py_wallfollowing.py

Controls the crazyflie and implements a wall following method in webots in Python

Author: Kimberly McGuire (Bitcraze AB)
"""


from controller import Robot
from controller import Keyboard

from math import cos, sin

from pid_controller import pid_velocity_fixed_height_controller
from wall_following import WallFollowing

FLYING_ATTITUDE = 1

if __name__ == '__main__':

robot = Robot()
timestep = int(robot.getBasicTimeStep())

# Initialize motors
m1_motor = robot.getDevice("m1_motor")
m1_motor.setPosition(float('inf'))
m1_motor.setVelocity(-1)
m2_motor = robot.getDevice("m2_motor")
m2_motor.setPosition(float('inf'))
m2_motor.setVelocity(1)
m3_motor = robot.getDevice("m3_motor")
m3_motor.setPosition(float('inf'))
m3_motor.setVelocity(-1)
m4_motor = robot.getDevice("m4_motor")
m4_motor.setPosition(float('inf'))
m4_motor.setVelocity(1)

# Initialize Sensors
imu = robot.getDevice("inertial_unit")
imu.enable(timestep)
gps = robot.getDevice("gps")
gps.enable(timestep)
gyro = robot.getDevice("gyro")
gyro.enable(timestep)
camera = robot.getDevice("camera")
camera.enable(timestep)
range_front = robot.getDevice("range_front")
range_front.enable(timestep)
range_left = robot.getDevice("range_left")
range_left.enable(timestep)
range_back = robot.getDevice("range_back")
range_back.enable(timestep)
range_right = robot.getDevice("range_right")
range_right.enable(timestep)

# Get keyboard
keyboard = Keyboard()
keyboard.enable(timestep)

# Initialize variables

past_x_global = 0
past_y_global = 0
past_time = 0
first_time = True

# Crazyflie velocity PID controller
PID_crazyflie = pid_velocity_fixed_height_controller()
PID_update_last_time = robot.getTime()
sensor_read_last_time = robot.getTime()

height_desired = FLYING_ATTITUDE

wall_following = WallFollowing(angle_value_buffer=0.01, reference_distance_from_wall=0.5,
max_forward_speed=0.3, init_state=WallFollowing.StateWallFollowing.FORWARD)

autonomous_mode = False

print("\n")

print("====== Controls =======\n\n")

print(" The Crazyflie can be controlled from your keyboard!\n")
print(" All controllable movement is in body coordinates\n")
print("- Use the up, back, right and left button to move in the horizontal plane\n")
print("- Use Q and E to rotate around yaw\n ")
print("- Use W and S to go up and down\n ")
print("- Press A to start autonomous mode\n")
print("- Press D to disable autonomous mode\n")

# Main loop:
while robot.step(timestep) != -1:

dt = robot.getTime() - past_time
actual_state = {}

if first_time:
past_x_global = gps.getValues()[0]
past_y_global = gps.getValues()[1]
past_time = robot.getTime()
first_time = False

# Get sensor data
roll = imu.getRollPitchYaw()[0]
pitch = imu.getRollPitchYaw()[1]
yaw = imu.getRollPitchYaw()[2]
yaw_rate = gyro.getValues()[2]
x_global = gps.getValues()[0]
v_x_global = (x_global - past_x_global)/dt
y_global = gps.getValues()[1]
v_y_global = (y_global - past_y_global)/dt
altitude = gps.getValues()[2]

# Get body fixed velocities
cos_yaw = cos(yaw)
sin_yaw = sin(yaw)
v_x = v_x_global * cos_yaw + v_y_global * sin_yaw
v_y = - v_x_global * sin_yaw + v_y_global * cos_yaw

# Initialize values
desired_state = [0, 0, 0, 0]
forward_desired = 0
sideways_desired = 0
yaw_desired = 0
height_diff_desired = 0

key = keyboard.getKey()
while key > 0:
if key == Keyboard.UP:
forward_desired += 0.5
elif key == Keyboard.DOWN:
forward_desired -= 0.5
elif key == Keyboard.RIGHT:
sideways_desired -= 0.5
elif key == Keyboard.LEFT:
sideways_desired += 0.5
elif key == ord('Q'):
yaw_desired = + 1
elif key == ord('E'):
yaw_desired = - 1
elif key == ord('W'):
height_diff_desired = 0.1
elif key == ord('S'):
height_diff_desired = - 0.1
elif key == ord('A'):
if autonomous_mode is False:
autonomous_mode = True
print("Autonomous mode: ON")
elif key == ord('D'):
if autonomous_mode is True:
autonomous_mode = False
print("Autonomous mode: OFF")
key = keyboard.getKey()

height_desired += height_diff_desired * dt

camera_data = camera.getImage()

# get range in meters
range_front_value = range_front.getValue() / 1000
range_right_value = range_right.getValue() / 1000
range_left_value = range_left.getValue() / 1000

# Choose a wall following direction
# if you choose direction left, use the right range value
# if you choose direction right, use the left range value
direction = WallFollowing.WallFollowingDirection.LEFT
range_side_value = range_right_value

# Get the velocity commands from the wall following state machine
cmd_vel_x, cmd_vel_y, cmd_ang_w, state_wf = wall_following.wall_follower(
range_front_value, range_side_value, yaw, direction, robot.getTime())

if autonomous_mode:
sideways_desired = cmd_vel_y
forward_desired = cmd_vel_x
yaw_desired = cmd_ang_w

# PID velocity controller with fixed height
motor_power = PID_crazyflie.pid(dt, forward_desired, sideways_desired,
yaw_desired, height_desired,
roll, pitch, yaw_rate,
altitude, v_x, v_y)

m1_motor.setVelocity(-motor_power[0])
m2_motor.setVelocity(motor_power[1])
m3_motor.setVelocity(-motor_power[2])
m4_motor.setVelocity(motor_power[3])

past_time = robot.getTime()
past_x_global = x_global
past_y_global = y_global
Loading