[SOLVED] CS ######################################################################

$25

File Name: CS_######################################################################.zip
File Size: 687.66 KB

5/5 - (1 vote)

######################################################################
# This file copyright the Georgia Institute of Technology
# Permission is given to students to use or modify this file (only)
# to work on their assignments.

Copyright By Assignmentchef assignmentchef

# You may NOT publish this file or make it available to others not in
# the course.
######################################################################

import math
import random

class DualRotor(object):
g = 9.8 # gravity = 9.8 m/s2

def __init__(self):
self.y = 0 # 0 is ground
self.x = 0 # 0 is starting point

self.propeller_speed= {1:0, 2:0} # rpm for each propeller. 1=left, 2=right

self.thrust = {1:0, 2:0} # thrust at each propeller
self.mass = 20 #30 #kg
self.weight = self.mass * self.g
self.velocity = 0
self.y_velocity = 0
self.x_velocity = 0
self.length = 0.25 # meters. Side to side length of drone
self.roll_angle = 0 # The drones normal resting position is 0 roll angle.
# For now it is pointing right (along x-axis). This
# is significant when calculating roll angles.

# Simple displacement added to the
# x-axis movement of the drone as a result
# of wind speed.

# TODO: Replace with motion model according to wind
self.WIND_FACTOR_STD = 0.0 # std dev for wind
self.WIND_SPEED_X = 0.0 # a constant wind speed in the horizontal direction

self.RPM_ERROR = 0 #2 # propeller RPM drifts by this amount

self.MAX_PROPELLER_SPEED = 10000
self.MAX_RPM_CHANGE_PER_STEP = 500
#self.MAX_THRUST = 2 * self.weight
self.RPM_TO_THRUST_RATIO = 1.1
self.RPM_TO_ROLL_RATIO = 1 #0.05
self.MAX_ROLL_ANGLE = 0.33 * math.pi
self.MAX_HEIGHT = 1000 #meters

self.sensor_noise_x = 0
self.sensor_noise_y = 0

def increase_propeller_speed(self, id, rpm=10):
assert rpm >= 0, rpm must be 0 or positive
rpm = min(self.MAX_RPM_CHANGE_PER_STEP, rpm)

self.propeller_speed[id] = min(self.propeller_speed[id] + rpm, self.MAX_PROPELLER_SPEED)

# update thrust based on a simplified formula
# lets say the rpm to thrust force ratio is 1:1.2
self.thrust[id] = self.propeller_speed[id] / self.RPM_TO_THRUST_RATIO

def decrease_propeller_speed(self, id, rpm=10):
assert rpm >= 0, rpm must be 0 or positive
rpm = min(self.MAX_RPM_CHANGE_PER_STEP, rpm)
self.propeller_speed[id] = max(self.propeller_speed[id] rpm, 0)

# update thrust based on a simplified formula
# lets say the rpm to thrust force ratio is 1:1.2
self.thrust[id] = self.propeller_speed[id] / self.RPM_TO_THRUST_RATIO

def add_thrust(self, thrust=5, roll=0):
self.thrust[id] = min(self.thrust[id] + thrust, self.MAX_THRUST)

def reduce_thrust(self, id, thrust=10):
self.thrust[id] = max(self.thrust[id] thrust, 0)

def set_thrust(self, id, net_force):
self.thrust[id] = net_force + self.g/2
self.propeller_speed[id] = self.thrust[id] * self.RPM_TO_THRUST_RATIO

def get_elevation(self):
return self.y + self.sensor_noise_y

def get_x_coord(self):
return self.x + self.sensor_noise_x

def get_coordinates(self):
return (self.x + self.sensor_noise_x, self.y + self.sensor_noise_y)

def is_max_rpm_reached(self):
return (self.propeller_speed[1] + self.propeller_speed[2]) == self.MAX_PROPELLER_SPEED*2

def is_max_roll_reached(self):
return abs(self.roll_angle) == self.MAX_ROLL_ANGLE

def wind_speed(self):
if self.WIND_FACTOR_STD != 0:
return random.gauss(0, self.WIND_FACTOR_STD)
return self.WIND_SPEED_X

def calc_one_side_move(self, id, dt):
# calculate net force: total thrust by propeller weight of drone
F = self.thrust[id] self.weight/2 # Assume each propeller supports 1/2 weight.
# Net force, can be negative (downward) or positive (upward)

# calculate acceleration
a = F / self.mass

# calculate movement
new_y = self.y + (1/2) * a * dt**2 #+ self.y_velocity * dt 0.1 * self.y_velocity

new_y = max(new_y, 0)

# Calculate x and y components of thrust.
# Zero roll angle is pointing right (along x-axis)
# so tilt right will be negative, and since we are
# calculating angles from drone being in upright position
# (i.e. 90 degrees), we will add the angle to 90 degrees
# for tilt right.
# Similarly tilt left will have positive roll
x_disp = new_y * math.cos((math.pi/2) + self.roll_angle)

new_y = new_y * math.sin((math.pi/2) + self.roll_angle)
new_y = max(new_y, 0) # sin might be negative

# create some invisible bound for x, if needed
# self.x = max(min(self.x, 2), -2)

return new_y, x_disp

def move(self, dt=1/10):

# Time is 1/10 sec by default

propeller_speeds_same = (self.propeller_speed[1] == self.propeller_speed[2])

if propeller_speeds_same:
# calculate net force: total thrust by propeller weight of drone
F = self.thrust[1] + self.thrust[2] self.weight #net force, can be negative (downward) or positive (upward)

# calculate acceleration
a = F / self.mass

# calculate movement
new_y = self.y + (1/2) * a * dt**2 #+ self.y_velocity * dt 0.1 * self.y_velocity

new_y = max(new_y, 0)

#self.velocity = (new_y self.y) / dt

new_x = self.x

#add wind factor but only if drone has lift off
if new_y > 0:
new_x += self.wind_speed()

self.velocity = math.sqrt((new_y self.y)**2 + (new_x self.x)**2) / dt

self.y = new_y
self.x = new_x

else:# propeller speeds are not the same

# first calculate new_y for each side
new_y1, x_disp_1 = self.calc_one_side_move(1, dt) # left side
new_y2, x_disp_2 = self.calc_one_side_move(2, dt) # right side

new_y = 0.5 * (new_y1 + new_y2) # center point of the drone, approx as average of each sides y

#self.y_velocity = (new_y self.y) / dt

new_x1 = self.x + x_disp_1 self.length # left side
new_x2 = self.x + x_disp_2 + self.length # right side

# find the slope (roll)
# m = (new_y2 new_y1)/(new_x2 new_x1)

# find roll angle
self.roll_angle = math.atan2(new_y2 new_y1, new_x2 new_x1)
# For now 0 is pointing right (along x-axis)
# so tilt right will be negative

new_x = self.x + x_disp_1 + x_disp_2 # + self.x_velocity * dt 0.1 * self.x_velocity

#add wind factor but only if drone has lift off
if new_y > 0:
new_x += self.wind_speed()

self.velocity = math.sqrt((new_y self.y)**2 + (new_x self.x)**2) / dt
#self.x_velocity = (new_x self.x) / dt

self.y = new_y
self.x = new_x

def update_rotor_speed(self, thrust_chg, roll_chg):
thrust Change in thrust
roll change in roll

# Clip thrust change to max thrust change allowed per step
if thrust_chg != 0:
sign = thrust_chg/abs(thrust_chg)
thrust_chg = min(self.MAX_RPM_CHANGE_PER_STEP / self.RPM_TO_THRUST_RATIO, abs(thrust_chg))
thrust_chg *= sign

# Clip roll change to max roll change allowed
if roll_chg != 0:
roll_sign = roll_chg / abs(roll_chg)
roll_chg = min(self.MAX_ROLL_ANGLE, abs(roll_chg))
roll_chg *= roll_sign

#print(adjusted thrust = , thrust)
#print(adjusted roll = , roll)

self.propeller_speed[1] = min(max(0, self.propeller_speed[1] + thrust_chg*self.RPM_TO_THRUST_RATIO roll_chg*self.RPM_TO_ROLL_RATIO + self.RPM_ERROR), self.MAX_PROPELLER_SPEED)
self.propeller_speed[2] = min(max(0, self.propeller_speed[2] + thrust_chg*self.RPM_TO_THRUST_RATIO + roll_chg*self.RPM_TO_ROLL_RATIO + self.RPM_ERROR), self.MAX_PROPELLER_SPEED)

self.thrust[1] = self.propeller_speed[1]/self.RPM_TO_THRUST_RATIO
self.thrust[2] = self.propeller_speed[2]/self.RPM_TO_THRUST_RATIO

CS: assignmentchef QQ: 1823890830 Email: [email protected]

Reviews

There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.

Shopping Cart
[SOLVED] CS ######################################################################
$25