import math
|
from collections import defaultdict
|
import re
|
|
def analyze_turn_rates(filepath):
|
print(f"Analyzing turn rates in {filepath} using Z-gyro...")
|
|
# Format: $CAL,count,time,state,pwm_t,pwm_s,x,y,z,head,pitch,roll,gx,gy,gz,ax,ay,az
|
|
state_data = defaultdict(list)
|
|
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
lines = f.readlines()
|
|
for line in lines:
|
line = line.strip()
|
if not line.startswith('$CAL'):
|
continue
|
|
parts = line.split(',')
|
if len(parts) < 15:
|
continue
|
|
try:
|
state = parts[3]
|
pwm_thr = int(parts[4])
|
pwm_str = int(parts[5])
|
|
# Get gyro Z (15th element, index 14)
|
# Unit check: Usually LSB or deg/s or rad/s. User said "Z轴角速度挺大的"
|
# If raw LSB, we need scale. If processed, maybe deg/s.
|
# Let's look at values: e.g. -1000, -1200.
|
# Assuming raw LSB for now, let's see the range.
|
gz_raw = int(parts[14])
|
|
# Also check heading change rate for verification if GPS heading is valid
|
heading = float(parts[9])
|
|
state_data[state].append({
|
'gz': gz_raw,
|
'pwm_thr': pwm_thr,
|
'pwm_str': pwm_str,
|
'heading': heading
|
})
|
|
except ValueError:
|
continue
|
|
print("\n=== Analysis of Turning Speeds ===")
|
print(f"{'State':<15} | {'PWM_Str':<8} | {'Avg Gyro Z':<10} | {'Est. Deg/s':<10}")
|
print("-" * 60)
|
|
results = []
|
|
sorted_states = sorted(state_data.keys())
|
for state in sorted_states:
|
if 'TURN' not in state:
|
continue
|
|
data = state_data[state]
|
gz_values = [d['gz'] for d in data]
|
pwm_str = data[0]['pwm_str']
|
|
if not gz_values:
|
continue
|
|
# Calculate average
|
avg_gz = sum(gz_values) / len(gz_values)
|
|
# Try to estimate actual deg/s from Gyro LSB
|
# Typical IMU scale (e.g. BMI088, MPU6050) at +/- 2000dps is ~16.4 LSB/(deg/s)
|
# at +/- 250dps is ~131 LSB/(deg/s)
|
# Let's guess scale based on user feedback or typical values.
|
# If raw values are around 1000, and it's turning visibly...
|
# 1000 / 16.4 = 60 deg/s.
|
# 1000 / 131 = 7.6 deg/s.
|
# Let's just report raw first.
|
|
results.append((state, pwm_str, avg_gz))
|
print(f"{state:<15} | {pwm_str:<8} | {avg_gz:<10.1f} | {avg_gz/16.4:<10.1f}?")
|
|
print("\n=== Proposed Mapping Table ===")
|
# Separate Left and Right turns
|
left_turns = []
|
right_turns = []
|
|
for state, pwm, gz in results:
|
if 'TURN_L' in state:
|
left_turns.append((pwm, gz))
|
elif 'TURN_R' in state:
|
right_turns.append((pwm, gz))
|
|
# Sort by PWM deviation from 1500
|
left_turns.sort(key=lambda x: x[0]) # 1000, 1100...
|
right_turns.sort(key=lambda x: x[0]) # 1600, 1700...
|
|
print("PWM | Gyro Z (Avg) | Direction")
|
for pwm, gz in left_turns:
|
print(f"{pwm:<4} | {gz:<12.1f} | Left")
|
for pwm, gz in right_turns:
|
print(f"{pwm:<4} | {gz:<12.1f} | Right")
|
|
if __name__ == "__main__":
|
analyze_turn_rates("python/calibration_20251205_105312.log")
|