|
#!/usr/bin/env python3 |
|
""" |
|
TurtleBot3 Assignment Analysis - Simple & Reliable |
|
Complete analysis script used for this assignment |
|
""" |
|
|
|
import pandas as pd |
|
import os |
|
import glob |
|
import math |
|
|
|
print("="*60) |
|
print("TURTLEBOT3 ASSIGNMENT ANALYSIS") |
|
print("="*60) |
|
|
|
# Find data directory |
|
data_dirs = glob.glob('/home/user/tb3_data_*') |
|
if not data_dirs: |
|
print("❌ No data found! Run data collection first.") |
|
exit() |
|
|
|
data_dir = sorted(data_dirs)[-1] |
|
print(f"📁 Data directory: {data_dir}") |
|
|
|
# Load and analyze data |
|
csv_file = os.path.join(data_dir, 'lidar_data.csv') |
|
data_lines = [] |
|
with open(csv_file, 'r') as f: |
|
for line in f: |
|
if not line.strip().startswith('#'): |
|
data_lines.append(line.strip()) |
|
|
|
# Parse and process |
|
header = data_lines[0].split(',') |
|
data = [] |
|
for line in data_lines[1:]: |
|
try: |
|
row = [float(x) for x in line.split(',')] |
|
data.append(row) |
|
except: |
|
continue |
|
|
|
df = pd.DataFrame(data, columns=header) |
|
print(f"✅ Loaded {len(df)} scans") |
|
|
|
# Statistical analysis |
|
beam_cols = [col for col in df.columns if col != 'timestamp'] |
|
num_beams = len(beam_cols) |
|
all_values = df[beam_cols].values.flatten() |
|
valid_values = [x for x in all_values if 0.1 < x < 30.0] |
|
|
|
print("\n" + "="*60) |
|
print("STATISTICAL ANALYSIS") |
|
print("="*60) |
|
|
|
print(f"Total measurements: {len(all_values):,}") |
|
print(f"Valid measurements: {len(valid_values):,}") |
|
print(f"Data quality: {len(valid_values)/len(all_values)*100:.1f}%") |
|
|
|
# Calculate statistics |
|
if valid_values: |
|
mean_val = sum(valid_values) / len(valid_values) |
|
min_val = min(valid_values) |
|
max_val = max(valid_values) |
|
variance = sum((x - mean_val) ** 2 for x in valid_values) / len(valid_values) |
|
std_dev = math.sqrt(variance) |
|
|
|
print(f"\n📈 Range Statistics:") |
|
print(f" Mean distance: {mean_val:.3f} m") |
|
print(f" Std deviation: {std_dev:.3f} m") |
|
print(f" Minimum: {min_val:.3f} m") |
|
print(f" Maximum: {max_val:.3f} m") |
|
|
|
# Generate report and visualizations |
|
try: |
|
import matplotlib |
|
matplotlib.use('Agg') |
|
import matplotlib.pyplot as plt |
|
|
|
# Create analysis directory |
|
analysis_dir = os.path.join(data_dir, 'analysis') |
|
os.makedirs(analysis_dir, exist_ok=True) |
|
|
|
# Plot 1: Sample scan |
|
if len(df) > 0: |
|
plt.figure(figsize=(10, 10)) |
|
sample = df.iloc[0] |
|
ranges = sample[beam_cols].values |
|
|
|
# Convert to Cartesian |
|
angles = [i * (2 * math.pi / num_beams) - math.pi for i in range(num_beams)] |
|
x = ranges * [math.cos(a) for a in angles] |
|
y = ranges * [math.sin(a) for a in angles] |
|
|
|
plt.scatter(x, y, s=5, alpha=0.6, color='blue') |
|
plt.scatter(0, 0, color='red', s=100, marker='^', label='TurtleBot3') |
|
plt.title('Sample LIDAR Scan (360° View)') |
|
plt.xlabel('X (m)') |
|
plt.ylabel('Y (m)') |
|
plt.axis('equal') |
|
plt.grid(True, alpha=0.3) |
|
plt.legend() |
|
plt.tight_layout() |
|
|
|
scan_file = os.path.join(analysis_dir, 'sample_scan.png') |
|
plt.savefig(scan_file, dpi=100) |
|
plt.close() |
|
print(f"✅ Sample scan: {scan_file}") |
|
|
|
# Plot 2: Histogram |
|
if valid_values: |
|
plt.figure(figsize=(10, 6)) |
|
plt.hist(valid_values, bins=50, edgecolor='black', alpha=0.7) |
|
plt.title('LIDAR Range Distribution') |
|
plt.xlabel('Distance (m)') |
|
plt.ylabel('Frequency') |
|
plt.grid(True, alpha=0.3) |
|
plt.tight_layout() |
|
|
|
hist_file = os.path.join(analysis_dir, 'histogram.png') |
|
plt.savefig(hist_file, dpi=100) |
|
plt.close() |
|
print(f"✅ Histogram: {hist_file}") |
|
|
|
# Plot 3: Data quality |
|
plt.figure(figsize=(8, 6)) |
|
labels = ['Valid', 'Invalid'] |
|
sizes = [len(valid_values), len(all_values) - len(valid_values)] |
|
colors = ['#4CAF50', '#F44336'] |
|
|
|
plt.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90) |
|
plt.title('Data Quality\nTotal measurements: {:,}'.format(len(all_values))) |
|
plt.tight_layout() |
|
|
|
quality_file = os.path.join(analysis_dir, 'data_quality.png') |
|
plt.savefig(quality_file, dpi=100) |
|
plt.close() |
|
print(f"✅ Data quality: {quality_file}") |
|
|
|
except ImportError: |
|
print("⚠️ Matplotlib not available, skipping plots") |
|
except Exception as e: |
|
print(f"⚠️ Could not create plots: {e}") |
|
|
|
print("\n" + "="*60) |
|
print("ANALYSIS COMPLETE!") |
|
print("="*60) |