زيفيروس: التثبيت وOndas
التصميم المثالي لجسر الجيروسكوب-ضربة الجناح: تعديل تنفّس Ondas، تغذية أمامية متزامنة مع الضربة، رنين مقفل الطور وتعديل مرن هوائي لكسب PID — وخريطة صادقة لما يوصّله البرنامج الثابت الحالي فعلاً.
السلالة: OrniFlight وOndas مبسّط
Ondas ليس اختراعاً من PteronautOS. عائلة التعديل الموجي — تحكم إيقاع الشهيق-التوقف، شراسة شكل الضربة، المكث غير المتناظر، والاقتران المرن الهوائي لحمل الجناح بسلطة PID — تعيش وتتطور في OrniFlight المشروع، الذي تحمل ويكيه ومحاكيه الخوارزميات المتقدمة(بما فيها servo-efficiency table ).
يضمّ PteronautOS تنفيذاً مبسّطاً جزئياً: نفس هندسة التنفس الرياضية، مقيّدة إلى ESP8285 مع MPU6050 واحد وحتى تسعة سيرفو. حيث يحاكي OrniFlight المرونة الهوائية المستمرة ويستكشف عائلات غلاف كاملة دون اتصال، يتعيّن على PteronautOS أن يقرر في نبضات 4 ms، على نواة 80 MHz، مع مشاركة حزمة راديو ExpressLRS لنفس السيليكون. كل معامل في هذه المقالة موجود في المشروعين؛ ثوابت البرمجية أدناه هي المجموعة الفرعية المحمولة جواً.
مسار الإشارة — من زيفيروس إلى Ornithopter
الجسر من الجيروسكوب إلى رفرفة الجناح قصير عمداً — أربعة ملفات، بلا تخصيص ديناميكي، بلا طوابير:
MPU6050 raw (I2C, 1 kHz register reads)
▼
Zephyrus::update() Mahony AHRS → roll°, pitch°, yawRate °/s
▼ dual PID: roll→0°, pitch→0°, yawRate→0°/s
4 raw pitch terms exposed pitchPTerm · pitchITerm · pitchDTerm · pitchErrorRate
▼
ZephyrusFilter.h (250 Hz) copies terms onto ornithopter.gyroPitch*
▼
Ornithopter::_computeServoMixer() / _computeGearboxMixer()
▼ Ondas P → phase · PD → dwell · I → asymmetry · SSFF → next stroke
_f[] → funcMap → wing / crest-rudder / tail servos (µs)
تُكتب الحدود الأربعة الخام في Zephyrus::update() فور حساب PID الميلان لتصحيحه:
pitchPTerm = ZEPHYR_PID_PITCH_KP * pitchErr; // raw proportional
pitchITerm = _pidPitch.integrator; // accumulated error
pitchDTerm = ZEPHYR_PID_PITCH_KD * _pidPitch.lastDerivative; // low-pass filtered D
pitchErrorRate = _pidPitch.lastDerivative; // °/s, for SSFF
كل الأربعة محمية بفخ NaN(إذا كان أي دخل NaN تُصفَّر الأربعة) حتى لا يصل إطار I²C تالف أبداً إلى حسابيات الخلّاط. سبعة حقول على Ornithopter تستقبل بيانات الجسر:
| حقل | مصدر Zephyrus | يستهلكه |
|---|---|---|
gyroPitchPTerm
|
pitchPTerm
|
Ondas P → تقدّم الطور(قناة الإيقاع) |
gyroPitchITerm
|
pitchITerm
|
Ondas I → عدم تناظر الضربة(قناة التوازن) |
gyroPitchDTerm
|
pitchDTerm
|
Ondas D → نسبة المكث(قناة الشراسة) |
gyroPitchErrorRate
|
pitchErrorRate
|
تراكم نصف الضربة SSFF |
gyroRudderCorrection
|
rudderCorrection
|
إزاحة µs لدفة العرف(نواتا السيرفو وعلبة التروس) |
gyroAileronCorrection
|
rollCorrection
× gearbox gain
|
علبة التروس: PID اللفة → أسطح جنيح الذيل V |
gyroElevatorCorrection
|
pitchCorrection
× gain ×
aeroGainScale
|
علبة التروس: PID الميلان → أسطح إلفون / رافعة |
تعديل Ondas — تنفّس بثلاث قنوات
Ondas(بالبرتغالية: «أمواج») هو نظام التنفس ثلاثي القنوات الذي يسقط حدود P وI وD الخام لـ PID الميلان على ثلاثة أبعاد متعامدة لشكل موجة الرفرفة. إنه حلقة استقبال ذاتي: إحساس الجيروسكوب بالميلان يشكّل حركة الجناح مباشرة، وحركة الجناح تغيّر الميلان الذي يشعر به الجيروسكوب.
الإيقاع — P → تقدّم الطور
خطأ الميلان الموجب(أنف لأعلى) يقدّم طور المذبذب، مقصّراً نصف الضربة الحالي؛ والخطأ السالب يؤخّره. القانون المثالي يدرّج نابض المذبذب:
_osc.kGainMod = 1.0f + gyroPitchPTerm * aeroGainScale * cadenceGain * 0.00005f;
// clamped to [0.5, 2.0] — phase can at most double or halve
يستهلكها advance() للمذبذب كـ error = kGain · kGainMod · cadenceTarget − kDamp · cadence. نطاق الضبط 0–100، افتراضياً 20.
الشراسة — مزيج PD في المكث
يُمزج حدّا P وD في إشارة شراسة واحدة تشحذ أو تلطّف مكث شكل الموجة:
ferocitySignal = (gyroPitchPTerm * ferocityPGain * 0.00015f
+ gyroPitchDTerm * ferocityDGain * 0.0003f) * aeroGainScale;
// clamped to [-0.5, 0.5], added to both stroke and return ferocity
مع ferocityPGain = 0(الافتراضي) يكون السلوك D فقط — تغيّرات الميلان السريعة تنتج ضربات أحدّ بينما يبقى الطيران المستقر جيبياً.
التوازن — I في عدم التناظر
يُزيح الحد التكاملي مركز الضربة: انحياز مستمر للأنف لأعلى يقوّي الضربة الهابطة، وانحياز مستمر للأنف لأسفل يقوّي الصاعدة.
float iBias = gyroPitchITerm * aeroGainScale * balanceGain * 0.0001f;
// clamped to [-3.0, 3.0]; added to strokeFer, subtracted from returnFer
التوازن هو القناة الأكثر زعزعة للاستقرار عند ضبطه مرتفعاً — يبقيه دليل الضبط المثالي منخفضاً(5–15) ويضيفه أخيراً. تطبيق الشراسة، بجمع أمر الطيّار وانحيازات Ondas وSSFF، يحافظ على سلطة الطيّار على كامل نافذة [1.0, 8.0]:
strokeFer = pilot(stroke) + ferocitySignal + iBias + _ssffFerocityUpBias
returnFer = pilot(return) + ferocitySignal − iBias + _ssffFerocityDownBias
تشكيل الموجة ومزج PD
شكل الموجة نفسه يتبع عائلة ضربات OrniFlight: كل نصف يستخدم شراسته، وعتبة انعكاس مشتركة تُبقي الجناحين الأيسر/الأيمن في الطور، ومزيج شكل لكل ملف يحوّل باستمرار ضربة مكث/هضبة مسطحة إلى مسار هرمي مدوّر. المستكشف التفاعلي أدناه يعرض الهندسة المأمورة لأي زوج شراسة هبوط/صعود — المنحنى نفسه الذي يطلبه الخلّاط كل نبضة.
تتحكم الشراسة في كل من طابع وتوقيت نصف الضربة. داخليًا، يتطابق إعداد WebUI من 0–100 مع 0–8. الشراسة الأعلى للهبوط تقصّر حصة الهبوط من الدورة؛ والشراسة الأعلى للعودة تقصّر حصة العودة. يُنقل الوقت المتبقي إلى النصف المقابل — لا يوجد توقف عند الصفر.
يختار تحكم شكل الشراسة لكل ملف تعريف طابع الشراسة العالية. عند 0% يفضّل شكلًا نهائيًا مسطحًا/مربعًا. وعند 100% يفضّل مسارًا هرميًا مدوّرًا. لا يزال كل نصف يستخدم شراسته الخاصة، فيبقى النصف منخفض الشراسة ممدودًا وجيبيًا بينما يقترب النصف مرتفع الشراسة من عبور قطري مباشر.
يُزيح انحراف الهبوط والصعود (±100) مركز كل نصف ضربة على طول محوره من البداية إلى النهاية — وهو نفس التماثل لكل نصف ضربة كما في الشراسة. القيمة الموجبة تُحمّل الضربة من الأمام: يبلغ الجناح ذروة السرعة أبكر فيزداد الدفع. السالبة تُؤخّرها: تنفق الضربة حركتها في النهاية فيقل الدفع. الالتواء رتيب ويحافظ على الطرفين، لذا فهو تمامًا مزيج غير متماثل مربع↔مثلث، وليس قفزة موضع أبدًا.
يقارن اقتران شكل الدفع بالخانق بين الثبات والمركز الأمامي-الخلفي في مقبض واحد. عند الفتح الكامل يربّع الضربة ويقدّم نصفي الضربة——تصل سرعة الذروة أبكر في الهبوط والصعود معاً؛ وعند التباطؤ يبقى كلاهما محايداً. يقود عدّاد العدوانية الوحيد الثبات والمركز معاً، فتهاجر كلتا الجناحين ونصفا الضربة بتناغم——سلطة دفع، لا انحراف ولا انحدار.
اقتران الجنيح→skew يقدّم أحد الجناحين ويؤخّر الآخر — عزم دوران على محور skew، التوأم المرآتي لـ skew الخانق. العصا يساراً تضيف skew للجناح الأيسر وتزيله من الأيمن؛ ويميناً العكس. يُستخدم مع أو بدل تفاضل سعة الدفة.
الانسياب (slew) هو دفعة أو كبح عابر على معدّل تغيّر العصا. إعطاء الوقود front-load نصفي الضربة لفترة وجيزة، وقطع الوقود late-load كليهما لفترة وجيزة؛ يحقن المعدّل المُرشَّح بتمرير منخفض (τ = 0.10 s) النبضة التي تتلاشى بعد استقرار العصا. اقترانان: انسياب معدّل الوقود (متناظر، دفع) وانسياب معدّل الجنيح (تفاضلي، انحراف جانبي).
يطبّق slew gain في Zephyrus الفكرة العابرة نفسها على الدفة: تغيّر سريع في الوضع يعزّز تصحيح الدفة وجيزاً (µs)، بفلترة تمرير منخفض (τ = 0.12 ث) وتقييد صارم عند ±80 µs. يشحذ الاستجابة لتغيّرات الوضع السريعة دون رفع الكسب الثابت.
مصفوفة محاور التحكم
عصا الدفة لا تملك سلطة انعراج في خلاط الأجنحة: مقابضها التفاضلية (السعة والشراسة) تبني نفس عدم التماثل يسار/يمين مثل انحراف الجنيح — وهذا عدم التماثل هو انقلاب جانبي. الانعراج الحقيقي لا يوجد إلا في دفة القحف المستقلة (Zephyrus، جيروسكوب فقط).
| إدخال التحكم | معامل الموجة | تأثير الطيران |
|---|---|---|
| عصا الجنيح | انحراف (skew) — تفاضلي، يسار/يمين |
انقلاب جانبي |
| عصا الدفة | السعة + الشراسة — تفاضلي، يسار/يمين |
انقلاب جانبي |
| انعراج — جيروسكوب Zephyrus | دفة القحف | انعراج (مستقل) |
توجيه الطيران و slew
الدورة الكاملة
كل نصف ممدود لعرض متساوٍ
قراءة التركيبات القصوى
ينتج الجمع 7 / 1 بوضوح هبوطًا قصيرًا مدببًا وعودة جيبية طويلة. تتطلب القيم الدقيقة وشبه القصوى عناية: يستخدم قانون المدة الحالي الكمية المتبقية تحت الشراسة 8. وبالتالي، يخصص 8 / 0 نحو 0.125% فقط من الدورة للهبوط، بينما يخصص حتى 8 / 6 نحو 0.5%. يظل الموضع متصلًا، لكن السرعة والتسارع المطلوبين قد يصبحان غير قابلين للتحقيق فيزيائيًا.
تخميد المرساة (k₂)
يُعرَض تخميد المذبذب كمرساة قابلة للضبط. القانون الأساسي هو نابض مخمَّد نحو هدف الإيقاع:
kDamp = 10.0f + anchorGain; // anchorGain 0 → k₂=10 (tight)
error = kGain * kGainMod * cadenceTarget
- kDamp * cadence;
عند anchorGain = 0(افتراضياً) يكون التخميد مشدوداً — تقارب سريع نحو الإيقاع المأمور. القيم الأعلى ترفع k₂ نحو 110 عند الكسب 100، فتقفل الإيقاع بقوة أكبر وترفض الاضطرابات. نطاق الضبط 0–100.
الرنين — مضخة مقفلة الطور
الرنين مضخّم قفل مطابق للطور: يضرب معدل خطأ الميلان في sin(طور المذبذب) ويتراكم — معزّزاً الضربة تماماً عندما يكون التصحيح أكثر فعالية، ومخمِّداً إياها عندما تصارع الجناح.
_resonanceAccum += gyroPitchErrorRate * sinf(_osc.phase)
* resonanceGain * 0.01f * dt;
_resonanceAccum *= expf(-dt / 0.15f); // leaky integrator, τ = 0.15 s
clamp(_resonanceAccum, -2.0f, 2.0f);
تُحقَن القيمة المتراكمة في شراسة الضربة والعودة للإطار التالي. عند resonanceGain = 0(افتراضياً) يُعطَّل المسار كله. يمنع الاضمحلال المسرَّب التراكم الجامح أثناء اضطراب مستمر.
SSFF — تغذية أمامية متزامنة مع الضربة
التغذية الأمامية المتزامنة مع الضربة تختلف فلسفياً عن كل حد PID: تصحّح النصف التالي من الضربة مما قاسه الجيروسكوب خلال الحالي. عند كل عبور صفري لجيب الرفرفة(انعكاس الجناح)، يصبح متوسط معدل خطأ الميلان لنصف الضربة المكتمل انحيازاً على شراسة النصف المقابل.
// zero-cross detected: finished one half-stroke, starting the next
meanError = _ssffAccumError / count;
bias = meanError * ssffGain * 0.00001f; // clamped ±2.0
// upstroke just ended → bias feeds the downstroke (power stroke)
// downstroke just ended → bias feeds the upstroke (recovery)
يُطبَّق انحياز الصعود على الضربة الهابطة(تصحيحاً للخطأ المتراكم على الصاعدة السابقة)؛ وانحياز الهبوط على الصاعدة. عندما ينخفض ssffGain إلى الصفر تُمسَح الانحيازات صراحةً كي لا يترك تعطيل WebUI قيماً قديمة في الموجة. المراكم 32 بت ويُصفَّر لكل نصف ضربة — عند 250 Hz سيحتاج ~24 يوماً من الرفرفة المستمرة ليفيض، وهو ليس مصدر قلق عملي.
تعديل مرن هوائي لكسب PID
كل تعديل Ondas وSSFF يُدرَّج بمعامل يعرف إن كان الأورنيثوبتر يرفرف أم ينزلق — تعديل كسب مرن هوائي. في نواة السيرفو(الموجة) المحدِّد هو بوابة الرفرفة بتخلّفها 50 µs:
aeroGainScale = isFlapping ? (aeroFlapCoeff * 0.01f)
: (aeroGlideCoeff * 0.01f);
في نواة علبة التروس المحدِّد هو حالة المحرك(armed && throttleNorm > 0.1f). الافتراضيات:
| معامل | افتراضي | نطاق | عند التفعيل |
|---|---|---|---|
aeroGlideCoeff
|
40 | 0–100 | الأجنحة ساكنة — انزلاق، أو محرك علبة التروس متوقف |
aeroFlapCoeff
|
40 | 0–100 | الأجنحة ترفرف — أو محرك علبة التروس يعمل |
التحجيم إلى 0–1 يجعل منزلق 0–100 هو سلطة الجيروسكوب على الجناح: عند 100 يملك الجيروسكوب التعديل كلياً، وعند 0 يكون متوقفاً. السلطة حسب النواة:
| سلطة | نواة السيرفو(الموجة) | نواة علبة التروس |
|---|---|---|
| دفة العرف | لفة + انعراج مجتمعان | انعراج فقط(اللفة/الميلان تذهبان إلى الأرجل) |
| موجة الجناح | تعديل تنفس كامل Ondas / SSFF | — |
| جنيحات الأرجل(ذيل V) | — | PID اللفة → جانب الجنيح من مزيج الإلفون |
| إلفونات الأرجل / رافعة | — | PID الميلان × aeroGainScale → جانب الرافعة |
تُقيَّد تصحيحات PID لعلبة التروس بـ ±250 µs(ZEPHYR_GEARBOX_CLAMP_US) قبل الخلط؛ ويُقيَّد مسار دفة العرف بـ ±200 µs. تأخير إطار واحد متأصل: يُحسب aeroGainScale في خلّاط علبة التروس لكن يستهلكه zephyrusUpdate() التالي — 4 ms عند 250 Hz، لا يُذكر للسيرفو الميكانيكية.
لوحة WebUI ونقاط نهاية الإعداد
تعرض لوحة الأورنيثوبتر مجموعتَي تثبيت عندما يتضمن البناء Zephyrus. منزلقات Ondas وSSFF(0–100): الإيقاع P→الطور، الشراسة D→المكث، الشراسة P→المكث، التوازن I→عدم التناظر، المرساة k₂، الرنين، كسب SSFF. مجموعة المرونة الهوائية: معامل الانزلاق ومعامل الرفرفة. كل القيم تُحفَظ عبر POST /pteronautos/config وتعود عبر GET /pteronautos/state:
{
"ornithopter": {
"cadence_gain": 20.0, "ferocity_d_gain": 20.0, "balance_gain": 10.0,
"ferocity_p_gain": 0.0, "anchor_gain": 0.0, "resonance_gain": 0.0,
"ssff_gain": 0.0,
"aero_glide_coeff": 40.0, "aero_flap_coeff": 40.0,
"aero_gain_scale": 0.4
}
}
aero_gain_scale يُحسب وهو للقراءة فقط. يقبل POST تحديثات جزئية ويقيّد كل حقل إلى [0, 100] على جانب الخادم.
دليل الضبط
تسلسل اختبار الطيران المثالي — كل خطوة رحلة، لا سحب منزلق:
- صفّر كل كسب. طِر يدوياً فقط؛ يجب أن يكون الهيكل مستقراً وقابلاً للتنبؤ قبل أن يكسب الجيروسكوب صوتاً.
- فعّل دفة العرف لدى Zephyrus(PID لفة+انعراج). تحقق أن الدفة تقاوم هزّ جناح لطيف قبل أن يلمس أي شيء شكل الموجة.
- الإيقاع(P→الطور) من 10 صعوداً. مرتفع جداً = أجنحة متشنّجة، مطاردة طور؛ منخفض جداً = لا شيء. الصحيح = تشعر الأجنحة بأنها «متصلة» بالميلان.
- الشراسة D(D→المكث) من 10. مرتفع جداً = يتذبذب شكل الموجة بين الحاد والناعم؛ الصحيح = تغيّرات الميلان السريعة تشحذ الضربة، والطيران المستقر يبقى جيبياً.
- الشراسة P(اختياري) من 5 — تمزج سلطة P في المكث.
- التوازن(I→عدم التناظر) أخيراً ومنخفضاً. هذه هي القناة الأكثر زعزعة للاستقرار؛ 5–15 فقط. تقاوم الانجراف المستمر، لا الصدمات العابرة أبداً.
- SSFF من 5، فقط بعد ثبات الإيقاع والشراسة. مرتفع جداً = تصحيح زائد ورفرفة نصف ضربة؛ الصحيح = تخميد مرئي لسعة تذبذب الميلان.
- معاملات المرونة الهوائية أخيراً. اضبط الانزلاق أولاً(الأجنحة ساكنة)، ثم الرفرفة. أبقِ الجيروسكوب مساعد طيّار موثوقاً، لا طيّاراً متوتراً.
حالة التنفيذ والتناقضات المفتوحة
خريطة صادقة، البرمجية الحالية(Ornithopter.cpp @ 72c63020). القوانين المثالية أعلاه هي التصميم؛ يحوي الكود سطح المعاملات الكامل والثوابت ومنزلقات WebUI وجسر الربط — لكن كتلة سقالة اختبار الطيران تفصل حالياً معظم الجيروسكوب عن نواة السيرفو:
// Ornithopter.cpp:269-275 (inside the flapping branch)
#ifdef ZEPHYRUS_ENABLED
// STEP 7: ALL gyro values hard-zeroed (NaN guard test)
_osc.kGainMod = 1.0f; // cadence channel OFF
gyroRudderCorrection = 0.0f; // crest rudder OFF while flapping
gyroAileronCorrection = 0.0f;
gyroElevatorCorrection= 0.0f;
#endif
هذه الكتلة الملتزمة مع عمل i18n كاختبار حارس NaN «STEP 7» ولم تُرجَع أبداً تعني أن سلوك نواة السيرفو اليوم هو:
- الإيقاع والشراسة-PD والتوازن والرنين وSSFF — كلها حاضرة كمعاملات وفي الجسر، لكن مواقع استهلاكها(
kGainMod،ferocitySignal،iBias،resonanceBias) مثبّتة على صفر أو تُصفَّر كل إطار(Ornithopter.cpp:282–284، 311–313، 354). - تثبيت دفة العرف يُصفَّر داخل فرع الرفرفة، لذا يعمل تصحيح الدفة حالياً في فرع الانزلاق فقط — عكس ما يحتاجه الطيران(معظم الاضطرابات تصل في منتصف الرفرفة).
- نواة علبة التروس هي الاستثناء الحي. تقرأ
gyroAileronCorrection/gyroElevatorCorrection/gyroRudderCorrectionوتطبّقها بقيود(الأسطر 436–451) — كتلة التصفير STEP-7 تعيش فقط في نواة السيرفو.
هذا ليس نقداً للرياضيات — بل حالة معروفة ومسمّاة: وحدات التثبيت مُجمَّعة ومُعلمة وموصولة بجسر، وتنتظر إزالة سقالة STEP-7 واستبدالها بسياسة NaN حقيقية(حرّاس Validatio يمنحون بيانات MPU مساراً نظيفاً بالفعل). حتى ذلك الحين، تعامل مع دليل ضبط Ondas/SSFF/الرنين أعلاه كمواصفة جاهزة للطيران، مُتحقق منها مقابل Zephyrus.cpp:729–737 وOrnithopterWaveform.h، لكنها لم تُحمَل جواً بعد.
سجل التصميم الموثوق يبقى STABILIZATION.md ؛ مشروعه الشقيق OrniFlight يحمل بحث ONDAS المتقدم باستمرار.