Cam Angle Calculation with Polynomial 3
Mechanical Cam angle calculation with length input using polynomial 3 with numpy polyfit
Formulaâ
Angle = (a * Length^3) + (b * Length^2) + (c * Length) + d)
Calculationâ
Python code for calculating the coefficients a, b, c, and d
import pandas as pd
import numpy as np
import argparse
import sys
def calculate_coefficients(file_name):
"""
Calculates the coefficients a, b, c, and d for the cubic formula:
Angle = a * Length^3 + b * Length^2 + c * Length + d
The script explicitly selects columns by index to handle CSV formatting issues.
"""
try:
# Print status messages to stderr (ensures they appear even if stdout is redirected)
print(f"--- Attempting to process file: {file_name} ---", file=sys.stderr)
# 1. Load the CSV. header=2 is used to position the header row.
df = pd.read_csv(file_name, header=2)
# 2. Select the third and fourth columns (index 1 and 2), which contain Angle and Length.
df_clean = df.iloc[:, [1, 2]].copy()
# 3. Explicitly rename columns. Based on the data, the column at index 1 is Angle (0, 2, 4...)
# and index 2 is Length (0.00, 0.01, 0.06...).
df_clean.columns = ['Angle', 'Length']
# Continue with cleaning
df_clean = df_clean.dropna()
if df_clean.empty:
raise ValueError("Data frame is empty after reading or cleaning (check file contents/columns).")
# Define independent (x) and dependent (y) variables
# Length is the independent variable (X), Angle is the dependent (Y)
x = df_clean['Length']
y = df_clean['Angle']
# Perform a degree 3 polynomial fit (cubic)
# polyfit returns coefficients in order of highest power to lowest: (a, b, c, d)
coefficients = np.polyfit(x, y, 3)
a, b, c, d = coefficients
# --- Output the final results to standard output (stdout) ---
print("\n--- Final Cubic Polynomial Regression Coefficients ---")
print(f"Model: Angle = (a * Length^3) + (b * Length^2) + (c * Length) + d")
print(f"a (Length^3 coefficient): {a}")
print(f"b (Length^2 coefficient): {b}")
print(f"c (Length^1 coefficient): {c}")
print(f"d (Constant term): {d}")
except FileNotFoundError:
print(f"\nERROR: File not found. Check the path and file name: {file_name}", file=sys.stderr)
except KeyError as e:
# This should no longer happen with the .iloc fix, but kept for general robustness
print(f"\nERROR: Column names 'Angle' or 'Length' not found. KeyError: {e}", file=sys.stderr)
except ValueError as e:
print(f"\nERROR: Data processing issue: {e}", file=sys.stderr)
except Exception as e:
print(f"\nAn unexpected error occurred during calculation: {e}", file=sys.stderr)
if __name__ == '__main__':
# Set up argument parser to read the -file_name flag
parser = argparse.ArgumentParser(description="Calculate cubic polynomial coefficients for Angle vs. Length data.")
parser.add_argument('-file_name', type=str, required=True, help='The path to the CSV file containing Angle and Length data.')
args = parser.parse_args()
calculate_coefficients(args.file_name)
Save this as cam.py.
Cam Dataâ
Save the known cam angle to length data in a csv file names values.csv.
| Index | Angle | Length |
|---|---|---|
| 0 | 0 | 0 |
| 1 | 2 | 0.01 |
| 2 | 4 | 0.06 |
| 3 | 6 | 0.16 |
| 4 | 8 | 0.29 |
| 5 | 10 | 0.46 |
Needs these values for every 2 degs and up to 180 which is equivalent to full linear motion length.
Runâ
Run the code with the following
python3 .\cam.py -file_name values.csv
Output should be
--- Attempting to process file: .\values.csv ---
--- Final Cubic Polynomial Regression Coefficients ---
Model: Angle = (a * Length^3) + (b * Length^2) + (c * Length) + d
a (Length^3 coefficient): 0.0006656070500861079
b (Length^2 coefficient): -0.07551855711975415
c (Length^1 coefficient): 4.172569761404579
d (Constant term): 11.128975872807523
Now, Download the function block library file here and import from Project > Library > Show References and import the library. Fill the values in the function block.