ตัวกรองคาลมาน - การนำไปใช้งานพารามิเตอร์และการปรับแต่ง


10

ก่อนอื่นนี่เป็นครั้งแรกที่ฉันพยายามสร้างตัวกรองคาลมาน

ก่อนหน้านี้ฉันโพสต์คำถาม follwoing กรองสัญญาณรบกวนและความแปรปรวนจากค่าความเร็วใน StackOverflow ซึ่งอธิบายพื้นหลังสำหรับโพสต์นี้ นี่เป็นตัวอย่างของค่าทั่วไปที่ฉันพยายามกรอง พวกเขาไม่จำเป็นต้องลดลงซึ่งเป็นกรณีที่นี่ แต่โดยทั่วไปแล้วอัตราการเปลี่ยนแปลงจะเป็นแบบนี้

X ------- Y
16 --- 233.75
24 --- 234.01
26 --- 234.33
32
--- 234.12 36 --- 233.85
39 --- 233.42
47 --- 233.69
52 --- 233.68
55 --- 233.76
60 --- 232.97
66 --- 233.31
72 --- 233.99

ฉันได้ดำเนินการกรองคาลมานของฉันตามกวดวิชานี้: Kalman Filter สำหรับ Dummies

การใช้งานของฉันมีลักษณะเช่นนี้ (pseudocode)

//Standard deviation is 0.05. Used in calculation of Kalman gain

void updateAngle(double lastAngle){
  if(firsTimeRunning==true)
     priorEstimate = 0;               //estimate is the old one here
     priorErrorVariance = 1.2;        //errorCovariance is the old one
  else
     priorEstimate = estimate;              //estimate is the old one here
     priorErrorVariance = errorCovariance;  //errorCovariance is the old one
  rawValue = lastAngle;          //lastAngle is the newest Y-value recieved
  kalmanGain = priorErrorVariance / (priorErrVariance + 0.05);
  estimate = priorEstimate + (kalmanGain * (rawValue - priorEstimate));
  errorCovariance = (1 - kalmanGain) * priorErrVariance;
  angle = estimate;              //angle is the variable I want to update
}                                //which will be lastAngle next time

ฉันเริ่มต้นด้วยการประมาณก่อนหน้านี้ 0 ดูเหมือนว่าจะทำงานได้ดี แต่สิ่งที่ฉันสังเกตเห็นคือ kalmanGain จะลดลงทุกครั้งที่มีการเรียกใช้การอัปเดตซึ่งหมายความว่าฉันเชื่อถือค่าใหม่ของฉันน้อยลงเมื่อตัวกรองของฉันทำงานนานขึ้น (?) ฉันไม่ต้องการสิ่งนั้น

ฉันเปลี่ยนจากการใช้ค่าเฉลี่ยเคลื่อนที่ (แบบง่ายและแบบเอ็กซ์โปเนนเชียลถ่วงน้ำหนัก) เพื่อใช้สิ่งนี้ ตอนนี้ฉันไม่สามารถได้ผลลัพธ์ที่ดีอย่างที่คิด

คำถามของฉันคือถ้านี่คือการนำไปปฏิบัติที่ถูกต้องและหากความแปรปรวนข้อผิดพลาดและส่วนเบี่ยงเบนมาตรฐานของฉันดูดีตามค่าตัวอย่างที่ฉันโพสต์ พารามิเตอร์ของฉันถูกเลือกแบบสุ่มเพื่อดูว่าฉันจะได้รับผลลัพธ์ที่ดีหรือไม่ ฉันลองหลาย ๆ ช่วงแล้ว แต่ได้ผลลัพธ์ไม่ดี หากคุณมีข้อเสนอแนะเกี่ยวกับการเปลี่ยนแปลงที่ฉันทำได้ก็จะได้รับการชื่นชมอย่างมาก ฉันขอโทษถ้ามีบางสิ่งที่ชัดเจนหายไป ครั้งแรกที่โพสต์ที่นี่ด้วย

คำตอบ:


5

ตัวกรองคาลมานมีประโยชน์เมื่อสัญญาณอินพุตของคุณประกอบด้วยการสังเกตที่มีเสียงดังของสถานะระบบเชิงเส้นไดนามิก เมื่อพิจารณาจากสถานะของระบบแบบอนุกรมตัวกรองคาลมานมีจุดมุ่งหมายเพื่อให้การประเมินสถานะของระบบพื้นฐานที่ซ้ำและดีกว่าซ้ำ เพื่อที่จะใช้งานได้สำเร็จคุณต้องมีแบบจำลองสำหรับพลวัตของระบบที่คุณกำลังประเมิน ตามที่อธิบายโดยละเอียดที่วิกิพีเดียโมเดลนี้อธิบายว่าระบบพื้นฐานของรัฐคาดว่าจะเปลี่ยนแปลงในขั้นตอนเดียวได้อย่างไรเมื่อได้รับสถานะก่อนหน้าอินพุตใด ๆ ของระบบและส่วนประกอบสุ่มแบบเกาส์กระจายเรียกว่ากระบวนการรบกวน

จากที่กล่าวมานั้นยังไม่ชัดเจนจากคำถามของคุณว่าคุณมีโมเดลพื้นฐานเช่นใด โพสต์ที่เชื่อมโยงระบุว่าคุณกำลังใช้ค่าความเร็วจากเซ็นเซอร์ สิ่งเหล่านี้สามารถจำลองเป็นข้อสังเกตโดยตรงของสถานะของระบบ (โดยที่สถานะคือความเร็วของมัน) หรือการสังเกตโดยอ้อมของสถานะของมัน (โดยที่สถานะเป็นตำแหน่งตัวอย่าง) แต่เพื่อที่จะใช้กรอบการทำงานของคาลมานคุณต้องเลือกแบบจำลองสำหรับวิธีการที่รัฐคาดว่าจะมีวิวัฒนาการเมื่อเวลาผ่านไป ข้อมูลเพิ่มเติมนี้จะถูกใช้เพื่อสร้างการประมาณการที่เหมาะสมที่สุด ตัวกรองคาลมานไม่ใช่กล่องดำวิเศษที่จะ "ล้าง" สัญญาณที่ใช้กับมัน

จากที่กล่าวมาปรากฏการณ์ที่คุณพูดพาดพิงถึงที่ตัวกรองคาลมานจะมีความมั่นใจมากขึ้นในการส่งออกของตัวเองไปยังจุดที่การสังเกตการป้อนข้อมูลถูกละเว้นอย่างก้าวหน้า สิ่งนี้สามารถลดลงได้ด้วยการเพิ่มค่าในเมทริกซ์ความแปรปรวนร่วมของสัญญาณรบกวนกระบวนการด้วยตนเอง จากนั้นในเชิงคุณภาพโมเดลสำหรับการเปลี่ยนสถานะของระบบมีองค์ประกอบสุ่มที่ใหญ่กว่าดังนั้นความสามารถในการประมาณการคาดการณ์สถานะต่อไปได้อย่างแม่นยำเนื่องจากสถานะปัจจุบันจะลดลง สิ่งนี้จะลดความเชื่อมั่นในการประเมินสถานะปัจจุบันของระบบและเพิ่มความเชื่อมั่นในการสังเกตการณ์ครั้งต่อไปเพื่อป้องกันไม่ให้เกิดผลกระทบ "ละเว้นการป้อนข้อมูล"


+1: โดยเฉพาะย่อหน้าสุดท้าย คิดว่าเสียงแปรปรวนร่วมในการออกแบบ KF เป็น "knobs" เพื่อ twiddle
Peter K.

4

หากฉันเข้าใจอย่างถูกต้องคุณมีสิ่งที่เคลื่อนไหวและคุณสามารถสังเกตเห็นความเร็วและความเร็วนี้จะมีเสียงดัง จากการวัดของคุณคุณสังเกตความแปรปรวน 2 แบบ \

  1. ความหลากหลายที่เกิดจากเสียงรบกวน
  2. ความหลากหลายเนื่องจากวัตถุกำลังเปลี่ยนความเร็วอย่างแท้จริง (เช่นการเลี้ยว)

เหตุผลที่คาลมานมีค่าเป็นศูนย์ก็คือคุณคิดโดยปริยายว่าความเร็วของวัตถุนั้นคงที่และสิ่งที่คุณต้องทำก็คือการประมาณความเร็วที่แท้จริงนี้

" เฮ้ฉันมีวัตถุที่เคลื่อนที่ด้วยความเร็วคงที่และฉันต้องการประเมินความเร็วคงที่นี้ "

แบบจำลองของคุณเป็นเช่นนี้ที่ไหน xk คือความเร็วในเวลา k และ yk เป็นการวัดที่สอดคล้องกัน

xk=xk1
yk=xk+qk

แต่วัตถุของคุณไม่เคลื่อนไหว ความเร็วเปลี่ยนไปและคุณไม่รู้ว่าจะเปลี่ยนแปลงอย่างไรและเมื่อไหร่

สิ่งที่คุณต้องพูดแทนคือ:

" เฮ้ฉันมีวัตถุที่เคลื่อนที่ด้วยความเร็ว แต่ฉันไม่แน่ใจว่ามันเปลี่ยนความเร็วอย่างไร "

มีหลายวิธีที่คุณสามารถทำได้: วิธีที่ง่ายที่สุดคือการเพิ่มความไม่แน่นอนของรัฐ

xk=xk1+vk1you add uncertainty
yk=xk+qk
ที่ไหน qk และ vk จะถือว่าเป็นเสียงสีขาว

สมการตัวกรองคาลมานของคุณจะมีลักษณะดังนี้:

y^k|k1=x^k|k1
Kk=Pk|k1Pk|k1+Qo
x^k|k=x^k|k1+Kk(yky^k|k1)
Pk|k=Pk|k1KkPk|k1
Pk+1|k=Pk|k+Qs

ในกรณีของ0.05คุณค่าคือความแปรปรวนของเสียงที่สังเกตได้Qo. เพื่อให้การเปลี่ยนแปลงนี้สิ่งที่คุณต้องทำคือการตั้งค่าQs, สภาวะแปรปรวนของเสียงรบกวนจากรัฐ (ความไม่แน่นอนในสถานะของคุณ) เป็นค่าคงที่บางอย่าง

ในรหัสของคุณการแก้ไขเล็กน้อยจะเป็น:

stateVariance = 0.5

errorCovariance = (1 - kalmanGain) * priorErrVariance + stateVariance;

โดยไม่เพิ่มstateVarianceหรือQs ในรหัสของคุณคุณคิดว่ามันเป็นศูนย์

stateVarianceค่านี้สามารถเป็นอะไรก็ได้ที่คุณต้องการ ขึ้นอยู่กับความมั่นใจของคุณว่าความเร็วจะเปลี่ยนไปเท่าใด หากคุณคิดว่าความเร็วจะคงที่พอสมควรให้ตั้งค่านี้เป็นจำนวนน้อย

วิธีนี้กำไร Kalman ของคุณจะไม่เป็นศูนย์


3

คุณต้องมีระบบไดนามิกเพื่อใช้ตัวกรองคาลมาน

ฉันจะแนะนำ

y=i=0naixi

a[k+1]=a[k]+w
cov(w)=Q
การวัด:
z=i=0naixi=y

ดังนั้นแทนที่จะใช้ x ในฐานะรัฐแนะนำค่าสัมประสิทธิ์ (a) เป็นรัฐ


1

ฉันคิดว่าคุณสามารถใช้ความคิดบางอย่างจากทฤษฎีการควบคุมคลาสสิกเช่นPID ควบคุม

สัญญาณ Y ของคุณสามารถเป็นตัวกำหนดค่าของคอนโทรลเลอร์ u (t) โรงงานกระบวนการเพียง 1 และ y (t) จะถูกกรองเอาท์พุท สิ่งที่คุณต้องทำคือการตั้งค่าพารามิเตอร์ (ปรับแต่ง) P, I และ D เพื่อให้ได้สิ่งที่คุณต้องการ

เอาต์พุต y (t) จะพยายาม "ติดตาม" อินพุต u (t) แต่พารามิเตอร์ควบคุมวิธีการติดตามนี้

ส่วนต่างกำไร D จะทำให้การตอบสนองของคุณไวต่อการเปลี่ยนแปลงข้อผิดพลาดอย่างรวดเร็ว ในกรณีของคุณฉันคิดว่า D ควรมีขนาดเล็ก คุณไม่ต้องการให้ y (t) เปลี่ยนแปลงหากคุณ (t) เปลี่ยนแปลงทันที

การได้มาซึ่ง 'ฉัน' จะทำให้การตอบสนองของคุณอ่อนไหวต่อข้อผิดพลาดสะสม คุณควรใส่ค่าสูง ถ้า u (t) เปลี่ยนระดับและเก็บไว้ที่นั่นข้อผิดพลาดจะถูกสร้างขึ้นแล้วคุณต้องการให้ y (t) ทำเช่นเดียวกัน

กำไร P สามารถปรับแต่งได้อย่างดี อย่างไรก็ตามลองเล่นกับพารามิเตอร์และดูสิ่งที่คุณได้รับ

มีวิธีการจูนที่ซับซ้อน แต่ฉันไม่เชื่อว่าคุณจะต้องการมัน

โชคดี.


จริงๆแล้วมันมีวิธีการที่ดีกว่า ดูโพสต์นี้
Daniel R. Pipa


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.