You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在步进电机位置-电阻映射数组中求特定距离的第二大峰值

Solving the Second Peak (Cricoid Cartilage) Detection for Neck Height Mapping

Nice project! Let's break down how to pinpoint the cricoid cartilage (your "lower point")—the second highest resistance peak that also meets specific distance requirements from the thyroid cartilage (your "upper point") stored in your points[stepper_motor_location][resistance] HashMap.

Here's a practical, Arduino-focused solution with two approaches depending on your peak definition:

1. First, Capture the Upper Peak (Thyroid Cartilage)

You already know how to do this, but we need to store both its resistance value and stepper position for later distance checks:

#include <HashMap.h>

// Assuming your HashMap is structured as: key = stepper position, value = resistance
HashMap<int, int> points;

int maxResistance = 0;
int maxPosition = -1;

// First pass: Locate the highest resistance peak (thyroid cartilage)
for (auto it = points.begin(); it != points.end(); ++it) {
    int currentPos = it->first;
    int currentRes = it->second;
    
    if (currentRes > maxResistance) {
        maxResistance = currentRes;
        maxPosition = currentPos;
    }
}

2. Option 1: Find the Second Highest Global Resistance (With Distance Check)

If your cricoid cartilage's resistance is simply the second highest overall (not just a local peak), use this second pass to filter candidates that fit your distance constraints:

int secondMaxResistance = 0;
int secondMaxPosition = -1;

// Adjust these values to match your project's anatomical requirements
const int MIN_VALID_DISTANCE = 5;  // Example: minimum 5 stepper steps apart
const int MAX_VALID_DISTANCE = 20; // Example: maximum 20 stepper steps apart

// Second pass: Hunt for the valid second-highest resistance
for (auto it = points.begin(); it != points.end(); ++it) {
    int currentPos = it->first;
    int currentRes = it->second;
    
    int positionDistance = abs(currentPos - maxPosition);
    // Skip the upper peak's position, check resistance hierarchy, and validate distance
    if (currentPos != maxPosition && 
        currentRes < maxResistance && 
        currentRes > secondMaxResistance &&
        positionDistance >= MIN_VALID_DISTANCE && 
        positionDistance <= MAX_VALID_DISTANCE) {
        
        secondMaxResistance = currentRes;
        secondMaxPosition = currentPos;
    }
}

// Validate and output the result
if (secondMaxPosition != -1) {
    Serial.print("Cricoid cartilage found at position: ");
    Serial.println(secondMaxPosition);
    Serial.print("Resistance value: ");
    Serial.println(secondMaxResistance);
} else {
    Serial.println("No valid cricoid candidate found—check distance thresholds or sensor data.");
}

3. Option 2: Find the Second Highest Local Peak (More Anatomically Accurate)

In real-world scenarios, the cricoid cartilage is likely a local peak (higher resistance than its adjacent positions) rather than just the second highest global value. Here's how to handle this:

Step 3.1: Collect All Local Peaks

First, identify all positions where resistance is higher than both neighboring positions:

#include <vector>
#include <algorithm>

vector<pair<int, int>> allPeaks; // Stores (position, resistance) for each peak

// Sort stepper positions to ensure we can check adjacent points
vector<int> sortedPositions;
for (auto it = points.begin(); it != points.end(); ++it) {
    sortedPositions.push_back(it->first);
}
sort(sortedPositions.begin(), sortedPositions.end());

// Detect all local peaks
for (int i = 0; i < sortedPositions.size(); ++i) {
    int currentPos = sortedPositions[i];
    int currentRes = points[currentPos];
    bool isPeak = false;
    
    // Check first position (only compare to next)
    if (i == 0 && sortedPositions.size() > 1) {
        int nextRes = points[sortedPositions[i+1]];
        isPeak = (currentRes > nextRes);
    }
    // Check last position (only compare to previous)
    else if (i == sortedPositions.size() - 1 && sortedPositions.size() > 1) {
        int prevRes = points[sortedPositions[i-1]];
        isPeak = (currentRes > prevRes);
    }
    // Check middle positions (compare to both neighbors)
    else if (i > 0 && i < sortedPositions.size() - 1) {
        int prevRes = points[sortedPositions[i-1]];
        int nextRes = points[sortedPositions[i+1]];
        isPeak = (currentRes > prevRes && currentRes > nextRes);
    }
    
    if (isPeak) {
        allPeaks.push_back({currentPos, currentRes});
    }
}

Step 3.2: Sort Peaks and Filter for Distance

Sort peaks by resistance (highest to lowest), then pick the first valid candidate that meets your distance rule:

// Sort peaks in descending order of resistance
sort(allPeaks.begin(), allPeaks.end(), [](const pair<int, int>& a, const pair<int, int>& b) {
    return a.second > b.second;
});

int cricoidPos = -1;
int cricoidRes = 0;

// Skip the upper peak, find the next valid candidate
for (int i = 1; i < allPeaks.size(); ++i) {
    int peakPos = allPeaks[i].first;
    int peakRes = allPeaks[i].second;
    int distance = abs(peakPos - allPeaks[0].first);
    
    if (distance >= MIN_VALID_DISTANCE && distance <= MAX_VALID_DISTANCE) {
        cricoidPos = peakPos;
        cricoidRes = peakRes;
        break;
    }
}

// Output the result
if (cricoidPos != -1) {
    Serial.print("Valid cricoid peak at position: ");
    Serial.println(cricoidPos);
    Serial.print("Resistance: ");
    Serial.println(cricoidRes);
} else {
    Serial.println("No valid cricoid peak found. Adjust thresholds or check sensor noise.");
}

Key Tips for Success

  • Filter Noise: Add a simple moving average to your resistance readings before storing them—this will reduce false peaks from sensor interference.
  • Calibrate Thresholds: Test with known anatomical positions to set MIN_VALID_DISTANCE and MAX_VALID_DISTANCE to match real neck anatomy.
  • Handle Edge Cases: If no valid candidate is found, add fallback logic (e.g., re-sample data, adjust thresholds) to keep your project running smoothly.

内容的提问来源于stack exchange,提问作者Xaiko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:27:21