สารบัญ:

หัวหุ่นจำลองเสียง Localizing ด้วย Kinect: 9 ขั้นตอน (พร้อมรูปภาพ)
หัวหุ่นจำลองเสียง Localizing ด้วย Kinect: 9 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: หัวหุ่นจำลองเสียง Localizing ด้วย Kinect: 9 ขั้นตอน (พร้อมรูปภาพ)

วีดีโอ: หัวหุ่นจำลองเสียง Localizing ด้วย Kinect: 9 ขั้นตอน (พร้อมรูปภาพ)
วีดีโอ: Unreal Engine 5 | Blueprint For Beginners (2023) 2024, พฤศจิกายน
Anonim
หัวหุ่นจำลองเสียงด้วย Kinect
หัวหุ่นจำลองเสียงด้วย Kinect

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

ขั้นตอนที่ 1: ทฤษฎี

ทฤษฎี
ทฤษฎี

การคำนวณมุม

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

สมมุติว่าหน้าคลื่นเป็นเส้นตรง ถ้าเสียงมาจากทางขวา มันจะตีไมโครโฟน #2 เวลา t2 และ ไมโครโฟน #1 เวลา t1 ระยะทางที่เสียงเดินทางระหว่างการกดปุ่มไมโครโฟน #2 และไมโครโฟน #1 คือความแตกต่างของเวลาในการตรวจจับเสียงคูณด้วยความเร็วของเสียง v s:

d = v s *(t1-t2) = vs*Δt

เราสามารถเชื่อมโยงระยะทางนี้กับระยะทาง d 12 ระหว่างคู่ไมโครโฟนและมุม θ จากคู่ไปยังแหล่งกำเนิดเสียงด้วยความสัมพันธ์:

cos(θ) = d/d 12 = vs*Δt /d12

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

สุดท้าย เราสามารถแก้หาทีต้าได้โดยหาโคไซน์ผกผัน:

θ = acos(vs*Δt/d12), 0 <= θ <= π

ในการทำให้มุมดูเป็นธรรมชาติขึ้นอีกหน่อย เราสามารถลบ 90 องศาจากทีต้า เพื่อให้ 0 องศาอยู่ตรงหน้าคู่นี้โดยตรง และ +/- 90 องศาคือเต็มทางซ้ายหรือทางขวาเต็ม นี่เปลี่ยนการแสดงออกของเราจากโคไซน์ผกผันเป็นไซน์ผกผัน

  • cos(θ-π/2) = บาป(θ) = d/d12 = vs*Δt/d12
  • θ = asin(vs*Δt/d12), -π/2 <= θ <= π/2

ค้นหาความล่าช้า

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

หลังจากรับสัญญาณเสียงแบบมีหน้าต่างแล้ว เราจะพบการหน่วงเวลาระหว่างทั้งสองโดยคำนวณความสัมพันธ์ข้ามของสัญญาณ ในการคำนวณหาความสัมพันธ์แบบไขว้ เราถือสัญญาณแบบหน้าต่างจากไมโครโฟนตัวหนึ่งคงที่ และเลื่อนสัญญาณที่สองไปตามแกนเวลาจากด้านหลังตัวแรกไปจนถึงตัวแรกจนสุด ในแต่ละขั้นตอนตามสไลด์ เราจะคูณแต่ละจุดในสัญญาณคงที่ด้วยจุดที่สอดคล้องกันในสัญญาณเลื่อน จากนั้นจึงรวมผลลัพธ์ทั้งหมดเข้าด้วยกันเพื่อคำนวณค่าสัมประสิทธิ์สหสัมพันธ์สำหรับขั้นตอนนั้น หลังจากเสร็จสิ้นการสไลด์ของเรา ขั้นตอนที่มีค่าสัมประสิทธิ์สหสัมพันธ์สูงสุดจะสอดคล้องกับจุดที่สัญญาณทั้งสองมีความคล้ายคลึงกันมากที่สุด และขั้นตอนใดที่เรากำลังดำเนินการอยู่จะบอกเราว่าตัวอย่าง n สัญญาณที่สองมีออฟเซ็ตจากสัญญาณ 1 จำนวนเท่าใด ถ้า n เป็นค่าลบ แสดงว่าสัญญาณที่สองล้าหลังสัญญาณที่หนึ่ง หากเป็นค่าบวก แสดงว่าสัญญาณที่สองอยู่ข้างหน้า และหากเป็นศูนย์ แสดงว่าทั้งสองอยู่ในแนวเดียวกันแล้ว เราแปลงออฟเซ็ตตัวอย่างนี้เป็นการหน่วงเวลาโดยใช้ความถี่สุ่มตัวอย่างกับความสัมพันธ์ Δt = n/fs ดังนั้น:

θ = asin(vs*n/(d12*fs)), -π/2 <= θ <= π/2

ขั้นตอนที่ 2: ส่วนประกอบ

อะไหล่

  • Microsoft Kinect สำหรับ Xbox 360 รุ่น 1414 หรือ 1473 Kinect มีไมโครโฟนสี่ตัวที่จัดเรียงเป็นเส้นตรงที่เราจะใช้
  • อะแดปเตอร์แปลงขั้วต่อที่เป็นเอกสิทธิ์ของ Kinect เป็น USB + ไฟ AC แบบนี้
  • Raspberry Pi 2 หรือ 3 ใช้ Raspbian Stretch เดิมทีฉันพยายามใช้ Pi 1 Model B+ แต่ก็ไม่มีประสิทธิภาพเพียงพอ ฉันยังคงมีปัญหาในการยกเลิกการเชื่อมต่อจาก Kinect
  • หัวนางแบบที่น่าขนลุกที่สุดที่คุณสามารถหาได้
  • เซอร์โวแบบอะนาล็อกที่แข็งแรงพอที่จะหมุนหัวหุ่นของคุณ
  • ที่ชาร์จ USB แบบเสียบผนัง 5V ที่มีกำลังไฟเพียงพอสำหรับจ่ายไฟให้กับทั้ง Pi และเซอร์โวและพอร์ตอย่างน้อยสองพอร์ต (ฉันใช้ปลั๊ก 5A 3 พอร์ตที่คล้ายกันนี้
  • สายไฟต่อที่มีสองเต้ารับ (หนึ่งอันสำหรับเครื่องชาร์จ USB ที่ผนังและอีกอันสำหรับอะแด็ปเตอร์ Kinect AC
  • สาย USB สองเส้น: สาย Type-A ถึง micro-USB สำหรับจ่ายไฟให้กับ Pi และอีกสายสำหรับจ่ายไฟเซอร์โวที่คุณไม่ต้องสนใจในการตัด
  • แท่นสำหรับใส่ของทุกอย่างและอีกแท่นสำหรับวางหัวนางแบบ ฉันใช้ถาดเสิร์ฟพลาสติกเป็นฐานและแผ่นพลาสติกเป็นฐานรองศีรษะ ทั้งคู่มาจาก Walmart และมีราคาเพียงไม่กี่ดอลลาร์
  • 4x #8-32 1/2" สลักเกลียวและน็อตเพื่อติดเซอร์โวของคุณกับแพลตฟอร์มที่ใหญ่ขึ้น
  • สลักเกลียว M3 8 มม. 2x พร้อมแหวนรอง (หรือขนาดใดก็ตามที่คุณต้องการเพื่อติดเซอร์โวฮอร์นเข้ากับแพลตฟอร์มที่เล็กกว่า)
  • สายจัมเปอร์ตัวผู้ต่อตัวผู้ 2 เส้น สายสีแดง 1 เส้นและสายสีดำ 1 เส้น และสายจัมเปอร์ตัวเมีย-ตัวผู้ 1 เส้น
  • แถบเวลโครติดกาว
  • เทปพันสายไฟ
  • เทปพันสายไฟสำหรับการจัดการสายเคเบิล

เครื่องมือ

  • เดรเมลพร้อมล้อตัด
  • เจาะ
  • ดอกสว่าน 7/64", 11/16" และ 5/16"
  • ก๊อก M3 (อุปกรณ์เสริม ขึ้นอยู่กับฮอร์นเซอร์โวของคุณ)
  • ไขควง
  • หัวแร้งพร้อมหัวแร้ง
  • มือช่วย (ไม่จำเป็น)
  • เครื่องหมาย
  • เข็มทิศ
  • เครื่องปอกสายไฟ
  • มัลติมิเตอร์ (อุปกรณ์เสริม)

PPE

  • แว่นตานิรภัย

  • มาส์กหน้า (สำหรับชิ้นพลาสติก dremmel-ed)

ขั้นตอนที่ 3: การประกอบแพลตฟอร์มล่าง

แอสเซมบลีแพลตฟอร์มล่าง
แอสเซมบลีแพลตฟอร์มล่าง
แอสเซมบลีแพลตฟอร์มล่าง
แอสเซมบลีแพลตฟอร์มล่าง
แอสเซมบลีแพลตฟอร์มล่าง
แอสเซมบลีแพลตฟอร์มล่าง

ส่วนแรกที่เราจะทำคือแพลตฟอร์มด้านล่าง ซึ่งจะรองรับ Kinect, เซอร์โว และอุปกรณ์อิเล็กทรอนิกส์ทั้งหมดของเรา ในการสร้างแพลตฟอร์มคุณจะต้อง:

  • ถาดเสิร์ฟพลาสติก
  • เซอร์โว
  • น็อต 4x #8-32 1/2" พร้อมน็อต
  • เดรเมลพร้อมล้อตัด
  • ไขควง
  • เจาะ
  • ดอกสว่าน 11/16"
  • เครื่องหมาย

ทำอย่างไร

  1. พลิกถาดของคุณคว่ำ
  2. วางเซอร์โวของคุณไปด้านข้างใกล้กับด้านหลังของถาด ตรวจสอบให้แน่ใจว่าเฟืองส่งออกของเซอร์โวอยู่ตามแนวกึ่งกลางของถาด จากนั้นทำเครื่องหมายรอบๆ ฐานของเซอร์โว
  3. ใช้ dremel และล้อตัด ตัดพื้นที่ที่คุณทำเครื่องหมายออก จากนั้นเลื่อนเซอร์โวของคุณเข้าไปในช่อง
  4. ทำเครื่องหมายที่กึ่งกลางของรูยึดตัวเรือนเซอร์โวบนถาด จากนั้นถอดเซอร์โวออกแล้วเจาะรูเหล่านั้นด้วยดอกสว่าน 11/16" ของคุณ การเจาะพลาสติกบางแบบนี้ทำได้ง่ายมาก ฉันจึงพบว่าปลอดภัยกว่ามาก เพื่อหมุนสว่านกลับด้านและค่อยๆ เกลี่ยวัสดุออก ช้ากว่าการเจาะรูอย่างถูกต้องมากแต่รับรองว่าไม่มีรอยแตกร้าว
  5. วางเซอร์โวของคุณกลับเข้าไปในสล็อต จากนั้นติดตั้งเข้ากับถาดด้วยสลักเกลียวและน็อต #8-32

ขั้นตอนที่ 4: หัวหน้าชุดประกอบแพลตฟอร์ม

หัวหน้าแท่นประกอบ
หัวหน้าแท่นประกอบ
หัวหน้าแท่นประกอบ
หัวหน้าแท่นประกอบ
หัวหน้าแท่นประกอบ
หัวหน้าแท่นประกอบ
หัวหน้าแท่นประกอบ
หัวหน้าแท่นประกอบ

ส่วนต่อไปที่เราจะทำคือแพลตฟอร์มสำหรับเชื่อมต่อหัวนางแบบกับเซอร์โว ในการสร้างฐานรากคุณจะต้อง:

  • แผ่นพลาสติก
  • เซอร์โวฮอร์น
  • สลักเกลียว M3 8 มม. 2x พร้อมแหวนรอง
  • ไขควง
  • เจาะ
  • ดอกสว่าน 7/64" และ 5/16"
  • เข็มทิศ
  • เดรเมลพร้อมล้อตัด

ทำอย่างไร

  1. วางเข็มทิศไว้ที่รัศมีฐานของหัวนางแบบ
  2. ใช้เข็มทิศเพื่อทำเครื่องหมายวงกลมที่อยู่ตรงกลางแผ่น นี่จะเป็นขนาดที่แท้จริงของแพลตฟอร์มหัวของเรา
  3. ใช้ dremel และล้อตัดของคุณเพื่อตัดแท่นขนาดเล็กออกจากจาน
  4. เจาะศูนย์กลางของแท่นใหม่ของคุณด้วยดอกสว่านขนาด 5/16" ซึ่งจะทำให้เราเข้าถึงสกรูที่ยึดฮอร์นเซอร์โวกับเซอร์โวของเราได้ เพื่อให้แท่นมีความมั่นคงในขณะที่เจาะรู ผมจึงใส่หลอด ลวดด้านล่างและเจาะผ่านตรงกลางของแกนม้วน
  5. จัดเรียงแตรเซอร์โวของคุณให้อยู่ตรงกลางแท่นและทำเครื่องหมายสองรูเพื่อติดแตรเข้ากับแท่น ตรวจสอบให้แน่ใจว่ารูยึดเหล่านี้อยู่ห่างกันเพียงพอเพื่อให้มีที่ว่างสำหรับหัวสลักและแหวนรอง M3 ของคุณ
  6. เจาะรูที่ทำเครื่องหมายเหล่านี้ด้วยดอกสว่าน 7/64"
  7. รูด้านล่างของฮอร์นเซอร์โวของฉันเรียบ นั่นคือไม่มีเกลียวสำหรับโบลต์ M3 ดังนั้นฉันจึงใช้สว่านและก๊อก M3 เพื่อทำเกลียว
  8. ใช้สลักเกลียวและแหวนรองเพื่อยึดฮอร์นเซอร์โวเข้ากับแท่นรองศีรษะ

ขั้นตอนที่ 5: สายไฟเซอร์โว

สายไฟเซอร์โว
สายไฟเซอร์โว
สายไฟเซอร์โว
สายไฟเซอร์โว
สายไฟเซอร์โว
สายไฟเซอร์โว
สายไฟเซอร์โว
สายไฟเซอร์โว

เซอร์โวแบบอะนาล็อกมักจะขับเคลื่อนด้วย 4.8-6V เนื่องจาก Raspberry Pi ใช้พลังงาน 5V จาก USB แล้ว เราจะทำให้ระบบของเราง่ายขึ้นด้วยการเปิดเครื่องเซอร์โวจาก USB ด้วย ในการทำเช่นนั้น เราจะต้องแก้ไขสาย USB ในการสร้างสายไฟเซอร์โว คุณจะต้อง:

  • สาย USB สำรองพร้อมปลายแบบ A (ชนิดที่เสียบเข้ากับคอมพิวเตอร์ของคุณ)
  • สายจัมเปอร์สีแดงหนึ่งเส้นและสีดำหนึ่งเส้น
  • หัวแร้ง
  • ประสาน
  • เครื่องปอกสายไฟ
  • เทปพันสายไฟ
  • มือช่วย (ไม่จำเป็น)
  • มัลติมิเตอร์ (อุปกรณ์เสริม)

ทำอย่างไร

  1. ตัดขั้วต่อที่ไม่ใช่ USB Type-A ออกจากสายเคเบิล จากนั้นดึงฉนวนออกเล็กน้อยเพื่อให้เห็นสายไฟด้านในทั้งสี่เส้น ตัดฉนวนหุ้มรอบๆ สายไฟที่สัมผัสออก
  2. โดยทั่วไปแล้ว สาย USB จะมีสายไฟสี่เส้น: สองเส้นสำหรับรับส่งข้อมูลและสองสายสำหรับพลังงานและกราวด์ เรามีความสนใจในด้านพลังงานและพื้นดิน ซึ่งโดยทั่วไปจะเป็นสีแดงและสีดำตามลำดับ ดึงฉนวนบางส่วนออกจากสายสีแดงและสีดำ แล้วตัดสายสีเขียวและสีขาวออก หากคุณกังวลว่าคุณไม่มีสายไฟและสายกราวด์ที่ถูกต้อง คุณสามารถเสียบสายเคเบิลเข้ากับอะแดปเตอร์แปลงไฟ USB และตรวจสอบแรงดันไฟขาออกด้วยมัลติมิเตอร์
  3. ถัดไป ให้ตัดปลายด้านหนึ่งของสายจัมเปอร์สีแดงและสีดำออก แล้วดึงฉนวนบางส่วนออก
  4. ตอนนี้ บิดสายไฟสีดำของจัมเปอร์และสาย USB เข้าด้วยกัน ข้ามกึ่งกลางของสายไฟที่สัมผัสแล้วบิดเข้าหากัน จากนั้นใช้บัดกรีกับสายที่จับคู่เพื่อยึดไว้ด้วยกัน การช่วยเหลือด้วยมือจะทำให้สิ่งนี้ง่ายขึ้นโดยถือสายเคเบิลให้เข้าที่
  5. ทำซ้ำขั้นตอนที่ 4 สำหรับสายสีแดง
  6. ปิดสายไฟที่เปิดโล่งด้วยเทปพันสายไฟหรือท่อหดด้วยความร้อนหากคุณรู้สึกอยากใช้ ข้อต่อเหล่านี้จะเปราะบางเนื่องจากสายไฟมีขนาดเล็ก ดังนั้นให้เพิ่มเทปชั้นที่สองที่ยึดสายจัมเปอร์ไว้ที่ฉนวนด้านนอกของสาย USB ซึ่งจะทำให้ชุดประกอบแข็งขึ้นและมีโอกาสแตกหักน้อยลง

ขั้นตอนที่ 6: การติดตั้งอุปกรณ์อิเล็กทรอนิกส์

การติดตั้งอุปกรณ์อิเล็กทรอนิกส์
การติดตั้งอุปกรณ์อิเล็กทรอนิกส์
การติดตั้งอุปกรณ์อิเล็กทรอนิกส์
การติดตั้งอุปกรณ์อิเล็กทรอนิกส์
การติดตั้งอุปกรณ์อิเล็กทรอนิกส์
การติดตั้งอุปกรณ์อิเล็กทรอนิกส์

สุดท้าย เราจะนำทุกอย่างมารวมกัน ติดตั้งอุปกรณ์อิเล็กทรอนิกส์และทุกอย่างอื่นๆ ไว้ที่แท่นด้านล่าง คุณจะต้องการ:

  • แท่นล่าง
  • หัวหน้าแพลตฟอร์ม
  • หัวหุ่น
  • Kinect พร้อมอะแดปเตอร์ USB+AC
  • อะแดปเตอร์แปลงไฟ USB
  • สายไฟต่อ
  • สายไมโคร USB
  • สายไฟเซอร์โว
  • ราสเบอร์รี่ปี่
  • สายจัมเปอร์ชาย-หญิง
  • กาวเวลโคร
  • กรรไกร

ทำอย่างไร

  1. ติดตั้ง Pi ที่ด้านล่างของถาดด้วย Velcro
  2. ต่ออะแดปเตอร์แปลงไฟ USB ด้วย Velcro
  3. เสียบเซอร์โวและ Pi เข้ากับอะแดปเตอร์ไฟ USB
  4. เชื่อมต่อพิน 12 (GPIO18) ของ Pi เข้ากับสายสัญญาณของเซอร์โว เป็นพินที่ 6 ทางด้านขวา
  5. เสียบสายพ่วงของคุณผ่านที่จับด้านหลังของถาดแล้วเสียบอะแดปเตอร์แปลงไฟ USB เข้าที่ด้านหนึ่ง
  6. นำอะแดปเตอร์ Kinect USB+AC และเสียบอะแดปเตอร์แปลงไฟที่อีกด้านหนึ่งของสายต่อและ USB เข้ากับ Pi
  7. ลากสายไฟของ Kinect ผ่านที่จับด้านหน้าของถาดแล้วเสียบเข้ากับอะแดปเตอร์ Kinect
  8. ฉันใช้เทปพันสายไฟเพื่อยึดสายเคเบิลไว้ที่ด้านล่างของแท่น นี่ไม่ได้ดูหรูหราที่สุด แต่โชคดีที่ทุกอย่างถูกซ่อนไว้
  9. พลิกแท่นด้านขวาขึ้นและใช้ Velcro เพื่อติดตั้ง Kinect ที่ด้านหน้าของแท่น
  10. ใช้เวลโครเพื่อยึดหัวหุ่นเข้ากับฐานรองศีรษะ เมื่อทุกอย่างเข้าที่แล้ว ให้แยกชิ้นส่วนทั้งสองออกจากกัน เพื่อให้เราสามารถเข้าถึงสกรูยึดเซอร์โวฮอร์นได้ อย่าเพิ่งขันแตรเข้ากับเซอร์โว เพราะเราต้องแน่ใจว่าเซอร์โวอยู่ในตำแหน่งกึ่งกลางก่อน เพื่อให้เราสามารถจัดวางทุกอย่างได้ เราจะดำเนินการนี้ในขั้นตอนต่อไป

ขั้นตอนที่ 7: ซอฟต์แวร์และอัลกอริทึม

ซอฟต์แวร์และอัลกอริทึม
ซอฟต์แวร์และอัลกอริทึม

ภาพรวม

ซอฟต์แวร์สำหรับโครงการนี้เขียนด้วยภาษา C++ และรวมเข้ากับระบบปฏิบัติการหุ่นยนต์ (ROS) ซึ่งเป็นเฟรมเวิร์กสำหรับการเขียนซอฟต์แวร์หุ่นยนต์ ใน ROS ซอฟต์แวร์สำหรับระบบจะแบ่งออกเป็นชุดของโปรแกรมที่เรียกว่า nodes ซึ่งแต่ละโหนดจะใช้ส่วนย่อยเฉพาะของฟังก์ชันการทำงานของระบบ ข้อมูลถูกส่งผ่านระหว่างโหนดโดยใช้วิธีการเผยแพร่/สมัครสมาชิก โดยที่โหนดที่ผลิตข้อมูลจะเผยแพร่และโหนดที่ใช้ข้อมูลสมัครรับข้อมูล การแยกโค้ดในลักษณะนี้ช่วยให้ขยายการทำงานของระบบได้ง่าย และอนุญาตให้ใช้โหนดร่วมกันระหว่างระบบเพื่อการพัฒนาที่รวดเร็วยิ่งขึ้น

ในระบบนี้ ส่วนใหญ่จะใช้ ROS เพื่อแยกรหัสที่คำนวณทิศทางการมาถึง (DOA) ของแหล่งกำเนิดเสียงออกจากรหัสที่ควบคุมเซอร์โว ทำให้โครงการอื่นรวมการประมาณ Kinect DOA โดยไม่ต้องรวมรหัสเซอร์โวที่อาจไม่ต้องการหรือต้องการ. หากคุณต้องการดูโค้ดเอง สามารถพบได้ใน GitHub:

github.com/raikaDial/kinect_doa

Kinect DOA โหนด

โหนด kinect_doa คือเนื้อและกระดูกของระบบนี้ โดยพื้นฐานแล้วทำทุกอย่างที่น่าสนใจ เมื่อเริ่มต้นระบบจะเริ่มต้นโหนด ROS ทำให้เวทมนตร์ ROS ทั้งหมดเป็นไปได้ จากนั้นอัปโหลดเฟิร์มแวร์ไปยัง Kinect เพื่อให้สตรีมเสียงพร้อมใช้งาน จากนั้นจะสร้างเธรดใหม่ซึ่งจะเปิดสตรีมเสียงและเริ่มอ่านข้อมูลไมโครโฟน Kinect สุ่มตัวอย่างไมโครโฟนสี่ตัวที่ความถี่ 16 kHz แต่ละตัว ดังนั้นจึงเป็นการดีที่จะมีความสัมพันธ์ข้ามและการรวบรวมข้อมูลในเธรดแยกกันเพื่อหลีกเลี่ยงข้อมูลที่ขาดหายไปเนื่องจากภาระการคำนวณ การเชื่อมต่อกับ Kinect ทำได้โดยใช้ libfreenect ซึ่งเป็นไดรเวอร์โอเพ่นซอร์สยอดนิยม

เธรดการรวบรวมเรียกใช้ฟังก์ชันเรียกกลับเมื่อใดก็ตามที่ได้รับข้อมูลใหม่ และทั้งคู่เก็บข้อมูลและกำหนดเวลาที่จะประเมิน DOA ข้อมูลจากไมโครโฟนแต่ละตัวถูกจัดเก็บในบัฟเฟอร์แบบหมุนความยาวเท่ากับหน้าต่างสุ่มตัวอย่างของเรา ซึ่งนี่คือ 8192 ตัวอย่าง นี่แปลว่าการคำนวณความสัมพันธ์ข้ามกับมูลค่าข้อมูลในช่วงครึ่งวินาทีที่ผ่านมา สิ่งที่ฉันพบจากการทดลองคือความสมดุลที่ดีระหว่างประสิทธิภาพและภาระในการคำนวณ การประมาณค่า DOA จะถูกทริกเกอร์สำหรับตัวอย่างทุกๆ 4096 ตัวอย่างโดยการส่งสัญญาณไปยังเธรดหลัก ดังนั้นความสัมพันธ์ข้ามที่ต่อเนื่องกันจะคาบเกี่ยวกัน 50% พิจารณากรณีที่ไม่มีการทับซ้อนกัน และคุณส่งเสียงอย่างรวดเร็วซึ่งถูกตัดครึ่งโดยหน้าต่างสุ่มตัวอย่าง ก่อนและหลังเสียงที่โดดเด่นของคุณน่าจะเป็นสัญญาณรบกวนสีขาว ซึ่งยากที่จะสอดคล้องกับความสัมพันธ์ข้าม หน้าต่างที่ทับซ้อนกันทำให้เราได้ตัวอย่างเสียงที่สมบูรณ์ยิ่งขึ้น เพิ่มความเชื่อถือได้ของความสัมพันธ์ข้ามสายโดยทำให้เรามีคุณสมบัติที่แตกต่างกันมากขึ้นในการจัดวาง

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

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

  1. มีไมโครโฟนสี่ตัวบน Kinect ซึ่งหมายความว่ามีรูปคลื่นทั้งหมดหกคู่ที่เราเชื่อมโยงกันได้ อย่างไรก็ตาม หากคุณดูการจัดเรียงเชิงพื้นที่ของอาร์เรย์ไมโครโฟน คุณจะเห็นว่าไมโครโฟน 2, 3 และ 4 อยู่ใกล้กันมาก อันที่จริงพวกมันอยู่ใกล้กันมากจนเนื่องจากความเร็วของเสียงและความถี่ในการสุ่มตัวอย่าง รูปคลื่นที่ได้รับที่ 2, 3 และ 4 จะถูกคั่นด้วยตัวอย่างข้างหน้าหรือข้างหลังอย่างน้อยหนึ่งตัวอย่าง ซึ่งเราสามารถตรวจสอบด้วยการคำนวณ maxlag = Δd *fs/vs โดยที่ Δd คือการแยกคู่ไมโครโฟน fs คือความถี่ในการสุ่มตัวอย่าง และ vs คือความเร็วของเสียง ดังนั้น คู่ที่มีความสัมพันธ์กันระหว่างสามคู่นี้จึงไม่มีประโยชน์ และเราจำเป็นต้องเชื่อมโยงไมโครโฟน 1 กับ 2, 3 และ 4 ข้ามความสัมพันธ์เท่านั้น
  2. เป็นที่ทราบกันดีว่าความสัมพันธ์ข้ามมาตรฐานของสัญญาณเสียงทำงานได้ไม่ดีเมื่อมีเสียงก้อง (echo) ทางเลือกที่มีประสิทธิภาพเรียกว่าความสัมพันธ์ข้ามสหสัมพันธ์กับการแปลงเฟส (GCC-PAT) วิธีนี้ใช้ฟังก์ชันการถ่วงน้ำหนักที่ขยายพีคในสหสัมพันธ์ข้าม ทำให้แยกสัญญาณดั้งเดิมออกจากเสียงสะท้อนได้ง่ายขึ้น ฉันเปรียบเทียบประสิทธิภาพของ GCC-PHAT กับความสัมพันธ์ข้ามอย่างง่ายในห้องเสียงก้อง (อ่านว่า: ห้องน้ำคอนกรีตกำลังได้รับการออกแบบใหม่) และพบว่า GCC-PHAT มีประสิทธิภาพมากขึ้น 7 เท่าในการประมาณค่ามุมที่ถูกต้อง
  3. เมื่อทำ cross-correlation เรากำลังนำสัญญาณทั้งสอง เลื่อนสัญญาณหนึ่งไปพร้อมกัน และในแต่ละขั้นตอนคูณแต่ละจุดในสัญญาณคงที่ของเราด้วยแต่ละจุดในสัญญาณการเลื่อนของเรา สำหรับสัญญาณความยาว n สองตัว จะส่งผลให้มีการคำนวณ n^2 เราสามารถปรับปรุงสิ่งนี้ได้โดยทำ cross-correlation ในโดเมนความถี่แทน ซึ่งเกี่ยวข้องกับการแปลงฟูริเยร์อย่างรวดเร็ว (การคำนวณ nlogn) การคูณแต่ละจุดในสัญญาณที่แปลงหนึ่งโดยจุดที่สอดคล้องกันในอีกจุดหนึ่ง (n การคำนวณ) จากนั้นทำการผกผัน การแปลงฟูริเยร์เพื่อกลับไปยังโดเมนเวลา (การคำนวณ nlogn) ส่งผลให้มีการคำนวณ n+2*nlogn น้อยกว่า n^2 อย่างไรก็ตาม นี่เป็นแนวทางที่ไร้เดียงสา ไมโครโฟนในอาร์เรย์ของเราอยู่ใกล้กันมาก และความเร็วของเสียงค่อนข้างช้ามากจนรูปคลื่นเสียงส่วนใหญ่จะอยู่ในแนวเดียวกันอยู่แล้วดังนั้น เราสามารถกำหนดกรอบความสัมพันธ์ข้ามของเราเพื่อพิจารณาการชดเชยที่อยู่ข้างหน้าหรือข้างหลังเล็กน้อยเท่านั้น สำหรับไมโครโฟน 1 และ 4 ความล่าช้าต้องอยู่ระหว่าง +/-12 ตัวอย่าง ซึ่งหมายความว่าสำหรับแต่ละสหสัมพันธ์ เราต้องทำการคำนวณ 24*n เท่านั้น ส่งผลให้ประหยัดการคำนวณเมื่อรูปคลื่นยาวกว่า 2900 ตัวอย่าง

ระบบนี้ใช้ประโยชน์จากไลบรารี minidsp ซึ่งใช้อัลกอริธึม GCC-PHAT ด้วยการปรับให้เหมาะสม 3

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

โหนดควบคุมเซอร์โว

เมื่อเทียบกับโหนด kinect_doa โหนดเซอร์โวนั้นค่อนข้างง่าย หน้าที่ของมันคือใช้ DOA โดยประมาณเท่านั้นและย้ายเซอร์โวไปที่มุมนั้น มันใช้ไลบรารี wiringPi เพื่อเข้าถึงโมดูลฮาร์ดแวร์ PWM ของ Raspberry Pi ใช้เพื่อกำหนดมุมของเซอร์โว เซอร์โวอะนาล็อกส่วนใหญ่ควบคุมโดยสัญญาณ PWM ที่มีความกว้างพัลส์ตั้งแต่ 1,000 µs ถึง 2000 µs ซึ่งสอดคล้องกับมุม 0° ถึง 180° แต่เซอร์โวที่ฉันใช้ถูกควบคุมด้วย 500 µs ถึง 2500 µs ซึ่งสอดคล้องกับมุม จาก 0 °ถึง 270 ° ดังนั้น โหนดสามารถกำหนดค่าสำหรับฮาร์ดแวร์เซอร์โวที่แตกต่างกันโดยการตั้งค่าพารามิเตอร์สำหรับความกว้างพัลส์ต่ำสุด ความกว้างพัลส์สูงสุด และความแตกต่างระหว่างมุมสูงสุดและต่ำสุด นอกจากนี้ เซอร์โวจะไม่เคลื่อนที่ไปที่มุมเป้าหมายทันที แต่จะเคลื่อนที่ไปทางมุมด้วยความเร็วที่กำหนดค่าได้ ทำให้มาร์กาเร็ตมีบรรยากาศที่ค่อยเป็นค่อยไปและน่าขนลุก (บวกกับเสียงของเซอร์โวที่เคลื่อนที่ไปมาอย่างรวดเร็วทำให้เกิดความรำคาญได้เร็วมาก).

ขั้นตอนที่ 8: สร้างและติดตั้ง

ติดตั้งการพึ่งพา:

ขั้นแรก ติดตั้ง libfreenect เราต้องสร้างมันจากแหล่งที่มาเพราะเวอร์ชันที่คุณได้รับจากตัวจัดการแพ็คเกจนั้นไม่รองรับเสียง เนื่องจากเราต้องอัปโหลดเฟิร์มแวร์ไปยัง Kinect เพื่อเปิดใช้งานเสียง และการแจกจ่ายเฟิร์มแวร์นี้ต่อไม่ถูกกฎหมายในเขตอำนาจศาลบางแห่ง นอกจากนี้ เราสามารถหลีกเลี่ยงการสร้างตัวอย่างที่ต้องใช้ OpenGL และ glut ซึ่งไม่จำเป็นสำหรับการติดตั้ง Raspbian ที่ไม่มีส่วนหัว

sudo apt-get ติดตั้ง git cmake build-essential libusb-1.0-0-dev

cd git clone https://github.com/OpenKinect/libfreenect cd libfreenect mkdir build cd build cmake.. -DCMAKE_BUILD_REDIST_PACKAGE=OFF -DCMAKE_BUILD_EXAMPLES=OFF ทำให้ sudo make install sudo cp ~/libfreenect/devplatform/51/linux/.rules /etc/udev/rules.d การควบคุม udevadm --reload-rules && udevadm trigger

ต่อไป เราต้องติดตั้งแพ็คเกจ WiringPi ซึ่งช่วยให้เราควบคุมพิน GPIO ของ Pi:

ซีดี

git โคลน git://git.drogon.net/wiringPi cd ~/wiringPi./build

แนบหัวนางแบบ:

เมื่อติดตั้ง WirePi เรียบร้อยแล้ว เราจะสามารถอ้อมกลับไปยังพื้นที่ฮาร์ดแวร์เพื่อติดหัวนางแบบเข้ากับแท่นด้านล่างได้ ในการตั้งศูนย์กลางเซอร์โวผ่านทางบรรทัดคำสั่ง ให้ป้อนคำสั่งต่อไปนี้:

gpio pwm-ms

gpio pwmc 192 gpio pwmr 2000 gpio -g pwm 18 150

หากไม่มีการเคลื่อนไหว แสดงว่าเซอร์โวของคุณอยู่ตรงกลางแล้ว อย่างไรก็ตาม เพื่อให้แน่ใจ คุณสามารถตั้งค่าเซอร์โวเป็นค่าที่ไม่อยู่ตรงกลางได้ เช่น gpio -g pwm 18 200 จากนั้นตั้งค่ากลับเป็น 150

เมื่อคุณแน่ใจว่าเซอร์โวอยู่ตรงกลางแล้ว ให้ติดเซอร์โวฮอร์นของแพลตฟอร์มส่วนหัวเข้ากับเซอร์โวเพื่อให้หัวนางแบบของคุณมองตรงไปข้างหน้า จากนั้นขันฮอร์นเข้ากับเซอร์โวและติดหัวของคุณผ่านเวลโครบิต

ติดตั้ง ROS:

ถัดไป ติดตั้ง ROS บน Pi ของคุณ คู่มือการติดตั้งที่ยอดเยี่ยมสามารถพบได้ที่นี่ สำหรับระบบของเรา เราไม่ต้องการ OpenCV ดังนั้นคุณสามารถข้ามขั้นตอนที่ 3 บิลด์นี้จะใช้เวลาหลายชั่วโมงจึงจะเสร็จสมบูรณ์ เมื่อทำตามคำแนะนำการติดตั้งเสร็จแล้ว ให้เพิ่มการจัดหาการติดตั้งให้กับ bashrc ของคุณ เพื่อให้เราสามารถใช้แพ็คเกจ ROS ที่ติดตั้งใหม่ของเราได้:

echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc

สร้างแพ็คเกจ Kinect DOA:

หลังจากเสร็จสิ้นแล้ว ให้สร้างพื้นที่ทำงาน catkin สำหรับโครงการของเราและเข้าสู่ไดเร็กทอรี src:

mkdir -p ~/kinect_doa_ws/src

cd ~/kinect_doa_ws/src

โค้ดสำหรับโปรเจ็กต์นี้มีอยู่ในแพ็คเกจ kinect_doa ดังนั้นให้โคลนลงในไดเร็กทอรี src ของเวิร์กสเปซใหม่ของคุณ:

โคลน git

แพ็คเกจ robot_upstart มีเครื่องมือที่ใช้งานง่ายสำหรับการติดตั้งไฟล์เรียกใช้งาน เพื่อให้ทำงานเมื่อเริ่มต้น ดังนั้นให้โคลนสิ่งนี้ลงในพื้นที่ทำงานของคุณด้วย:

โคลน git

ตอนนี้ เราสามารถสร้างโค้ดโปรเจ็กต์ได้โดยการเรียก catkin_make จากไดเร็กทอรีระดับบนสุดของเวิร์กสเปซของเรา จากนั้นจึงสร้างซอร์สโค้ดเพื่อสร้างแพ็คเกจของเรา:

cd ~/kinect_doa_ws

catkin_make echo "แหล่งที่มา /home/pi/kinect_doa_ws/devel/setup.bash" >> ~/.bashrc

การวิ่งและการปรับแต่ง:

สมมติว่าทุกอย่างเสียบปลั๊กและเปิดเครื่องแล้ว ตอนนี้คุณควรจะสามารถเปิดระบบและให้ Kinect ติดตามเสียงของคุณได้! อย่างไรก็ตาม หากคุณมี Kinect 1473 ให้เปิดไฟล์ก่อน ~/kinect_doa_ws/src/kinect_doa/launch/kinect_doa.launch ในโปรแกรมแก้ไขข้อความและตั้งค่าพารามิเตอร์โดยใช้_kinect_1473 เป็น true นอกจากนี้ หากคุณใช้เซอร์โวที่แตกต่างจากที่ฉันทำ อาจเป็นเซอร์โวแอนะล็อกมาตรฐาน ดังนั้นในขณะที่อยู่ในไฟล์เรียกใช้งาน ให้เปลี่ยนพารามิเตอร์ min_us เป็น 1000, max_us เป็น 2000 และ max_deg เป็น 180

roslaunch kinect_doa kinect_doa.launch

เล่นกับมันซักพัก หากคุณรู้สึกว่าระบบไวเกินไป (มองไปในทิศทางแบบสุ่มที่ไม่ตรงกับเสียงหรือเสียงเฉพาะ) ให้ลองเปลี่ยนพารามิเตอร์ white_noise_ratio ในไฟล์เรียกใช้งานแล้วเปิดระบบอีกครั้งจนกว่าการตอบสนองจะอยู่ในระดับที่คุณพอใจ. การเพิ่มอัตราส่วนจะทำให้ระบบตอบสนองน้อยลงและในทางกลับกัน คุณอาจต้องดำเนินการปรับแต่งนี้ทุกครั้งที่คุณย้ายระบบไปยังตำแหน่งอื่นเพื่อให้ได้ประสิทธิภาพที่คุณต้องการ

ในการเปิดโปรแกรมเมื่อเราเปิดเครื่อง Pi เราใช้แพ็คเกจ robot_upstart เพื่อติดตั้งไฟล์เรียกใช้ของเรา หาก ROS ไม่ได้ทำงานอยู่ ให้เริ่มด้วยคำสั่ง roscore จากนั้นเปิดเทอร์มินัลใหม่และติดตั้งการเปิดใช้ด้วย:

rosrun robot_upstart ติดตั้ง kinect_doa/launch/kinect_doa.launch -- รูทผู้ใช้ --symlink

เราสร้าง symlink ไปยังไฟล์เรียกใช้งานแทนการคัดลอกเพื่อให้เราสามารถเปลี่ยนพารามิเตอร์โดยแก้ไข ~/kinect_doa_ws/src/kinect_doa/launch/kinect_doa.launch

ขั้นตอนที่ 9: ซ่อนไว้ที่สำนักงาน

ซ่อนไว้ที่ออฟฟิศ
ซ่อนไว้ที่ออฟฟิศ

ตอนนี้สำหรับส่วนที่สนุก ไปทำงานหลังเลิกงานและตั้งหัวนางแบบของคุณเป็นความลับ จากนั้นนั่งลงและดูว่าเพื่อนร่วมงานของคุณใช้เวลานานเท่าใดกว่าจะตามทัน! คุณเป็นผู้สร้างสรรค์ใหม่รับประกันว่าจะหันหัวสองสาม…

แนะนำ: