我一直在编写一段代码,目的是创建一个文本文件并在其中存储一个数字,以及创建一个图像文件夹,用于存储 picamera 捕获的图像。昨晚它运行得非常好,但我删除了图像文件夹并尝试今天再次运行它,但它很糟糕,它根本不起作用。它总是给我一个权限错误 13,权限被拒绝。这很奇怪,因为当我将代码复制并粘贴到 replit 中时,它会按预期运行。但它在 Thonny 或 Pycharm 中根本不起作用。 我什至尝试从代码中完全删除图像函数,但它仍然显示相同的错误消息。
这是代码:
import os
import time
from picamera import PiCamera
from exif import Image
from datetime import datetime
from math import radians, sin, cos, sqrt, atan2
import shutil
from pathlib import Path
# find base folder and set up results and images folder
base_folder = Path(__file__).parent.resolve()
data_file = base_folder / "results.txt"
image_folder = base_folder / "images"
if not image_folder.exists():
image_folder.mkdir(parents=True, exist_ok=True)
# Initialize PiCamera
camera = PiCamera()
# Initialize variables
latitude1 = longitude1 = latitude2 = longitude2 = None
time1 = time2 = 0
total_speed = 0
speed_counter = 0
ISS_altitude_km = 422
multiplier = 0
image_counter = 0
def distance_to_centre(latitude1, latitude2):
"""
using the WGS 84 model of the Earth to more accurately determine the distance between the centre of the Earth and ISS.
using this model also allows for speed to be more accurately modelled at the poles where the Earth is flatter
"""
# Convert latitude and longitude from degrees to radians
lat_rad1 = radians(latitude1)
lat_rad2 = radians(latitude2)
# Earth's radius at the given latitude
earth_radius = 6371.0 # Average Earth radius in kilometers
r_latitude1 = earth_radius * (1 - 0.00669437999014 * (sin(lat_rad1) ** 2))**0.5
r_latitude2 = earth_radius * (1 - 0.00669437999014 * (sin(lat_rad2) ** 2))**0.5
r_latitude_average = 0.5 * (r_latitude1 + r_latitude2)
# Altitude above the Earth's reference ellipsoid
altitude = r_latitude_average / 1000
# Distance from point to center of the Earth
distance_to_center = altitude + earth_radius
return distance_to_center
def extract_coordinates(image_path):
"""
searches through the metadata of an image to find latitude and longitude positions, as well as time taken
"""
# Extract latitude, longitude, and time from the new image metadata
with open(image_path, 'rb') as img_file:
image = Image(img_file)
# Extract degrees, minutes, and seconds
lat_degrees, lat_minutes, lat_seconds = image.gps_latitude
lon_degrees, lon_minutes, lon_seconds = image.gps_longitude
# Convert to decimal degrees
latitude = lat_degrees + lat_minutes / 60 + lat_seconds / 3600
longitude = lon_degrees + lon_minutes / 60 + lon_seconds / 3600
# work out time at which photo was taken
time = datetime.strptime(image.datetime_original, "%Y:%m:%d %H:%M:%S")
return latitude, longitude, time
def calculate_multiplier(latitude1, latitude2):
"""
takes into account increased acceleration near the equation due to Earth's surface being closer to the ISS at the equator (as modelled by WGS 84).
allows for a scale factor to be calculated in order to determine by how much linear speed had increased as a result of higher gravitational forces at equator on ISS
"""
# Calculate the average latitude
average_latitude = (latitude1 + latitude2) / 2
# Calculate the multiplier based on average latitude
equator_multiplier = 1.05
polar_multiplier = 1.0
multiplier = equator_multiplier - (equator_multiplier - polar_multiplier) * abs(average_latitude) / 90
return multiplier
def haversign(latitude1, longitude1, latitude2, longitude2):
"""
calculates the great-circle distance between two points on a sphere
Earth is being modelled as a sphere in this formula. C represents the central angle.
This central angle can be multiplied by the distance from the centre of the Earth in order to estimate distance travelled between snapshots
Haversign is able to compute good estimates for linear speed, but not precise ones.
We can use our WGS 84 model, as well as our calculate_multiplier function to simulate the oval-like shape of the Earth in conjunction with the Haversign formula to gain more precise reading.
"""
# Calculate c constant in Haversign formula
lat1, lon1 = radians(latitude1), radians(longitude1)
lat2, lon2 = radians(latitude2), radians(longitude2)
delta_lat = lat2 - lat1
delta_lon = lon2 - lon1
a = sin(delta_lat / 2) ** 2 + cos(lat1) * cos(lat2) * sin(delta_lon / 2) ** 2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
return c
def store_image(image_path):
"""
Store the image in the images folder if the total size of stored images does not exceed 250MB.
"""
global image_counter
if image_counter < 42:
image_path = Path(image_path) # Convert to Path object
new_image_path = image_folder # destination path
image_size = os.path.getsize(image_path)
total_size = sum(os.path.getsize(f) for f in image_folder.glob('*'))
# Check if adding the new image exceeds the limit
if total_size + image_size <= 250 * 1024 * 1024:
# Move the image to the images folder
shutil.move(image_path, new_image_path)
image_counter += 1
def main():
global total_speed, speed_counter # declaring total_speed and speed_counter as global variables so interpreter won't confuse them as local
# Loop for 10 minutes
start_time = time.time()
while time.time() - start_time < 540: # 600 seconds = 10 minutes
# Capture image
image_path = f"image_{int(time.time())}.jpg"
camera.capture(image_path)
# extract coordinates and find time at which image was taken
latitude1, longitude1, time1 = extract_coordinates(image_path)
# storing image if possible
store_image(image_path)
# Wait for 10 seconds between pictures
time.sleep(10)
# Capture another image
image_path = f"image_{int(time.time())}.jpg"
camera.capture(image_path)
# extract new coordinates and find new time at which image was taken
latitude2, longitude2, time2 = extract_coordinates(image_path)
# storing new image
store_image(image_path)
# Calculate time difference between the two pictures
time_diff = (time2 - time1).total_seconds() # in seconds
# Calculate c constant in Haversign formula
c = haversign(latitude1, longitude1, latitude2, longitude2)
# Calculate distance (including altitude) between two points
distance_to_centre_of_earth = distance_to_centre(latitude1, latitude2)
distance = (distance_to_centre_of_earth + ISS_altitude_km) * c
# Calculate speed
multiplier = calculate_multiplier(latitude1, latitude2)
speed = (distance / time_diff) * multiplier # km/s
total_speed = total_speed + speed
speed_counter = speed_counter + 1
# Final calculation
average_speed = total_speed / speed_counter
answer = "{:.4f}".format(average_speed) # giving answer to 5 s.f.
# Writing to results file
output_string = answer
with open(data_file, 'w') as file:
file.write(output_string)
main()
camera.close
您可以尝试将以下内容添加到第 15 行代码的括号中吗?
模式=0o755
我经验不多。我希望它有效。