I've been writing a piece of code with the purpose of creating a text file and storing a number in it, as well as creating an images folder which it will store images caught by a picamera. It worked amazingly well last night but I deleted the images folder and tried to run it again today but it was dreadful, it didn't work at all. It always gives me a Permission Error 13, Permission denied. It's strange because when I copy and paste my code into replit, it'll run as intended. But it will not work at all in Thonny or Pycharm. I've even tried removing the image function completely from the code but it still shows the same error message.
Here was the code:
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
Here was the exact error message:
Traceback (most recent call last): File "C:\Users\armaa\AppData\Local\Programs\Thonny\lib\runpy.py", line 196, in _run_module_as_main return _run_code(code, main_globals, None, File "C:\Users\armaa\AppData\Local\Programs\Thonny\lib\runpy.py", line 86, in _run_code exec(code, run_globals) File "C:\Users\armaa\AppData\Roaming\Python\Python310\Scripts\Astro-Pi-Replay.exe\__main__.py", line 7, in <module> File "C:\Users\armaa\AppData\Roaming\Python\Python310\site-packages\astro_pi_replay\main.py", line 263, in main _main(args) File "C:\Users\armaa\AppData\Roaming\Python\Python310\site-packages\astro_pi_replay\main.py", line 221, in _main AstroPiExecutor.run(args.mode, args.venv_dir, args.main, args.debug) File "C:\Users\armaa\AppData\Roaming\Python\Python310\site-packages\astro_pi_replay\executor.py", line 578, in run main = AstroPiExecutor.add_name_is_main_guard(main) File "C:\Users\armaa\AppData\Roaming\Python\Python310\site-packages\astro_pi_replay\executor.py", line 402, in add_name_is_main_guard shutil.copy2(main, original_main) File "C:\Users\armaa\AppData\Local\Programs\Thonny\lib\shutil.py", line 434, in copy2 copyfile(src, dst, follow_symlinks=follow_symlinks) File "C:\Users\armaa\AppData\Local\Programs\Thonny\lib\shutil.py", line 256, in copyfile with open(dst, 'wb') as fdst: PermissionError: [Errno 13] Permission denied: 'C:\\Users\\armaa\\AppData\\Local\\Temp\\astro_pi_replay\\original_main.py'
Can you try adding the following to the parentheses in the code on line 15?
mode=0o755
I'm not very experienced. I hope it works.