Skip to main content

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.

IndexAngleLength
000
120.01
240.06
360.16
480.29
5100.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.