سلسلة حساس الـIMU:
- تَفْهيمُ حساس الـ IMU: أساسيات حساسي التسارع والجايروسكوب وكيفية استخلاص زوايا الإمالة والدحرجة منهما.
- معايرة الحساس المغناطيسي من مسببات تشوه الحقل: لماذا وكيف.
- تفهيم حساس IMU: نُظم تمثيل اتجاهية الجسم وربط قيم الحساس مع مكتبة VPython ثلاثية الأبعاد.
- معايرة الحساس المعناطيسي لاسلكياً باستخدام البلوتوث.
إن أحد طرق تحديد الجهة الجغرافية تعتمد على الحقل المغناطيسي للكرة الأرضية وباستخدامه نعرف جهة الشمال باستخدام البوصلة الميكانيكية وذلك بتوجّه القسم الأحمر من إبرتها باتجاه الشمال والقسم الآخر من الإبرة نحو الجنوب.
إن أقطاب الحقل المغناطيسي للأرض لا تتطابق مع الأقطاب الجغرافية لها، وبسبب عدم التطابق تم الاصطلاح على القطب الجغرافي والقطب المغناطيسي.
إن الأقطاب الجغرافية لها أماكن ثابتة متعارف عليها وهي أماكن التقاء خطوط الطول والعرض في شمال وجنوب الكرة الأرضية، ولكن أماكن الأقطاب المغناطيسية تتغير كل فترة لأسباب فيزيائية تتعلق بالتكوين الأرضي المُسبب لنشأة هذا الحقل المغناطيسي الأرضي.
إيجاد الاتجاه الجغرافي باستخدام الحساس المغناطيسي
إن قيمة الميل declination للزاوية بين القطب الجغرافي والقطب المغناطيسي محددة من قبل العلماء، ويوجد مصادر مرجعية تعطي قيمة الميل الذي يجب استخدامه اعتماداً على مكاننا من سطح الأرض. يفسر هذا لنا طلب تشغيل الـGPS عند استخدام البوصلة في الجوال حيث يتم تحديد الموقع الجغرافي وبذلك تحديد درجة الميل، بالإضافة إلى المعلومات الأخرى التي يتم استقبالها من أقمار نظام التموضع العالمي GPS.
إن استخدام الحساس المعناطيسي Magnetometer الرقمي يوفر لنا إمكانية قياس الحقل المغناطيسي المحيط بالحساس والمخترق له وبالتالي الحقل المغناطيسي الأرضي. تزوّد هذه الحساسات قيمة رقمية تعبر عن شدّة الحقل المغناطيسي عبر 3 محاور ولهذا يسمى حساس مغناطيسي ثلاثي المحاور Three axis Magnetometerوتكون قيمة الشعاع المقاسة في نقطة في الفضاء الثلاثي تساوي:
نستخرج درجة الزاوية بقيمة من 0-360 بناءً على بعدها من الشمال وذلك بوضع الحساس بشكل مستوي بحيث يكون المحور Z متعامد مع السطح ويكون شعاع الحقل المغناطيسي يوثر على المحورين X و Y فقط.
نبدأ بحالة مرجعة وهي جعل محور الحساس X متوازٍ مع شعاع الحقل المغناطيسي الأرضي، وبهذا يكون قيمة الحقل على محورٍ واحدٍ فقط.
يمكننا التحسس لجهة الشمال ولجهة الجنوب عندما يكون الحساس متوازٍ على المحور X مع الحقل وذلك لأن القيمة على المحور X تكون أعظمية وموجبة وعلى المحور Y صفرية لتعامد الحقل المغناطيسي الأرضي معه.
يكون الحساس في الحالة العامّة منحرف بزاوية معينة عن الحقل، ولهذا يمكن حساب هذه الزاوية والمعبرة عن قيمة بعدنا بالدرجات عن الشمال المغناطيسي أو الشمال الجغرافي بعد الأخذ بعين الاعتبار الميل بين الشمالين بناءً على الموقع الجغرافي.
يمكن حساب الزاوية باستخدام قانون المثلثات المعروف:
يجب الانتباه خلال التنفيذ العملي لواحدة الزوايا وتحويلها من الراديان إلى الدرجات و الأخذ بعين الاعتبار زاوية الميل بين الشمال الجغرافي والشمال المغناطيسي.
خرج الحساس المغناطيسي من أجل دوران بـ 360 درجة
إن القيمة الرقمية المعبّرة عن شدّة الحقل تتراوح بين قيمة موجبة عظمى عندما يتوازى المحور مع الحقل بنفس الجهة الشمالية وقيمة صفرية عندما يتعامد معه وقيمة سالبة عظمى عندما يتعاكس مع جهة الشمال ويمكن التعبير عنها بالحالة المثالة بإشارة جيبية للمحورين X و Y عند دوران المحور 360 درجة.
سنستخدم دارة الكترونية مع حساس حقيقي للتأكد من شكل الإشارة على المحورين مع إدارة الدارة بشكل مستمر وأفقي بين درجات الشمال والجنوب وفي ما يلي شكل الإشارة باستخدام QMC5883L GY-271 Compass module.
إن شكل الإشارة ليس تماماً كما هو متوقع، فقسم الإشارة الأول الذي يمر من الشمال للشرق مروراً بالجنوب له قيمة أعظمية مختلفة عن القسم الثاني الذي يمر من الجنوب للغرب مروراً بالشمال، وبرسم إشارة المحور Y نجد أنها أسوأ حالة من المحور X حيث تبدو الإشارة الجيبية المتوقعة منزاحة عن المحور الصفري ولا تصل إليه في أي اتجاه.
إن السبب وراء هذا الشكل غير المنتظم يعود لسبب وجود حقول مغناطيسية مجاورة تتداخل مع الحقل المغناطيسي الأرضي وهذا يؤثر على شكل الإشارة. إن المشكلة الأخرى التي تظهر أيضاً هي عدم انطباق الاتجاه الذي تصل فيه قيمة الإشارة في المحور X للقيمة صفر في الشرق أو الغرب مع الدرجة الحقيقة للشرق والغرب حقيقةً وهذا أيضاً بسبب تأثيرات الحقول الجانبية. لهذا السبب تحتاج حساسات الحقول المغناطيسية لضبط ومعايرة ويسمى بالـ Calibration.
أسباب حدوث التشوه للحقل المغناطيسي
السبب الأول لتشوه الحقل المغناطيسي بالنسبة للحساس يسمى Hard Iron Distortion ومصدره المواد والمنتجات التي تُصدر حقل مغناطيسي مثل المغناطيس أو السماعات أو المحركات وهذا التشوه ينعكس بانزياح الإشارة عن الصفر بقيمة معينة Offset. يتم معالجة هذا النوع من التشوه بسهولة من خلال حساب الانزياح عن الصفر وطرح قيمته من القيم المستقبلة من الحساس.
السبب الثاني لتشوه الحقل المغناطيسي يسمى Soft Iron Distortion ومصدره المواد مثل الحديد والنيكل ذات النفاذية المغناطيسية permeability العالية. يعد هذا النوع من التشوهات أكثر تعقيداً ويحتاج حسابات أكثر.
نعبّر عن الإشارة الرقمية التي تُقرأ من الحساس بشكل أوضح من الإشارة الجيبة، إذا يجب أن ترسم هذه الإشارة بالحالة المثالية دائرة مركزها الصفر بعد المعايرة، وترسم دائرة منحرفة عن الصفر في حالة Hard Iron أو شكل قطع ناقص Ellipse في حال التشوه بـSoft iron.
يعمم الشكل السابق من أجل 3 محاور على شكل كرة. إن الانزياح عن الصفر يعني أن القراءات في المحور لا يمر عبر الصفر بأي اتجاه كان وهذا بسبب وجود حقل مجاور غير الحقل المغناطيسي الأرضي يمنع القراءة الصفرية عند تعامد الحقل الأرضي مع المحور، وبشكل مشابه يمكن تفسير تحوّل الشكل من شكل دائري متوقع إلى شكل قطع ناقص.
التحقق عملياً من خرج الحساس QMC5883L
نرسم في الأسفل شكل مأخود من الخرج الرقمي للحساس QMC5883L عبر ثلاث محاور وهي نقاط:
- المحور X مع المحور Y: أعطت شكل دائري منزاح عن الصفر.
- المحور Y مع المحور Z: أعطت شكل بيضوي (قطع ناقص) منزاح عن الصفر.
- المحور Z مع المحور X: أعطت شكل بيضوي (قطع ناقص) منزاح عن الصفر.
نستخدم الكود التالي لغرض رسم النقاط التي نحصل عليها من الحساس، وهذا الكود هو نسخة معدّلة من كود من شركة Adafruit.
import time import matplotlib.pyplot as plt import matplotlib.animation as animation import datetime import matplotlib.dates as mdates from collections import deque import numpy as np import serial import re import math PORT = "/dev/ttyACM0" # How many sensor samples we want to store HISTORY_SIZE = 25000 serialport = None # Pause re-sampling the sensor and drawing for INTERVAL seconds INTERVAL = 0.01 def get_imu_data(): global serialport if not serialport: # open serial port serialport = serial.Serial(PORT, 9600, timeout=0.1) # check which port was really used print("Opened", serialport.name) # Flush input time.sleep(3) serialport.readline() # Poll the serial port line = str(serialport.readline(), 'utf-8') if not line: return None vals = line.strip().split(',') if len(vals) != 3: return None try: vals = [float(i) for i in vals] except ValueError: return None print(vals) return vals #print(vals) mag_x = deque(maxlen=HISTORY_SIZE) mag_y = deque(maxlen=HISTORY_SIZE) mag_z = deque(maxlen=HISTORY_SIZE) fig, ax = plt.subplots(1, 1) ax.set_aspect(1) def animate(i): for _ in range(30): ret = get_imu_data() if not ret: continue x = ret[0] y = ret[1] z = ret[2] mag_x.append(x) mag_y.append(y) mag_z.append(z) # Clear all axis ax.cla() # Display the sub-plots ax.scatter(mag_x, mag_y, color='r') ax.scatter(mag_y, mag_z, color='g') ax.scatter(mag_z, mag_x, color='b') if len(mag_x) == HISTORY_SIZE: anim.event_source.stop() # Pause the plot for INTERVAL seconds plt.pause(INTERVAL) anim = animation.FuncAnimation(fig, animate,interval=INTERVAL) plt.show()
يتوقع الكود استقبال القيم للمحاور الثالثة عبر اتصال تسلسلي يوجد فيه في كل سطر قيمة المحاور بالترتيب ومفصول بينها بفاصلة. يوجد كود أردوينو كمثال يمكن أن يؤدي الغرض المطلوب لإرسال القيم عبر اتصال تسلسلي:
#include <Wire.h> #include <Adafruit_Sensor.h> #include <Adafruit_HMC5883_U.h> /* Assign a unique ID to this sensor at the same time */ Adafruit_HMC5883_Unified mag = Adafruit_HMC5883_Unified(12345); void displaySensorDetails(void) { sensor_t sensor; mag.getSensor(&sensor); Serial.println("------------------------------------"); Serial.print ("Sensor: "); Serial.println(sensor.name); Serial.print ("Driver Ver: "); Serial.println(sensor.version); Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id); Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" uT"); Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" uT"); Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" uT"); Serial.println("------------------------------------"); Serial.println(""); delay(500); } void setup(void) { Serial.begin(9600); Serial.println("HMC5883 Magnetometer Test"); Serial.println(""); /* Initialise the sensor */ if(!mag.begin()) { /* There was a problem detecting the HMC5883 ... check your connections */ Serial.println("Ooops, no HMC5883 detected ... Check your wiring!"); while(1); } /* Display some basic information on this sensor */ displaySensorDetails(); } void loop(void) { /* Get a new sensor event */ sensors_event_t event; mag.getEvent(&event); /* Display the results (magnetic vector values are in micro-Tesla (uT)) */ Serial.print(int(event.magnetic.x)); Serial.print(","); Serial.print(int(event.magnetic.y)); Serial.print(","); Serial.println(int(event.magnetic.z)); delay(10); }
لرسم شكل مشابه للشكل الذي في الأسفل يجب تحريك الحساس في جميع الاتجاهات لعدّة دقائق.
نلاحظ في الشكل وجود نوعين من التشوه وهو التشوه المسبب لانزياح عن المبدأ الصفري وأيضاً التشوه المسبب لانحراف عن الشكل الدائري المتوقع والحصول على شكل بيضوي (قطع ناقص) وهذا بسبب وجود تشوه الـSoft Iron.
تتحول نقاط المحاور الثلاثة بعد إجراء المعايرة من الأشكال المنحرفة عن الشكل الدائري وعن الصفر إلى أشكال دائرية ومتمركز عند الصفر.
خطوات المعايرة
نستخدم للمعايرة برنامج اسمه magneto V1.2 والذي يحتاج لإدخال مجموعة من النقاط للمحاور الثلاثة X و Y و Z. نقوم بخطوتين رئيسيتين لحساب محدّدات المعايرة عبر البرنامج وهما:
الخطوة الأولى: تحديد قيمة الحقل المغناطيسي الأرضي في مكان المعايرة ونستخدم الموقع www.ngdc.noaa.gov من أجل الحصول على تلك القيمة. توضح الصورتان التاليتان طريقة استخدام الموقع.
الخطوة الثانية:
يُزوَّد البرنامج بالنقاط بوحدة مايركو تيسلا uT على المحاور الثلاثة من خلال ملف txt بحيث يحوي كل سطر على قراءة المحور X ثم المحور Y ثم المحور Z ويباعد بينهما باستخدام Tab. مثال:
-22.01240144 -19.46159489 -29.6283882 -22.01240144 -19.46159489 -29.6283882 -22.01240144 -19.46159489 -29.6283882 -22.01240144 -19.46159489 -29.6283882 -19.85806644 -23.96601389 -31.4289172 -19.85806644 -23.96601389 -31.4289172
يوجد في ما يلي كود يمكن إضافته إلى كود البايثون السابق لتخزين النقاط بالصيغة المطلوبة
with open('points.txt', 'w') as f: for i in range(0,len(mag_x)): f.write("{}\t{}\t{}\n".format(mag_x[i],mag_y[i],mag_z[i]))
يجب اختيار النقاط بحيث تشكل الدوائر والقطوع الناقصة قبل المعايرة التي استعرضناها سابقاً.
نجد في خرج البرنامج قسمين وهما القسم الذي سيعالج التشوه بسبب الـHard Iron المسبب للانزياح عن المركز الصفري ولذلك هي قيم ثلاثة -واحدة لكل محور- والقسم الذي سيعالج التشوه بسبب الـSoft Iron المسبب لتشوه الشكل الكروي لشكل قطع ناقص وهي على شكل مصفوفة بالبعد 3X3.
بعد حساب معاملات المعايرة، يتم تعويض القيم في النموذج الرياضي التالي الذي يتألف من القيم بعد المعايرة في الطرف الأيسر وهي
و مصفوفة معايرة تأثير الـSoft Iron وقيم الانحرف عن الصفر bh الواجب طرحها من القيم المستعادة من الحساس مباشرةً
يوجد طريقتان للتأكد من صحة المعايرة وهما:
الطريقة الأولى: تُسجل عينات من محاور الحساس الثلاثة بعد المعايرة و يجري حساب مصفوفة المعايرة من جديد ويجب أن تكون المصفوفة الناتجة أقرب للمصفوفة الواحدية وهذا يعني أن القيم مُعايرة.
الطريقة الثانية: استخدام الاتجاهات الجغرافية كنقطة مرجعية لمعرفة دقة المعايرة. نستخدم مثلاً بوصلة الهاتف المحمول لتحديد الشمال الجغرافي ونقارن ذلك مع الشمال الجغرافي المُحتسب من الحساس المغناطيسي. شرحنا في مقدمة هذا المقال كيفية احتساب الاتجاه الجغرافي عبر الحساس المغناطيسي.
إن الكود أدناه يحسب قيمة الزاية بالدرجات ويمكن إضافته لكود البايثون بعد تعطيل قسم رسم النقاط فيه
while True: ret = get_imu_data() if not ret: continue x = ret[0] y = ret[1] z = ret[2] A= np.array([[1.134709 ,0.011465 ,0.069223],[0.011465 ,1.117556 ,0.057125],[0.069223 ,0.057125 ,1.710475]]) # change this array according to your calibration B = np.array([[x],[y],[z]]) - np.array([[-1.744835] ,[-17.592499] ,[-1.965020]]) # change this array according to your calibration Cal = np.matmul(A, B) heading = math.atan2(Cal[1],Cal[0]) if heading < 0: heading = heading + 2*math.pi heading_degree = heading *180/math.pi heading_degree = heading_degree + 5.7 # change 5.7 the declination in your area print(heading_degree)
ملاحظة حول أماكن وضع الحساس المغناطيسي
يجب الانتباه إلى إبعاد الحساس عن أي مصادر تشويه محتملة. قد تُستخدم مثلاً لوحة التجارب الـTest board أثناء التجريب وهي بحد ذاتها أحد مصادر تشويه الحقل وذلك لدخول معادن في تركيبتها.
يوجد مجموعة من النصائح التصميمية بخصوص مكان تموضع الحساس يجب مراعاتها عند تصميم الدارات المطبوعة والأجهزة الإلكترونية التي تحتوي على حساس مغناطيسي وسأقتبس أهمها من ورقة تقنية من شركة invensense مشار لها في المصادر.
- يحب إبعاد الحساس عن المواد التي تسبب التشوه Soft Iron لمسافة 10 ملم على الأقل.
- يفضل وضع الحساس على حواف الدارة أو زواياها.
- عند وجود حاجة لإضافة مواد معدنية في الدارة الإلكترونية فيجب اختيارها من مواد ذات نفاذية مغناطيسية منخفضة permeability مثل النحاس والألمنيوم والفضة والذهب وذلك ينطبق في حالات إضافة درع عازل sheild وعندها يتم الموازنة بين مكان تواجد الحساس وإمكانية ابعاده عن هذه المواد مسافة 10 ملم واختبار مادة ذات نفاذية عالية تستطيع صد الحقول عن الدارة مع تأثيرها كثيراً على الحساس المغناطيسي وبين مادة ذات نفاذية أقل وبالتالي قدرة أقل على صد الحقول الكهرطيسية مع أثر أقل على الحساس .
- إبعاد الحساس عن خطوط الداراة الإلكترونية التي يمر فيها تيارات لمسافة معينة بناءً على قيم التيار المار.
قيمة التيار المار (ميلي أمبير) | المسافة الموصى بها (ملم) |
0.2 | 2 |
1 | 10 |
2 | 20 |
10 | 100 |
20 | 200 |
المصادر
- درس مقدّم من Shawn Hymel على اليوتيوب (1) لشرح خطوات معايرة حساس مغناطيسي لبناء بوصلة ولكنه يستخدم برنامج MotionCal خلال المعايرة والذي يحتاج إلى وجود حساس تسارع Accelometer و حساس Gyroscopr.
- درس مقدّم من MicWro Engr على اليوتيوب (1) لشرح خطوات معايرة حساس مغناطيسي باستخدام برنامج magneto V1.2.
- ورقة تقنية honeywell من شركة ذات الرقم AN-203 والتي تتحدث عن استخدام الحساس المغناطيسي كبوصلة.
- سلسلة من عدّة أجزاء من قناة Robert’s Smorgasbord على اليوتيوب (1 – 2) تشرح بالتفصيل العملي والرياضي عن معايرة الحساسات المغناطيسية وتحديداً الحساس QMC5883L.
- دليل من شركة vectornav من جزئين (1 – 2) يتحدث عن مصادر الخطأ والمعايرة للحساسات المغناطيسية.
- ورقة تقنية من شركة InvenSense ذات الرقم AN-000011 تتحدث عن مصادر التشويه وبعض النصائح التصميمية للدارات المطبوعة التي تحوي حساس مغناطيسي.