find the distance between a point and a curve python - python

How can I find the closet distance between my trajectory and (384400,0,0)?
Also, how can I the distance from (384400,0,0) to the path at time t = 197465?
I understand that the arrays have the data but is there a way to have it check the distance of all the points (x,y,z) and return what I am looking for?
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
me = 5.974 * 10 ** (24) # mass of the earth
mm = 7.348 * 10 ** (22) # mass of the moon
G = 6.67259 * 10 ** (-20) # gravitational parameter
re = 6378.0 # radius of the earth in km
rm = 1737.0 # radius of the moon in km
r12 = 384400.0 # distance between the CoM of the earth and moon
M = me + mm
pi1 = me / M
pi2 = mm / M
mue = 398600.0 # gravitational parameter of earth km^3/sec^2
mum = G * mm # grav param of the moon
mu = mue + mum
omega = np.sqrt(mu / r12 ** 3)
nu = -129.21 * np.pi / 180 # true anomaly angle in radian
x = 327156.0 - 4671
# x location where the moon's SOI effects the spacecraft with the offset of the
# Earth not being at (0,0) in the Earth-Moon system
y = 33050.0 # y location
vbo = 10.85 # velocity at burnout
gamma = 0 * np.pi / 180 # angle in radians of the flight path
vx = vbo * (np.sin(gamma) * np.cos(nu) - np.cos(gamma) * np.sin(nu))
# velocity of the bo in the x direction
vy = vbo * (np.sin(gamma) * np.sin(nu) + np.cos(gamma) * np.cos(nu))
# velocity of the bo in the y direction
xrel = (re + 300.0) * np.cos(nu) - pi2 * r12
# spacecraft x location relative to the earth
yrel = (re + 300.0) * np.sin(nu)
# r0 = [xrel, yrel, 0]
# v0 = [vx, vy, 0]
u0 = [xrel, yrel, 0, vx, vy, 0]
def deriv(u, dt):
n1 = -((mue * (u[0] + pi2 * r12) / np.sqrt((u[0] + pi2 * r12) ** 2
+ u[1] ** 2) ** 3)
- (mum * (u[0] - pi1 * r12) / np.sqrt((u[0] - pi1 * r12) ** 2
+ u[1] ** 2) ** 3))
n2 = -((mue * u[1] / np.sqrt((u[0] + pi2 * r12) ** 2 + u[1] ** 2) ** 3)
- (mum * u[1] / np.sqrt((u[0] - pi1 * r12) ** 2 + u[1] ** 2) ** 3))
return [u[3], # dotu[0] = u[3]
u[4], # dotu[1] = u[4]
u[5], # dotu[2] = u[5]
2 * omega * u[5] + omega ** 2 * u[0] + n1, # dotu[3] = that
omega ** 2 * u[1] - 2 * omega * u[4] + n2, # dotu[4] = that
0] # dotu[5] = 0
dt = np.arange(0.0, 320000.0, 1) # 200000 secs to run the simulation
u = odeint(deriv, u0, dt)
x, y, z, x2, y2, z2 = u.T
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z)
plt.show()

To find the distance along each point in the trajectory:
my_x, my_y, my_z = (384400,0,0)
delta_x = x - my_x
delta_y = y - my_y
delta_z = z - my_z
distance = np.sqrt(np.power(delta_x, 2) +
np.power(delta_y, 2) +
np.power(delta_z, 2))
And then to find the min and that specific distance:
i = np.argmin(distance)
t_min = i / UNITS_SCALE # I can't tell how many units to a second. Is it 1.6?
d_197465 = distance[int(197465 * UNITS_SCALE)]
PS, I'm no rocket scientist, and thus haven't actually checked the stuff above x, y, z, x2, y2, z2 = u.T. I'm assuming that those are your trajectory's position and velocity?

Related

Why is my code so slow using Numpy compared to Matlab

I'm sorry for my ignorance in using NumPy and python. I'm much more comfortable in Matlab however I've been required to convert my code from Matlab to Python. To run my script in Python takes 113 seconds meanwhile it takes 7 seconds in MATLAB. Both produce correct results albeit different due to stochasticity. The big culprit I believe is my derivative function. I profiled my python code and it says that this function accounts for 76% of the run time (It doesn't take up nearly as much percent-wise in MATLAB). I understand there is a lot of code so if anyone could help me with making my python derivative code perform more similarly to MATLAB that would be greatly appreciated! If you have any questions feel free to ask. Thank you!
Derivative6DOF.py
## Derivative6DOF Variables
# Input Variables
# x - vehicle state = [x, y, z, u, v, w, phi, theta, psi, p, q, r, omega1, omega2, omega3, omega4]'
# dt - time step
# bigOmegasTarget - commanded rotor speeds = [omega1, omega2, omega3, omega4]'
# batterySOC - percent battery charge remaining
# m - mass of vehicle
# g - gravitational acceleration constant
# I - moment of inertia = eye([I11, I22, I33]')
# Cd0 - Profile drag coefficient of each rotor
# pitch - pitch of blade
# rho - density of air
# a - lift curve slope of the airfoil
# b - number of blades
# c - chord length of blade
# R - total length of the rotor blade
# viGuessInitial - guess induced velocity
# posProps - position of propellers from center of gravity = [x, y, z]'
# A - area of propeller
# maxCapacity - max battery capacity
# powerDrawComponents - power drawn by components from battery
# Kv - voltage coefficient of motor [rad/sec/V]
# Kt - motor torque coefficent [N*m/A]
# voltMax - max voltage supplied
# resistanceMotor - resistance of motor
# PeMax - max power possible
# Jp - inertia about each motor (includes propellor and motor) [kg*m^2]
# Output Variables
# xdot - vehicle state derivative = [u, v, w, udot, vdot, zdot, p, q, r, pdot, qdot, rdot, omegadot1 omegadot2 omegadot3 omegadot4]'
# battery - battery state = [percentRemaining, dischargeRate]'
# k - thrust-to-omega coefficient (https://andrew.gibiansky.com/blog/physics/quadcopter-dynamics/#:~:text=Each#20rotor#20contributes#20some#20torque,CDAv2.)
# b_coeff - yaw-to-omega coefficient (https://andrew.gibiansky.com/blog/physics/quadcopter-dynamics/#:~:text=Each#20rotor#20contributes#20some#20torque,CDAv2.)
# Intermediate Variables
# DCM - rotation matrix from body frame to inertial frame
# UVWp - translational velocity at each propeller = [u, v, w]'
# theta0 - root blade angle
# theta1 - linear twist of blade
# T - thrust
# vi - induced velocity iterated guess
# vPrime - effective speed of flow at the rotor
# viCalc - induced velocity calculated
# Pinduced - induced power
# Pprofile - profile power
# Qp - rotor aerodynamic torque (current motor torque)
# totalThrust - sum of each rotor thrust
# QeMax - max electric motor torque possible
# PeMax - max electric power available
# Qe - electric motor torque (desired motor torque)
# ind - index
# Maero - aerodynamic pitching, rolling and yawing moments = [x, y, z]'
# H - hub forces = [x, y, z]'
# Mgyro - gyroscopic moments = [x, y, z]'
# Cl - coefficient of lift
# AR - aspect ratio
# Cd - coefficient of drag
# lx - distance of props in x-direction
# ly - distance of props in y-direction
# LScale - pitch scalar coefficient
# MScale - roll scalar coefficient
# NScale - yaw scalar coefficient
# MThrust - differential thrust = [x, y, z]'
# F - sum of all forces acting on vehicle
# M - sum of all moments acting on vehicle
# powerDrawMotors - sum of all power draw from all 4 motors
# totalPowerDraw - total power load on battery from all components (motors, camera, electronics, etc.)
# maxBatteryPower = maxCapacity*voltMax/1000; # (Whr) Max possible power from battery at start
# State Element Vector
# x - x-position
# y - y-position
# z - z-position
# u - x-velocity
# v - y-velocity
# w - z-velocity
# udot - x-acceleration
# vdot - y-acceleration
# wdot - z-acceleration
# phi - angle about y-axis
# theta - angle about x-axis
# psi - angle about z-axis
# p - angular velocity about y-axis
# q - angular velocity about x-axis
# r - angular velocity about z-axis
# pdot - angular acceleration about y-axis
# qdot - angular acceleration about x-axis
# rdot - angular acceleration about z-axis
# omega1 - angular speed of front left rotor
# omega2 - angular speed of back right rotor
# omega3 - angular speed of front right rotor
# omega4 - angular speed of back left rotor
# omegadot1 - angular acceleration of front left rotor
# omegadot2 - angular acceleration of back right rotor
# omegadot3 - angular acceleration of front right rotor
# omegadot4 - angular acceleration of back left rotor
# percentRemaining - percent battery charge remaining
# dischargeRate - discharge rate of battery
# Additional Notes
# Mgyro Derivation Code (Page 639)
# syms p q r Omega Jp
# omega = [0; 0; Jp*Omega]; rotation about positive z-axis
# skewMatrix = [0 -r q; r 0 -p; -q p 0];
# Mgyro = -skewMatrix*omega
import numpy as np
def Derivative6DOF(x,dt,bigOmegasTarget,batterySOC,m,g,I,Cd0,pitch,rho,a,b,c,R,viGuessInitial,posProps,A,maxCapacity,powerDrawComponents,Kv,Kt,voltMax,resistanceMotor,PeMax,Jp,processNoise,theta0,theta1):
# direction cosine matrix (from bodyframe to NED)
DCM = np.array([[np.cos(x[8]) * np.cos(x[7]),- np.sin(x[8]) * np.cos(x[6]) + np.cos(x[8]) * np.sin(x[7]) * np.sin(x[6]),np.sin(x[8]) * np.sin(x[6]) + np.cos(x[8]) * np.cos(x[6]) * np.sin(x[7])],[np.cos(x[7]) * np.sin(x[8]),np.cos(x[8]) * np.cos(x[6]) + np.sin(x[8]) * np.sin(x[7]) * np.sin(x[6]),- np.cos(x[8]) * np.sin(x[6]) + np.sin(x[8]) * np.cos(x[6]) * np.sin(x[7])],[- np.sin(x[7]),np.sin(x[6]) * np.cos(x[7]),np.cos(x[7]) * np.cos(x[6])]])
# propeller velocity
UVWp = np.zeros((4,3))
for i in range(0,4):
UVWp[i,:] = x[3:6] + np.cross(x[9:12],posProps[i,:])
T = np.zeros((4,))
vi = np.ones((4,)) * viGuessInitial
# induced velocity for each rotor
for i in range(0,4):
# induced velocity
vPrime = np.sqrt(UVWp[i,0] ** 2 + UVWp[i,1] ** 2 + (UVWp[i,2] - vi[i]) ** 2)
T[i] = rho * a * b * c * R / 4 * ((UVWp[i,2] - vi[i]) * x[12 + i] * R + 2 / 3 * (x[12 + i] * R) ** 2 * (theta0 + 0.75 * theta1) + (UVWp[i,0] ** 2 + (UVWp[i,1] ** 2)) * (theta0 + 0.5 * theta1))
viCalc = T[i] / (2 * rho * A * vPrime)
# converge iterated induced velocity and calculated induced velocity
while np.abs(vi[i] - viCalc) > 1e-05:
# induced velocity
vPrime = np.sqrt(UVWp[i,0] ** 2 + UVWp[i,1] ** 2 + (UVWp[i,2] - vi[i]) ** 2)
T[i] = rho * a * b * c * R / 4 * ((UVWp[i,2] - vi[i]) * x[12 + i] * R + 2 / 3 * (x[12 + i] * R) ** 2 * (theta0 + 0.75 * theta1) + (UVWp[i,0] ** 2 + (UVWp[i,1] ** 2)) * (theta0 + 0.5 * theta1))
viCalc = T[i] / (2 * rho * A * vPrime)
# increment the induced velocity guess
vi[i] = vi[i] + 0.1 * (viCalc - vi[i])
# calculate induced power, profile power, and rotor aerodynamic torque for each rotor
Pinduced = T*(vi-UVWp[:,2])
Pprofile = (rho*Cd0*b*c*x[12:16]*R**2/8 * ((x[12:16]*R)**2 + UVWp[:,0]**2 + UVWp[:,1]**2))
Qp = 1/x[12:16]*(Pinduced + Pprofile)
# calculate total thrust
totalThrust = np.array([[0],[0],[-np.sum(T)]]).reshape((3,))
# calculate electric motor torque
QeMax = PeMax / x[12:16]
Qe = (Kt / resistanceMotor) * (bigOmegasTarget - x[12:16]) / Kv
# confirm electric motor torque isn't exceeding limit
np.where(Qe > QeMax, Qe, QeMax)
# calculate aerodynamic pitching, rolling, and yawing moments
Maero = np.zeros((3,))
Maero[0] = np.sum(np.array([[- 1],[- 1],[1],[1]]) * rho * a * b * c * R**2 * (x[12:16] * R**2 / 16 * x[9] + ((UVWp[:,2] - vi) / 8 + x[12:16] * R * theta0 / 6 + x[12:16] * R * theta1 / 8) * UVWp[:,0]))
Maero[1] = np.sum(np.array([[- 1],[- 1],[1],[1]]) * rho * a * b * c * R**2 * (x[12:16] * R**2 / 16 * x[10] + ((UVWp[:,2] - vi) / 8 + x[12:16] * R * theta0 / 6 + x[12:16] * R * theta1 / 8) * UVWp[:,1]))
Maero[2] = np.sum(np.array([[- 1],[- 1],[1],[1]]) * Qe)
# calculate hub force
H = -np.sign(x[3:6]) * np.sum(rho * Cd0 * b * c * x[12:16] * R**2 / 4 * np.array([UVWp[:,0],UVWp[:,1],np.array([[0],[0],[0],[0]]).reshape(4,)]))
# calculate gyroscopic moments
Mgyro = np.sum(x[12:16] * np.array([[-1],[-1],[1],[1]]).reshape(4,)) * Jp * np.array([-x[10], x[9], 0]).reshape((3,))
# calculate thrust-to-omega coefficient
k = T / x[12:16]**2
# calculate yaw-to-omega coefficient
Cl = 2 * T / (rho * R**2 * x[12:16]**2)
AR = R**2 / A
Cd = Cd0 + Cl**2 / (np.pi * AR * 1)
b_coeff = 0.5 * R ** 3 * rho * Cd * A
# calculate motor-mixer scalar coefficients
lx = np.abs(posProps[:,0])
ly = np.abs(posProps[:,1])
LScale = k * ly
MScale = k * lx
NScale = b_coeff
# calculate differential thrust
MThrust = np.zeros((3,))
MThrust[0] = np.sum(x[12:16]**2 * np.array([1,-1,-1,1]).reshape((4,)) * LScale)
MThrust[1] = np.sum(x[12:16]**2 * np.array([1,-1,1,-1]).reshape((4,)) * MScale)
MThrust[2] = np.sum(x[12:16]**2 * np.array([-1,-1,1,1]).reshape((4,)) * NScale)
# total force and moment acting on quadcopter in inertial frame
F = DCM # (totalThrust + H)
M = DCM # (Maero + Mgyro + MThrust)
# calculate state derivative
xdot = np.zeros((16,))
xdot[0:3] = np.array([x[3],x[4],x[5]])
xdot[3] = F[0] / m
xdot[4] = F[1] / m
xdot[5] = g + F[2] / m
xdot[6] = x[9] + np.tan(x[7]) * np.sin(x[6]) * x[10] + np.tan(x[7]) * np.cos(x[6]) * x[11]
xdot[7] = np.cos(x[6]) * x[10] - np.sin(x[6]) * x[11]
xdot[8] = 1/np.cos(x[7]) * np.sin(x[6]) * x[10] + 1/np.cos(x[7]) * np.cos(x[6]) * x[11]
xdot[9] = (M[0] + x[10] * x[11] * (I[1,1] - I[2,2])) / I[0,0]
xdot[10] = (M[1] + x[9] * x[11] * (I[2,2] - I[0,0])) / I[1,1]
xdot[11] = (M[2] + x[9] * x[10] * (I[0,0] - I[1,1])) / I[2,2]
xdot[12:16] = 1/Jp * (Qe - Qp)
xdot = xdot + np.random.randn(16,) * processNoise
# calculate battery state
powerDrawMotors = np.sum(Qp * x[12:16])
totalPowerDraw = powerDrawMotors + powerDrawComponents
maxBatteryPower = maxCapacity * voltMax / 1000
discharge = totalPowerDraw * dt / 3600 / maxBatteryPower * 100
batterySOC = batterySOC - discharge
battery = np.array([[batterySOC],[discharge]]).reshape((2,))
return xdot,battery,k,b_coeff,vi

Converting British National Grid Co-ordinates to WGS64 Latitude and Longitude in Python

I am having trouble converting a table of Eastings/Northings co-ordinates from the British National Grid System to Latitude/Longitude co-ordinates in the WGS84 system. I have written the below set of functions with constants from the Ordnance Survey's Helmert transformation spreadsheet: https://www.ordnancesurvey.co.uk/business-government/tools-support/os-net/coordinates
import math
import pandas as pd
North = 666099.000 # Northing to be transformed
East = 253697.000 # Easting to be transformed
a = 6377563.396 # Semi-major axis for OGSB36
#a = 6378137.0000 # Semi-major axis for WGS84
b = 6356256.909 # Semi-minor axis for OGSB36
#b = 6356752.3142 # Semi-minor axis for WGS84
f0 = 0.9996012717 # Central Meridan Scale
e0 = 400000 # True origin Easting
n0 = -100000 # True origin Northing
PHI0 = 0.855211333 # True origin latitude (Radians) i.e. N 49 0' 0''
DecimalPHI0 = 49.00000000 # True origin latitude (Degrees)
LAM0 = -0.034906585 # True origin longitude (Radians) i.e. W 2 0' 0''
DecimalLAM0 = -2.00000000 # True origin longitude (Degrees)
def InitialLat(North, n0, af0, PHI0, n, bf0):
"""
Compute initial value for Latitude (PHI) IN RADIANS.
Input:
- northing of point (North) and northing of false origin (n0) in meters;
- semi major axis multiplied by central meridian scale factor (af0) in meters;
- latitude of false origin (PHI0) IN RADIANS;
- n (computed from a, b and f0) and
- ellipsoid semi major axis multiplied by central meridian scale factor (bf0) in meters.
"""
#First PHI value (PHI1)
PHI1 = ((North - n0) / af0) + PHI0
def Marc(bf0, n, PHI0, PHI1):
"""
Compute meridional arc.
Input:
- ellipsoid semi major axis multiplied by central meridian scale factor (bf0) in meters;
- n (computed from a, b and f0);
- lat of false origin (PHI0) and initial or final latitude of point (PHI) IN RADIANS.
"""
Marc = bf0 * (((1 + n + ((5 / 4) * (n ** 2)) + ((5 / 4) * (n ** 3))) * (PHI1 - PHI0))
- (((3 * n) + (3 * (n ** 2)) + ((21 / 8) * (n ** 3))) * (math.sin(PHI1 - PHI0)) * (math.cos(PHI1 + PHI0)))
+ ((((15 / 8) * (n ** 2)) + ((15 / 8) * (n ** 3))) * (math.sin(2 * (PHI1 - PHI0))) * (math.cos(2 * (PHI1 + PHI0))))
- (((35 / 24) * (n ** 3)) * (math.sin(3 * (PHI1 - PHI0))) * (math.cos(3 * (PHI1 + PHI0)))))
return Marc
# Calculate M
M = Marc(bf0, n, PHI0, PHI1)
#Calculate new PHI value (PHI2)
PHI2 = ((North - n0 - M) / af0) + PHI1
#Iterate to get final value for InitialLat
while abs(North - n0 - M) > 0.00001:
PHI2 = ((North - n0 - M) / af0) + PHI1
M = Marc(bf0, n, PHI0, PHI2)
PHI1 = PHI2
InitialLat = PHI2
return InitialLat
def E_N_to_Lat(East, North, a, b, e0, n0, f0, PHI0, LAM0):
"""
Un-project Transverse Mercator eastings and northings back to latitude.
Input:
- eastings (East) and northings (North) in meters; _
- ellipsoid axis dimensions (a & b) in meters; _
- eastings (e0) and northings (n0) of false origin in meters; _
- central meridian scale factor (f0) and _
- latitude (PHI0) and longitude (LAM0) of false origin in decimal degrees.
"""
#Convert angle measures to radians
Pi = math.pi
RadPHI0 = PHI0 * (Pi / 180)
RadLAM0 = LAM0 * (Pi / 180)
# Compute af0, bf0, e squared (e2), n and Et
af0 = a * f0
bf0 = b * f0
e2 = ((af0 ** 2) - (bf0 ** 2)) / (af0 ** 2)
n = (af0 - bf0) / (af0 + bf0)
Et = East - e0
# Compute initial value for latitude (PHI) in radians
PHId = InitialLat(North, n0, af0, RadPHI0, n, bf0)
# Compute nu, rho and eta2 using value for PHId
nu = af0 / (math.sqrt(1 - (e2 * ((math.sin(PHId)) ** 2))))
rho = (nu * (1 - e2)) / (1 - (e2 * (math.sin(PHId)) ** 2))
eta2 = (nu / rho) - 1
# Compute Latitude
VII = (math.tan(PHId)) / (2 * rho * nu)
VIII = ((math.tan(PHId)) / (24 * rho * (nu ** 3))) * (5 + (3 * ((math.tan(PHId)) ** 2)) + eta2 - (9 * eta2 * ((math.tan(PHId)) ** 2)))
IX = ((math.tan(PHId)) / (720 * rho * (nu ** 5))) * (61 + (90 * ((math.tan(PHId)) ** 2)) + (45 * ((math.tan(PHId)) ** 4)))
E_N_Lat = (180 / Pi) * (PHId - ((Et ** 2) * VII) + ((Et ** 4) * VIII) - ((Et ** 6) * IX))
return(E_N_Lat)
def E_N_to_Long(East, North, a, b, e0, n0, f0, PHI0, LAM0):
"""
Un-project Transverse Mercator eastings and northings back to longitude.
Input:
- eastings (East) and northings (North) in meters;
- ellipsoid axis dimensions (a & b) in meters;
- eastings (e0) and northings (n0) of false origin in meters;
- central meridian scale factor (f0) and
- latitude (PHI0) and longitude (LAM0) of false origin in decimal degrees.
"""
# Convert angle measures to radians
Pi = 3.14159265358979
RadPHI0 = PHI0 * (Pi / 180)
RadLAM0 = LAM0 * (Pi / 180)
# Compute af0, bf0, e squared (e2), n and Et
af0 = a * f0
bf0 = b * f0
e2 = ((af0 ** 2) - (bf0 ** 2)) / (af0 ** 2)
n = (af0 - bf0) / (af0 + bf0)
Et = East - e0
# Compute initial value for latitude (PHI) in radians
PHId = InitialLat(North, n0, af0, RadPHI0, n, bf0)
# Compute nu, rho and eta2 using value for PHId
nu = af0 / (math.sqrt(1 - (e2 * ((math.sin(PHId)) ** 2))))
rho = (nu * (1 - e2)) / (1 - (e2 * (math.sin(PHId)) ** 2))
eta2 = (nu / rho) - 1
# Compute Longitude
X = ((math.cos(PHId)) ** -1) / nu
XI = (((math.cos(PHId)) ** -1) / (6 * (nu ** 3))) * ((nu / rho) + (2 * ((math.tan(PHId)) ** 2)))
XII = (((math.cos(PHId)) ** -1) / (120 * (nu ** 5))) * (5 + (28 * ((math.tan(PHId)) ** 2)) + (24 * ((math.tan(PHId)) ** 4)))
XIIA = (((math.cos(PHId)) ** -1) / (5040 * (nu ** 7))) * (61 + (662 * ((math.tan(PHId)) ** 2)) + (1320 * ((math.tan(PHId)) ** 4)) + (720 * ((math.tan(PHId)) ** 6)))
E_N_Long = (180 / Pi) * (RadLAM0 + (Et * X) - ((Et ** 3) * XI) + ((Et ** 5) * XII) - ((Et ** 7) * XIIA))
return E_N_Long
def E_N_to_Lat_Long(North, East):
Lat = E_N_to_Lat(East,North,a,b,e0,n0,f0,DecimalPHI0,DecimalLAM0)
Long = E_N_to_Long(East,North,a,b,e0,n0,f0,DecimalPHI0,DecimalLAM0)
return [Lat, Long]
This all runs fine but it only has a conversion accuracy of +/- 3m or so which isn't good enough for the application I need it for. Is there a better alternative for converting several thousand co-ordinates using Python?
Here are a couple of python libraries for converting from WGS84 to BNG, both utilise OSTN15 for accurate conversions:
https://github.com/urschrei/convertbng
https://grid-banger.readthedocs.io/en/latest/README.html
More info from OS can be found here: https://www.ordnancesurvey.co.uk/documents/resources/guide-coordinate-systems-great-britain.pdf

Scipy odeint. Gravitational motion

I solve the motion in gravitational field around the sun with scipy and mathplotlib and have a problem. My solution is not correct. It is not like in example. Formulas that I used.
from scipy.integrate import odeint
import scipy.constants as constants
import numpy as np
import matplotlib.pyplot as plt
M = 1.989 * (10 ** 30)
G = constants.G
alpha = 30
alpha0 = (alpha / 180) * np.pi
v00 = 0.7
v0 = v00 * 1000
def dqdt(q, t):
x = q[0]
y = q[2]
ax = - G * M * (x / ((x ** 2 + y ** 2) ** 1.5))
ay = - G * M * (y / ((x ** 2 + y ** 2) ** 1.5))
return [q[1], ax, q[3], ay]
vx0 = v0 * np.cos(alpha0)
vy0 = v0 * np.sin(alpha0)
x0 = -150 * (10 ** 11)
y0 = 0 * (10 ** 11)
q0 = [x0, vx0, y0, vy0]
N = 1000000
t = np.linspace(0.0, 100000000000.0, N)
pos = odeint(dqdt, q0, t)
x1 = pos[:, 0]
y1 = pos[:, 2]
plt.plot(x1, y1, 0, 0, 'ro')
plt.ylabel('y')
plt.xlabel('x')
plt.grid(True)
plt.show()
How can I fix this?
Maybe you can tell me solution with another method for example with Euler's formula or with using other library.
I will be very greatful if you help me.

Plot a ball rolling down a curve

I want to "animate" a circle rolling over the sin graph, I made a code where the circle moves rapidly down a straight line, now I want the same but the acceleration will be changing.
My previous code:
import numpy as np
import matplotlib.pyplot as plt
theta = np.arange(0, np.pi * 2, (0.01 * np.pi))
x = np.arange(-50, 1, 1)
y = x - 7
plt.figure()
for t in np.arange(0, 4, 0.1):
plt.plot(x, y)
xc = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.cos(theta))
yc = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.sin(theta))
plt.plot(xc, yc, 'r')
xp = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.cos(np.pi * t))
yp = ((-9.81 * t**2 * np.sin(np.pi / 2)) / 3) + (5 * np.sin(np.pi * t))
plt.plot(xp, yp, 'bo')
plt.pause(0.01)
plt.cla()
plt.show()
You can do this by numerically integrating:
dt = 0.01
lst_x = []
lst_y = []
t = 0
while t < 10: #for instance
t += dt
a = get_acceleration(function, x)
x += v * dt + 0.5 * a * dt * dt
v += a * dt
y = get_position(fuction, x)
lst_x.append(x)
lst_y.append(y)
This is assuming the ball never leaves your slope! If it does, you'll also have to integrate in y in a similar way as done in x!!
Where your acceleration is going to be equal to g * cos(slope).

minimum distance from an array [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I followed this method from my other post [distance between a point and a curve[(find the distance between a point and a curve python) but something is wrong. The values aren't accurate.
I plotted this same trajectory in Mathematica and checked a few distances and I have found distances as low as 18000 where python is returning a minimum of 209000.
What is going wrong in the code at the bottom?
EDIT There was an error in this code everything checks out now. Thanks.
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
me = 5.974 * 10 ** (24) # mass of the earth
mm = 7.348 * 10 ** (22) # mass of the moon
G = 6.67259 * 10 ** (-20) # gravitational parameter
re = 6378.0 # radius of the earth in km
rm = 1737.0 # radius of the moon in km
r12 = 384400.0 # distance between the CoM of the earth and moon
M = me + mm
pi1 = me / M
pi2 = mm / M
mue = 398600.0 # gravitational parameter of earth km^3/sec^2
mum = G * mm # grav param of the moon
mu = mue + mum
omega = np.sqrt(mu / r12 ** 3)
nu = -129.21 * np.pi / 180 # true anomaly angle in radian
x = 327156.0 - 4671
# x location where the moon's SOI effects the spacecraft with the offset of the
# Earth not being at (0,0) in the Earth-Moon system
y = 33050.0 # y location
vbo = 10.85 # velocity at burnout
gamma = 0 * np.pi / 180 # angle in radians of the flight path
vx = vbo * (np.sin(gamma) * np.cos(nu) - np.cos(gamma) * np.sin(nu))
# velocity of the bo in the x direction
vy = vbo * (np.sin(gamma) * np.sin(nu) + np.cos(gamma) * np.cos(nu))
# velocity of the bo in the y direction
xrel = (re + 300.0) * np.cos(nu) - pi2 * r12
# spacecraft x location relative to the earth
yrel = (re + 300.0) * np.sin(nu)
# r0 = [xrel, yrel, 0]
# v0 = [vx, vy, 0]
u0 = [xrel, yrel, 0, vx, vy, 0]
def deriv(u, dt):
n1 = -((mue * (u[0] + pi2 * r12) / np.sqrt((u[0] + pi2 * r12) ** 2
+ u[1] ** 2) ** 3)
- (mum * (u[0] - pi1 * r12) / np.sqrt((u[0] - pi1 * r12) ** 2
+ u[1] ** 2) ** 3))
n2 = -((mue * u[1] / np.sqrt((u[0] + pi2 * r12) ** 2 + u[1] ** 2) ** 3)
- (mum * u[1] / np.sqrt((u[0] - pi1 * r12) ** 2 + u[1] ** 2) ** 3))
return [u[3], # dotu[0] = u[3]
u[4], # dotu[1] = u[4]
u[5], # dotu[2] = u[5]
2 * omega * u[5] + omega ** 2 * u[0] + n1, # dotu[3] = that
omega ** 2 * u[1] - 2 * omega * u[4] + n2, # dotu[4] = that
0] # dotu[5] = 0
dt = np.arange(0.0, 320000.0, 1) # 200000 secs to run the simulation
u = odeint(deriv, u0, dt)
x, y, z, x2, y2, z2 = u.T
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z)
plt.show()
my_x, my_y, my_z = (384400,0,0)
delta_x = x - my_x
delta_y = y - my_y
delta_z = z - my_z
distance = np.array([np.sqrt(delta_x ** 2 + delta_y ** 2 +
delta_z ** 2)])
print(distance.min())
Corrected code
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
me = 5.974 * 10 ** (24) # mass of the earth
mm = 7.348 * 10 ** (22) # mass of the moon
G = 6.67259 * 10 ** (-20) # gravitational parameter
re = 6378.0 # radius of the earth in km
rm = 1737.0 # radius of the moon in km
r12 = 384400.0 # distance between the CoM of the earth and moon
M = me + mm
pi1 = me / M
pi2 = mm / M
mue = 398600.0 # gravitational parameter of earth km^3/sec^2
mum = G * mm # grav param of the moon
mu = mue + mum
omega = np.sqrt(mu / r12 ** 3)
nu = -129.21 * np.pi / 180 # true anomaly angle in radian
x = 327156.0 - 4671
# x location where the moon's SOI effects the spacecraft with the offset of the
# Earth not being at (0,0) in the Earth-Moon system
y = 33050.0 # y location
vbo = 10.85 # velocity at burnout
gamma = 0 * np.pi / 180 # angle in radians of the flight path
vx = vbo * (np.sin(gamma) * np.cos(nu) - np.cos(gamma) * np.sin(nu))
# velocity of the bo in the x direction
vy = vbo * (np.sin(gamma) * np.sin(nu) + np.cos(gamma) * np.cos(nu))
# velocity of the bo in the y direction
xrel = (re + 300.0) * np.cos(nu) - pi2 * r12
# spacecraft x location relative to the earth
yrel = (re + 300.0) * np.sin(nu)
# r0 = [xrel, yrel, 0]
# v0 = [vx, vy, 0]
u0 = [xrel, yrel, 0, vx, vy, 0]
def deriv(u, dt):
n1 = -((mue * (u[0] + pi2 * r12) / np.sqrt((u[0] + pi2 * r12) ** 2
+ u[1] ** 2) ** 3)
- (mum * (u[0] - pi1 * r12) / np.sqrt((u[0] - pi1 * r12) ** 2
+ u[1] ** 2) ** 3))
n2 = -((mue * u[1] / np.sqrt((u[0] + pi2 * r12) ** 2 + u[1] ** 2) ** 3)
- (mum * u[1] / np.sqrt((u[0] - pi1 * r12) ** 2 + u[1] ** 2) ** 3))
return [u[3], # dotu[0] = u[3]
u[4], # dotu[1] = u[4]
u[5], # dotu[2] = u[5]
2 * omega * u[4] + omega ** 2 * u[0] + n1, # dotu[3] = that
omega ** 2 * u[1] - 2 * omega * u[3] + n2, # dotu[4] = that
0] # dotu[5] = 0
dt = np.arange(0.0, 320000.0, 1) # 200000 secs to run the simulation
u = odeint(deriv, u0, dt)
x, y, z, x2, y2, z2 = u.T
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot(x, y, z)
plt.show()
my_x, my_y, my_z = (384400,0,0)
delta_x = x - my_x
delta_y = y - my_y
delta_z = z - my_z
distance = np.array([np.sqrt(delta_x ** 2 + delta_y ** 2 +
delta_z ** 2)])
print(distance.min())

Categories