Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ParkWardRR/d5658e96c1830a6d087a2007b2efd794 to your computer and use it in GitHub Desktop.
Save ParkWardRR/d5658e96c1830a6d087a2007b2efd794 to your computer and use it in GitHub Desktop.
#!/bin/bash
#
# bmw-bootmod3-knock-event-context-extractor.sh
#
# BMW Bootmod3 Knock Event Extractor – Direct, Reliable, Context-Rich
#
# USER PARAMETERS – Set these at the top for clarity
INPUT_FILE="input.csv" # Path to BM3 datalog CSV file
OUTPUT_PREFIX="output-knock-random" # Output file prefix
BUFFER_PERCENT=10 # Buffer as percent of total lines (e.g., 10 for 10%)
OUTPUT_DIR="." # Output directory ("." for current folder, or set path)
#
# SUMMARY
# -------
# This script finds all rows in a Bootmod3 (BM3) CSV where "Knock Detected" is 1.
# For each knock event, it includes a buffer of rows before and after, based on BUFFER_PERCENT.
# Output is a new CSV, ready for review by humans or for analysis in AI tools like GPT.
#
# Use Cases:
# - Quickly isolate knock events and context for tuning or troubleshooting.
# - Feed output into AI models for automated analysis.
# - Share concise, relevant data with your tuner.
#
# Typical Data Insights:
# - Knock Detected: ECU registers knock, but timing corrections are mild—no immediate danger.
# - Ignition Timing: Positive and stable, no aggressive timing pull.
# - Boost: Actual below target, wastegate duty cycle high.
# - AFR: Rising (leaning out) can increase knock risk; richer is safer under load.
# - Fuel Pressure: HPFP matches target, system is healthy.
# - IAT: Moderate, but rising temps increase knock sensitivity.
# - Load/Throttle: Throttle open, but actual load lower than target—ECU may limit for safety.
#
# INSTRUCTIONS
# 1. Place script and CSV in same folder, or set INPUT_FILE and OUTPUT_DIR as needed.
# 2. Adjust BUFFER_PERCENT for more or less context.
# 3. Run: chmod +x knock-extract-bm3-csv.sh && ./knock-extract-bm3-csv.sh
#
# Output: CSV with all knock events and surrounding data, suitable for further analysis.
#
#
# AI ANALYSIS USE CASE EXAMPLE
# ----------------------------
# After running this script, you can use the output CSV with AI models like this:
#
# 1. Upload output CSV to GPT-4o/Gemini with this prompt:
# "Analyze this BMW 428i datalog. Why did knock occur?
# Consider: AFR vs target, timing corrections, boost deviation,
# fuel pressure, and IAT. Give tuning recommendations."
#
# 2. Sample AI Response (GPT-4o):
# "Knock occurred at 17.574s during moderate load (55.4%)
# with AFR 13.72:1 (lean for WOT). Recommendations:
# - Enrich AFR to 12.5:1 in 50-60% load range
# - Reduce timing advance by 0.5° in problematic cells
# - Verify MAP sensor accuracy (7.5psig vs target 7.4psig)"
#
# 3. Sample Gemini Response:
# "Three knock events detected with rising IAT (86°F → 91°F).
# Wastegate duty cycle at 97% suggests turbo strain. Action items:
# 1. Add 1° timing buffer above 90°F IAT
# 2. Clean intercooler for better heat dissipation
# 3. Log LPFP pressure to rule out fuel starvation"
#
# This workflow helps optimize DME maps while respecting factory safety margins
#
# Generate random 5-digit number for output file
RAND_ID=$(jot -r 1 10000 99999)
OUTPUT_FILE="${OUTPUT_DIR}/${OUTPUT_PREFIX}-${RAND_ID}.csv"
# Calculate buffer size (integer, based on percent of total lines)
TOTAL_LINES=$(wc -l < "$INPUT_FILE")
BUFFER_SIZE=$((TOTAL_LINES * BUFFER_PERCENT / 100))
echo "BMW BM3 Knock Event Extractor"
echo "-----------------------------"
echo "Input file: ${INPUT_FILE}"
echo "Total lines: ${TOTAL_LINES}"
echo "Buffer size: ±${BUFFER_SIZE} lines (${BUFFER_PERCENT}%)"
echo "Output file: ${OUTPUT_FILE}"
echo "Output directory:${OUTPUT_DIR}"
echo ""
awk -F',' -v buffer="$BUFFER_SIZE" -v outfile="$OUTPUT_FILE" '
BEGIN {
print "AWK: Buffer size set to", buffer
}
NR == 1 {
header = $0
next
}
{
lines[NR] = $0
if ($17 == 1) {
print "Knock detected at line", NR, "(Time:", $1 "s)"
knocks[NR] = 1
}
}
END {
for (knock_line in knocks) {
start = knock_line - buffer > 1 ? knock_line - buffer : 1
end = knock_line + buffer < NR ? knock_line + buffer : NR
print "Processing knock at line", knock_line, "- lines", start, "to", end
for (i = start; i <= end; i++) {
selected[i] = 1
}
}
print header > outfile
for (i = 2; i <= NR; i++) {
if (selected[i]) {
print lines[i] >> outfile
}
}
}' "$INPUT_FILE"
echo ""
echo "Done. Results saved to ${OUTPUT_FILE}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment