Tag: resection

การเล็งสกัดย้อน (Resection) ด้วยการวัดมุมภายใน ระยะทางและและมุมแบริ่งด้วยวิธีการคำนวณแบบ Least Squares (ตอนที่ 2)

 ตั้งสมการ Observation Equation

ขอทบทวน ค่า aik, bik  เรียกว่า  direction coefficients และ  cik, dik เรียกว่า distance coefficients

ในกรณีวัดมุมเล็งสกัดย้อนจากสมการด้านบนและเอาแทนที่ในสมการด้านล่าง

เขียนให้ดูง่ายดังนี้  zi  คือค่าอะซิมัทเริ่มต้น

เราจะมาคำนวณหาค่า aik, bik กันก่อน มาคำนวณที่จุด P ค่าพิกัด N = 193939.897 E = 110879.464 ไปสถานีหลักฐานจุดที่ 1  ที่มีค่าพิกัด N = 192315.290 E = 120383.500 คำนวณระยะทางได้ 9641.890 เมตร คำนวณหาอะซิมัทได้ 99°42’1.1″ ดังนั้น aik = aP1 = -sin( 99°42’1.1″) / (9641.890 * 100) * 3600 * 180/3.141592654 = -0.2109 second (มุมแปลงเป็นหน่วยฟิลิปดา ระยะทางแปลงหน่วยเป็น ซม.)

bik = bP1 = cos(99°42’1.1″) / (9641.890 * 100) * 3600 * 180/3.141592654 = -0.0360 second

เราจะฟอร์มสมการในรูปแบบ v + Bx = f โดยที่

v คือเมตริกเวคเตอร์ของ residual

B คือเมตริกของค่า coefficient ของมุม ระยะทาง

f คือเมตริกความต่างของค่าที่คำนวณและค่าที่รังวัด

ผมคำนวณหาค่าaik, bik ทุกๆการรังวัดมุมมาดังนี้

มาทบทวนดูสมการระยะทางดังนี้้

คำนวณหา cik = cP1 = cos(99°42’1.1″) = -0.1685

dik= dP1 = sin(99°42’1.1″) = 0.9857

คำนวณทุกการรังวัดระยะทางมาได้ดังตาราง

สมการสุดท้ายคือการวัดเล็งสกัด (Bearing intersection)

จากสมการ v + Bx = f มาพิจารณาฝั่งซ้าย v + Bx ก่อน ผมฟอร์มเป็นเมตริกดังนี้

มาดูเมตริก เป็นเมตริกแสดงความต่างระหว่างค่าที่คำนวณกับค่ารังวัด f = Computed – Observation มาดูตามตาราง น่าจะเข้าใจได้ง่าย ค่า diff ในตารางก็คือค่า f นั่นเอง โปรดระวังหน่วยมุมจะเป็นฟิลิปดา (second) หน่วยระยะทางใช้เป็นซม.

ยกตัวอย่างค่าของเมตริก f เริ่มจากการวัดเล็งสกัดย้อน จะใช้มุมอะซิมัทที่ได้จากการคำนวณมาเป็นตัวเริ่มต้น ค่าจากจุด P ไปสถานีหลักฐานที่ 1 จะได้ค่าความต่างเท่ากับ 0.0 ต่อไปจากจุด P ไปสถานีหลักฐานที่ 2 คำนวณได้ 119.5116959 จากมุมที่วัดมา 99° 42′ 1.1″ + 19° 48′ 41″ = 119.5116957 ได้ค่าความต่าง = (119.5116959 – 119.5116957) * 3600 =  0.0008 second

ที่ง่ายที่สุดคือวัดระยะทางจากจุด P ไปสถานีหลักฐานจุดที่ 1 ได้ 9641.795 เมตร ส่วนการคำนวณจากค่าพิกัด P เริ่มต้นมายังค่าพิกัดสถานีหลักฐาน 1 ได้ค่าคำนวณ = 9641.890 เมตร ความต่าง = (9641.890 – 9641.795) * 100 = 9.5 ซม.

สุดท้ายสามารถนำค่ามาเขียนเป็นเมตริก ดังนี้

v + Bx = f

จะเห็นว่าสมการนี้ติดค่า residual ของเมตริก v และเมตริก x ไม่สามารถคำนวณต่อไป แต่หัวใจของ least squares ตามชื่อเลยครับคือผลรวมค่ายกกำลังสองของ  residual ที่ได้ค่าน้อยที่สุด

ถ้าค่า weight หรือน้ำหนักของการรังวัดไม่เท่ากันจะต้องคูณน้ำหนักเข้าไปด้วย

จากสมการ v + Bx = f แทนค่า v = f – Bx ในสมการ

ค่า Φ จะมีค่าน้อยที่สุด ดังนั้นจะหาอนุพันธ์ (ดิฟ) โดยที่ให้ x มีค่าเท่ากับศูนย์

ที่นี้ก็จำง่าย Nx = t โดยที่ N = BTWB และ f = BTW

สุดท้ายสามารถหาค่าเมตริก x = N-1เมื่อได้ค่า x แล้วก็สามารถย้อนไปหาเมตริก residual (v) ได้ ตามสมการ v + Bx = f

ผลลัพธ์การคำนวณรอบที่ 1

ผมใช้ฟังก์ชั่นของ excel หาเมตริกได้ดังนี้


ได้เมตริก x คือค่าปรับแก้หน่วยเป็นซม. เอาพิกัดจุด P และมุมอะซิมัท เริ่มต้นมาปรับได้ดังนี้ N = 193939.897 – 0.090829= 193939.806 ค่า E = 110879.464 + 0.04695 =  110879.511 และค่ามุมอะซิมัท = 99°42’1.1″ – 2.1156″ = 99° 41′ 58.99″ (99.6997191)

ผลลัพธ์การคำนวณรอบที่ 2

เอาค่าพิกัดของจุด P ที่ได้จากรอบที่ 1 มาเป็นตัวเริ่มต้น พร้อมทั้งมุมอะซิมัทด้วย

ตั้งสมการเมตริก v + Bx = f ได้ดังนี้

แก้สมการ Nx = t ได้ดังนี้

จะได้เมตริก x ค่าใหม่ เอาพิกัดจุด P และค่าอะซิมัทมาปรับได้ดังนี้ N =193939.806  – 0.0016 = 193939.790  และ E = 110879.511 + 0.0085 = 110879.519  ค่าอะซิมัท = 99° 41′ 58.99″ + 0.137″ = 99°41′ 59.13″ (99.6997572)

ผลลัพธ์การคำนวณรอบที่ 3

ต่อไปฟอร์มรูปเมตริก v + Bx = f สังเกตว่าเมตริก B ค่าเปลี่ยนไปเล็กน้อยมาก

คำนวณหาเมตริก x จากสมการ Nx = t => x = N-1t

จะได้เมตริก x ค่าใหม่ เอาพิกัดจุด P และค่าอะซิมัทมาปรับได้ดังนี้ N = 193939.790- 0.0003 = 193939.787  และ E = 110879.519 + 0.0001 = 110879.521 ค่าอะซิมัท = 99° 41′ 58.99″ + 0.024″ = 99°41′ 59.15″ (99.6997639)

มาถึงตอนนี้จะเห็นว่าค่าปรับแก้ ในเมตริก x  น้อยมากอยู่ในระดับเศษส่วนของมิลลิเมตร ΔN = -0.285 cm ΔE = 0.152 cm ดังนั้นแสดงว่าค่าที่คำนวณมานั้น convergence แล้ว ดังนั้นผมสรุปว่าผลลัพธ์ดังนี้

ค่าพิกัดจุด P (Free Station)

N = 193939.787 E = 110879.521 ค่าอะซิมัทจากจุด P ไปสถานีหลักฐานที 1 = 99°41′ 59.15″

 ตรวจสอบผลลัพธ์การคำนวณด้วย Microsurvey StarNet

เพื่อให้มั่นใจว่าผลลัพธ์ที่ได้จะถูกต้อง ผมใช้ Microsurvey StarNet  มาเป็นตัวช่วย ข้อมูลสถานีรังวัดไม่เกิน ดังนั้นผมยังใช้เวอร์ชั่นทดลองใช้ได้อยู่ เมื่อเปิดโปรแกรมมาผมใช้เมนู Options -> Project ตั้งค่าดังนี้ เปลี่ยนหน่วยเป็นเมตรให้เรียบร้อยก่อนที่ Adjustment > Units > Linear > Meters

จากนั้นปรับ  standard error  ของกล้องวัดมุมและระยะทางให้สอดคล้อง ผมปรับระยะทาง Distance constant 4mm ปรับ Distance PPM = 20 ความหมายตัวนี้คือ 4mm ± 20mm/1,000,000 x L (m) ถ้าวัดระยะทาง 1000 เมตร error จะอยู่ประมาณ 24 mm (กล้อง Total Station สมัยปัจจุบันเรื่องระยะทางทำได้ดีกว่านี้มาก)

จากนั้นป้อนข้อมูลไปดังนี้ หมายเหตุว่า C = Control Point ไม่มีเครื่องหมาย ! !  ตามหลังแสดงว่าเป็นค่าเริ่มต้นหรือประมาณการ A = Angle, D = Distance และ B = Bearing ถ้าสนใจก็ไปดาวน์โหลดโปรแกรมของ Microsurvey StarNet  มาทดลองได้

แล้วคัดลอกข้อมูลด้านล่างแล้วไปวางลงในหน้า  input เพื่อลองคำนวณดูผลลัพธ์กันได้

# Resection 2D combined resection, distance and bearing intersection.

# Approximate coordinates for the unknown free station
#
C P 193939.897 110879.464

# Coordinates for the known stations
C 1 192315.290 120383.500 ! !
C 2 189545.730 118642.430 ! !
C 3 188084.770 112278.210 ! !
C 4 190640.940 109654.540 ! !
C 5 190044.860 108065.980 ! !
C 6 194455.370 110632.930 ! !
A P-1-2 19-48-41
A P-1-4 100-40-19
A P-1-5 116-8-36
A P-1-6 234-44-22

#Distance measurements
D P-1 9641.795
D P-3 6019.802
D P-5 4804.793

#Bearing measurements
B 1-P 279-41-59.5
B 3-P 346-33-52
B 5-P 35-50-34

จากนั้นใช้เมนู Run > Adjustment

สรุปสถิติการคำนวณดังนี้ จะเห็นว่ามีจำนวนข้อมูลรังวัดมา 10 (วัดมุมเล็งสกัดย้อน 4 มุม ระยะทาง 3 ระยะ วัดมุมเล็งสกัด 3 มุม จำนวนสิ่งที่ไม่รู้ค่า 2 ค่า คือค่าพิกัด  x,y ของจุด P

Adjustment Statistical Summary
==============================

Iterations = 2

Number of Stations = 7

Number of Observations = 10
Number of Unknowns = 2
Number of Redundant Obs = 8

 

Adjusted Coordinates (Meters)

Station N E Description
P 193939.788830 110879.521213
1 192315.290000 120383.500000
2 189545.730000 118642.430000
3 188084.770000 112278.210000
4 190640.940000 109654.540000
5 190044.860000 108065.980000
6 194455.370000 110632.930000

จะได้ค่าพิกัดจุด  P ดังนี้ N = 193939.789 E = 110879.521 ต่างจากที่ผมคำนวณมาเล็กน้อย อย่างแรกคือผมไม่ได้ใช้น้ำหนัก  weight  แต่ของ MicroSurvey Starnet บังคับใช้ โปรแกรมไม่ได้แสดงค่าสมการให้ดู จึงตรวจสอบไม่ได้ว่าเมตริกของ W เป็นอย่างไร อย่างที่สองคือการคำนวณวนลูปสองรอบเท่านั้น แสดงว่าอัลกอริทึ่มอาจจะใช้อนุกรมเทเลอร์ลำดับที่ 2 ด้วย ซึ่งผมใช้ลำดับเดียวจึงต้องวนลูปมากกว่า

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

การเล็งสกัดย้อน (Resection) ด้วยการวัดมุมภายใน ระยะทางและและมุมแบริ่งด้วยวิธีการคำนวณแบบ Least Squares (ตอนที่ 1)

จากที่เขียนโปรแกรมสำหรับเครื่องคิดเลขคำนวณเล็งสกัดย้อนสำหรับเครื่องคิดเลข Casio fx-9860G II SD ทำให้นึกถึงวิธีการคำนวณแบบ least squares ที่เป็นพื้นฐานเคยร่ำเรียนมา โดยเฉพาะการรังวัดในปัจจุบันที่การรังวัดระยะทางด้วยกล้องประมวลผลรวมทำได้ง่าย เมื่อรวมกับการรังวัดมุม จะทำให้มีค่าเกินหรือ redundant มาคำนวณในวิธีแบบ least square ได้ การรังวัดแบบเล็งสกัดย้อนบางตำราเรียกว่า free station

การวัดเล็งสกัดย้อนในยุคแรกจะวัดมุมจากหมุดสถานีหลักฐานกันเป็นหลัก และหมุดสถานีหลักฐานต้องมีค่าพิกัดและมีจำนวนอย่างน้อยสามหมุด ดังนั้นการวัดมุมอย่างน้อยสองมุมจะเพียงพอต่อการมาคำนวณ ในบทความนี้ผมจะพาไปทัวร์การคำนวณวิธี least squares ด้วยการใช้การรังวัดผสมประกอบด้วยการวัดมุมภายใน วัดระยะทาง และการวัดมุมแบริ่งหรือการวัดภาคทิศ จากนั้นจะยกตัวอย่างพร้อมทั้งวิธีการคำนวณ ปิดท้ายทดสอบผลลัพธ์การคำนวณด้วยโปรแกรม Microsurvey StarNet

การวัดแบบ 2D

การวัดแบบนี้จะวัดมุมราบและระยะราบก็พอนำมาคำนวณหาค่าพิกัดของ free station ได้ ตัวอย่างที่ผมจะแสดงการคำนวณในลำดับต่อไปจะเป็นการวัดแบบ 2D เพื่อลดความซับซ้อน

การวัดแบบ 3D

การวัดระยะทางจะวัดแบบ Slope distance วัดมุมดิ่ง ถ้าทราบค่าระดับของหมุดสถานีหลักฐานและวัดความสูงของเป้าที่ตั้งบนสถานีหมุดหลักฐาน จากนั้นวัดความสูงกล้อง เมื่อนำมาคำนวณร่วมกับมุมราบแล้วจะได้ค่าพิกัดของ free station รวมทั้งค่าระดับด้วย

แนะนำตำรา

เมื่อผมกลับไปดูวิธีการคำนวณด้วย least square แต่กลับพบกับความนะจังงัง ว่าความรู้ที่รับการประสิทธิประสาทมาบัดนี้ได้คืนท่านอาจารย์ที่มหาวิทยาลัยไปจนหมดแล้วสิ้นเชิง นั่งงงกับการตั้งสมการ Observation Equation อยู่นานพอสมควร เมื่อไม่เป็นผลก็ต้องกลับไปหาตำราค่อยๆพลิกความทรงจำกลับมาใหม่

ตำราที่จะแนะนำให้อ่านเป็นของ Mr.Rod Deakin (Rodney Edwin Deakin) ถ้าดูตามโปรไฟล์ก่อนจะเกษียณเป็นอาจารย์ให้มหาวิทยาลัยสอนเรื่อง Engineering Survey มาก่อน ตำราหรือบทความที่แต่งนั้นมีความหลากหลายมากในเว็บไซต์ส่วนตัวนี้ อ่านง่าย เพลินจนลืมไปว่าเรื่องที่อ่านนั้นยาก

ตามไปดูหน้า least squares ลองเลื่อนไปด้านล่างดูเรื่อง “Notes on Least Squares” คือตำราที่จะมาแนะนำกันมีทั้งหมด 10 บท เนื่องจากผมพอมีพื้นฐานมาบ้างเล็กน้อย จึงไม่ได้อ่านเรียงหน้าตั้งแต่บทที่ 1 แต่อาศัยข้ามไปอ่านบทที่ 7 ก่อน พอเจอเมตริกผมงงก็ข้ามไปอ่าน “Appendix A” เฉพาะเรื่องเมตริก บวก ลบ คูณ อินเวอร์ส แล้วค่อยกลับมาอ่านบทอื่นๆอีกที ดังนั้นคนที่ห่างเรื่องนี้นานๆแนะนำให้ไปดูเรื่องเมตริกอันดับแรก

บทที่ 7 อนุกรมเทเลอร์

สำหรับการคำนวณเล็งสกัดย้อนด้วยวิธี least square ปฐมบทจะอยู่ที่บทที่ 7 เริ่มต้นจากอนุกรมเทเลอร์ เหตุที่เราต้องใช้เพราะว่าสมการที่จะนำมาคิด  resection นั้นไม่ใช่สมการแบบเชิงเส้นหรือ linear equation ดังนั้นจะต้องมีการถอดสมการเชิงเส้นออกมาและอยู่ในรูปอนุกรม เพื่อให้สามารถนำมาคำนวณได้ จะมีตัวอย่างสมการ Observation Equation 2 ตัวอย่างคือ

  • วัดมุม (Measure direction)
  • วัดระยะทาง (Measure distance)

บทที่ 9 คำนวณเล็งสกัดย้อน (Least Squares Resection)

บทนี้จะเริ่มตั้งแต่ตั้งสมการ  Observation Equation (ไม่เชิงเส้น) ของการวัดมุม จาก free station ไปยังหมุดสถานีหลักฐาน จากนั้นจะถอดสมการไม่เชิงเส้นด้วยอนุกรมเทเลอร์ แล้วก็มีตัวอย่างแสดงวิธีการคำนวณ

บทที่ 10 คำนวณเล็งสกัด (Least Squares Bearing Intersection)

ผู้อ่านอาจจะสังเกตสองคำคือเล็งสกัดกับเล็งสกัดย้อน

  • เล็งสกัดย้อน (Resection) คือไปตั้งกล้องที่  free station แล้ววัดมุมภายในไปหาสถานีหมุดหลักฐาน

  • เล็งสกัด (Bearing Intersection) จะเป็นการวัดมุมแบริ่ง ตัวอย่างได้แก่การวัดดาวเหนือในสมัยก่อน คือเราจะมีหมุดคู่เป็น base line ต้องการทราบมุมแบริ่งของ base line นี้ก็ตั้งกล้องที่หมุดตัวแรกแล้วอาศัยวัดดาวเหนือกับหมุดอีกตัวบน base line ดังนั้นถ้าวัดแบริ่งสัก 2 base line ไปตัดกันก็จะได้ค่าพิกัด

การถอดสมการเล็งสกัดย้อนด้วยอนุกรมเทเลอร์

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

การวัดมุมในทางปฏิบัติจะส่องไปหาสถานีแรก P1 ตั้งมุมราบเป็น 0 แล้วกวาดไปสถานีที่ 2 วัดมุมได αi1 กวาดไปหาสถานีหลักฐาน P2 วัดมุมได้ α12 ทำเช่นนี้เรื่อยๆ จนถึงสถานีหลักฐาน Pk จะได้มุม αik แต่ในงานสำรวจด้านตรีโกณมิติเราจะไม่คำนวณโดยใช้มุมภายในแต่จะใช้มุมอะซิมัท ดังนั้นมุมภายในเหล่านี้ต้องเปลี่ยนเป็นเทอมของมุมอะซิมัททั้งหมด ซึ่งไม่ได้ยุ่งยากอะไร ถ้าทราบมุมอะซิมัทที่ไปหาสถานีแรก P1 ก็จะทราบอะซิมัทสถานีที่เหลือทั้งหมด แต่ในความเป็นจริงเราไม่ทราบ เพราะว่าค่าพิกัด P1 ยังไม่ทราบในตอนนี้

สำหรับสมการคำนวณหาอะซิมัทและระยะทางระหว่างจุด Pi และ Pk เมื่อทราบค่าพิกัดคำนวณได้ดังสมการ

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

โดยที่ E = E0 + ΔE และ N = N0 + ΔN ส่วน E0 และ N0 คือค่าเริ่มต้นเป็นค่าประมาณการ ส่วนค่า ΔE, ΔN เป็นค่าปรับแก้ (correction) ซึ่งสองตัวนี้จะคำนวณได้จากสมการ least squares ที่กำลังจะว่ากันต่อไป และถ้าดูสมการจะเห็นว่าติดค่าอนุพันธ์ (ดิฟ) ซึ่งค่าดิฟหาได้ดังนี้

จากสมการด้านบน aik, bik เรามีค่าประมาณการเริ่มต้น Ei, Ni ดังนั้นสามารถหาค่าพวกนี้ได้ มาดูสมการระยะทางค่าดิฟ หาได้ดังนี้

จากสมการด้านบน cik, dik เรามีค่าประมาณการเริ่มต้น Ei, Ni ดังนั้นสามารถหาค่าพวกนี้ได้เช่นเดียวกัน

ตั้งสมการ Observation Equation สำหรับการวัดมุมภายใน (เล็งสกัดย้อน)

สมการ Observation Equation เป็นสมการที่เป็นหัวใจของการคำนวณ least squares ถ้าตั้งสมการนี้ได้ก็สามารถคำนวณต่อได้ แต่งานรังวัดถ้าวัดเกินมาจะมี residual เป็นส่วนเกิน สมการ Observation Equation ของการวัดมุมอะซิมัทแสดงได้ดังนี้

vik คือ residual คงไม่ลืมกันนะว่า มุมอะซิมัท Øik จากสถานีตั้งกล้องไปยังแต่ละสถานีหมุดหลักฐานเท่ากับ อะซิมัทไปหมุดสถานีหลักฐานตัวแรก Zi บวกด้วยมุมราบที่กวาดไป αik เขียนในรูปอนุกรมเทเลอร์ดังนี้

ในกรณีงานรังวัดเล็งสกัดย้อน ΔNk และ ΔEk ทราบค่าพิกัดดังนั้นเทอมตัวนี้จะเป็นศูนย์ กลายเป็นสมการนี้

ตั้งสมการ Observation Equation สำหรับการวัดระยะทาง

คล้ายๆกับสมการสำหรับการวัดทิศทาง แสดงได้ดังนี้

เขียนในรูปอนุกรมเทเลอร์

ตั้งสมการ Observation Equation สำหรับการวัดแบริ่ง (เล็งสกัด)

ถือว่าเป็นอาหารเสริมก็แล้วกัน สมัยนี้ยุค GNSS  คงหายากแล้วสำหรับการวัดภาคทิศอะซิมัทด้วยการวัดดาว

สมการเดียวกับที่เราใช้เล็งสกัดย้อน แต่ในที่นี้เราทราบค่าพิกัด Nk, Ek  ทำให้ ΔNk และ ΔEk เทอมตัวนี้จะเป็นศูนย์ และสมการจะคงเหลือดังนี้

ตัวอย่างงานรังวัดเล็งสกัดย้อนแบบรวมวัดมุม ระยะทาง และรังวัดภาคทิศ

มาถึงตอนนี้ผู้อ่านบางท่านเห็นสมการแล้วอาจจะงงงวยเหมือนผมในตอนแรกๆ มาลองแก้สมการดูจากตัวอย่างโจทย์ ที่นี้จะทำให้เข้าใจมากขึ้น ดูรูปด้านล่าง ตั้งกล้องที่จุด P ทำการรังวัดโดยที่วัดมุมไปยังสถานีหลักฐาน โจทย์ตัวนี้เป็นโจทย์ที่ผมเจอในอินเทอร์เน็ต เมื่อค้นหาการคำนวณเล็งสกัดย้อนแบบวิธีคำนวณ least square ดูได้ที่ลิ๊งค์นี้ โจทย์ที่จะคำนวณเปิดไปดูได้หน้าท้ายๆ

กำหนดค่าพิกัดหมุดสถานีหลักฐานดังตารางด้านล่าง วัดมุมโดยที่เล็งไปที่สถานี 1 ตั้งมุมราบเป็นศูนย์แล้ววัดมุมไปที่สถานี 2, 4, 5 และ 6 ทำการวัดระยะทางไปที่สถานี 1, 3  และ 5  รังวัดภาคทิศ (วัดดาว) ที่สถานี 1, 3 และ 6 ดังตารางด้านล่าง

คำนวณหาค่าพิกัดจุดตั้งกล้องโดยประมาณ

ผมใช้เครื่องคิดเลข fx 9860 GII SD คำนวณหาค่าพิกัดของ P  ด้วยโปรแกรม Resection ป้อนค่าพิกัดและมุมได้ดังนี้

จุด A, B และ C  ของเครื่องคิดเลขก็คือจุดที่ 1, 2 และ 6 ของโจทย์ด้านบนตามลำดับ

ผมจะใช้ค่าจุด P ที่ค่าพิกัดโดยประมาณ N = 193939.897 E = 110879.464 เพื่อเป็นค่าเริ่มต้นในการคำนวณด้วย least squares

เนื่องจากบทความยาวมาก ติดตามกันตอนที่ 2 ต่อนะครับ

Update: โปรแกรมคำนวณเล็งสกัดย้อนฉบับปรับปรุง (Resection) สำหรับเครื่องคิดเลขเทพ Casio fx 9860G II SD

Update: โปรแกรมคำนวณเล็งสกัดย้อนฉบับปรับปรุง (Resection) สำหรับเครื่องคิดเลขเทพ Casio fx 9860G II SD

ผมเขียนเรื่องการคำนวณเล็งสกัดย้อน (Resection) จากตอนก่อนหน้านี้ด้วยอัลกอริทีมใหม่ของ Josep M. Font-Llagunes อ่านได้ที่

ติดปีกเครื่องคิดเลขเทพ Casio fx 9860G II SD ด้วยโปรแกรมภาษาซีบน AddIn ตอนที่ 5 โปรแกรมคำนวณ Resection ด้วยอัลกอริทึ่มสมัยใหม่


ในตอนนี้ผมจะมาเรียบเรียงโปรแกรมด้วยไลบรารี MyLib ที่ใช้ก่อนหน้านี้มาหลายโปรแกรมแล้ว โดยในครั้งนี้จะใช้อัลกอริทึมหลายๆตัวมาคำนวณเพื่อเปรียบเทียบกันดู เมื่อคำนวณแล้วมีรูปกราฟฟิคหยาบๆให้ดูพอกล้อมแกล้ม

การคำนวณเล็งสกัดย้อน หรือ Resection Problem มีมานานแล้วหลักๆแล้ววิธีการคำนวณแบ่งเป็น 2 วิธีหลักๆคือ แบบการตรีโกณมิติ (Trigonometric Solution) และวิธีการแบบเรขาคณิตวงกลมตัดกัน (Geometric Circle Intersection) วิธีการนี้นอกจากนำมาใช้ในงานสำรวจแล้ว ในแวดวงหุ่นยนต์ที่ใช้ในสถานที่ในร่ม ผู้อ่านอาจจะคุ้นกับการแข่งขันหุ่นยนต์ของน้องๆนักศึกษา การหาตำแหน่งในร่มของหุ่นยนต์จะอาศัยวิธีการนี้ จะอาศัยตั้งสถานีฐานที่รู้ค่าพิกัด 3 สถานี (Beacon) แล้วหุ่นยนต์จะมีอุปกรณ์จำพวก Goniometer ที่คอยหมุนกวาดหามุม 3 มุม จากตำแหน่งที่หุ่นยนต์ตั้งอยู่กับสถานีฐานนั้น จากนั้นจะคำนวณหาพิกัดตัวเองแบบ realtime

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

รายชื่อโปรแกรมเล็งสกัดย้อน

1.Kaestner-Burkhardt Method ใช้ตรีโกณมิติมาช่วยในด้านการคำนวณ วิธีการคำนวณนี้คิดค้นกันมานมนานแล้วและวิธีการคำนวณจะตั้งชื่อตามผู้ที่คิดค้น วิธีการนี้ได้มีคนนำมาปรับปรุงกันหลายครั้ง

2.TienStra Method ใช้วิธีการด้านตรีโกณมิติมาช่วยในการคำนวณ

 

3.Collins Method ใช้วิธีการด้านตรีโกณมิติมาช่วยในการคำนวณ

4.Cassini Method ใช้วิธีการด้านตรีโกณมิติมาช่วยในการคำนวณ

5.Font-Llagunes ใช้วิธีเรขาคณิตโดยใช้วงกลมมาตัดกันมาช่วยในการคำนวณ

ผมประยุกต์โดยการนำสูตรมาแปลงเป็นโค้ดภาษาซี  โดยได้นำวิธีการคำนวณทั้งหมด 5 วิธี แต่คงไม่สามารถอธิบายวิธีการคำนวณได้หมด

ดาวน์โหลดโปรแกรม (Download)

ไปที่หน้าดาวน์โหลด (Download) หรือไปที่โปรแกรม Resectionจะได้ไฟล์ชื่อ “RESCTNEX.G1A” จากนั้นทำการก็อปปี้ไฟล์เข้าเครื่องคิดเลขผ่านโปรแกรม Casio FA-124 หรือ copy ผ่าน SD Card ก็สะดวกเหมือนกัน

เริ่มใช้งานโปรแกรม

ที่เครื่องคิดเลขกดปุ่ม “MENU” จะเห็นลิสต์ของไอคอนของโปรแกรมต่างๆ ตัวโปรแกรม Resection อยู่ด้านล่างๆใช้ปุ่มลูกศร เลื่อนลงมาแล้วกดคีย์ “EXE

เมนูหลัก  (Main Menu)

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

Met – Method (F1) เลือกวิธีการคำนวณที่ผมกล่าวมาข้างต้นจำนวน 5 วิธี

Coor – Coordinates (F2) ป้อนค่าพิกัดของเป้าหลัง (control point) จุดที่ทราบค่าพิกัด 3 จุด (A, B และ C ตามลำดับ)

Ang – Angle (F3) ป้อนค่ามุมสองมุม (α และ β ตามลำดับ)

Calc – Calculate (F4) คำนวณเล็งสกัดย้อนหาค่าพิกัดจุดตั้งกล้อง

Info – Information (F5) แสดงเครดิตไลบรารีที่ใช้งาน

Exit – Exit (F6) ออกจากโปรแกรมนี้

เลือกวิธีการคำนวณ (Method)

ที่เมนูหลักของโปรแกรมกดคีย์ F1 – Met เลือกวิธีการคำนวณ จะเห็นหน้าจอแสดง Resection Method

กดคีย์ “EXE” จะเห็น drop down list ลงมาให้เลือกดังรูปด้านล่าง ในที่นี้ลองเลือก “TienStra

กด F6 – OK เพื่อออก

ตัวอย่างที่ 1 กำหนดค่าพิกัดจุด A (1000E, 2000N) ค่าพิกัดจุด  B (1078.331E, 2077.869N) และค่าพิกัดจุด C (1172.191E, 2154.753N) วัดมุม α = 40°8’24” และมุม β = 57°36’0″ หาค่าพิกัดจุด P

ป้อนค่าพิกัดหมุดหลักฐาน (Input Control Points Coordinates)

ที่เมนูหลักกดคีย์ F2-Coor เพื่อป้อนค่าพิกัดหมุดหลักฐานที่ทราบค่าพิกัด 3 จุด ดังนี้

 

กดคีย์ F6 – OK เพื่อออก

ป้อนค่ามุม (Input Angles)

ที่เมนูหลักกดคีย์ F3 – Ang เพื่อป้อนมุม 2 มุมดังนี้ สำหรับการป้อนมุมให้ใช้เครื่องหมายลบ (-) คั่น

กดคีย์ F6 – OK เพื่อออก

คำนวณหาค่าพิกัด (Calculate Resection)

ที่เมนูหลักกดคีย์ F4 – Calc เพื่อคำนวณเล็งสกัดย้อน จะได้ผลลัพธ์ดังรูปด้านล่าง กดคีย์ F1 – PgUp หรือ F2 – PgDn เพื่อเลื่อนดูผลลัพธ์ โปรแกรมจะแสดงค่าพิกัดหมุดหลักฐาน 3 จุด พร้อมทั้งมุมที่ป้อนไปเพื่อทบทวนว่าผู้ใช้ป้อนเข้าไปถูกต้องตามที่ต้องการหรือไม่ และสุดท้ายก็แสดงค่าพิกัดจุดเล็งสกัดย้อน (Resection) ที่เราต้องการคือ (1167.446E, 2016.916N)

แสดงแผนผัง (Plot)

ต้องการดูแผนผังการจัดวางตัวของจุดหลักฐาน 3 จุดและผลลัพธ์ก็สามารถดูได้คร่าวๆ กดคีย์ F5 – Plot 

สามารถกดคีย์ F1 – Dn (Down) เพื่อเลื่อนภาพลง) F2 – Up (เลื่อนภาพขึ้น) F3 – Lt (Left เลื่อนภาพไปด้านซ้าย) F4 – Rt (เลื่อนภาพไปด้านขวา) หรือกด F5 – M-> (เลือกเมนูด้านขวา) เมนูด้านขว่าจะมี F1 -Z+ (เพื่อขยายภาพ) F2 – Z- (เพื่อย่อภาพ) เสร็จแล้วกดคีย์ F6 -Done เพื่อออก กดคีย์ F6 – Done อีกครั้งเพื่อออกมาเมนูหลัก

คำนวณด้วยวิธีการอื่น

การคำนวณด้วยวิธี Tienstra ได้นำเสนอไปแล้วลองมาใช้วิธีการอื่นมาลองคำนวณบ้าง ถ้าผู้ใช้ออกจากโปรแกรมด้วยการกดคีย์ F6 – Exit โปรแกรมจะทำการเก็บค่าต่างๆที่ป้อนไปทังหมดไว้ เมื่อเข้ามาใช้โปรแกรมอีกรอบ ถ้าต้องการใช้ค่าเดิมจะไม่ต้องป้อนใหม่อีกครั้ง

Kaestner-Burkhardt Method

ที่เมนูหลักกดคีย์ F1 -Met เพื่อเลือกวิธีการคำนวณ ในที่นี้เลือก Kaestner กดคีย์ F6 – OK เพื่อออก

ที่เมนูหลักกดคีย์ F3 – Calc เพื่อทำการคำนวณ (ไม่ต้องป้อนค่าพิกัดและค่ามุมใหม่) จะได้ผลลัพธ์มาดังนี้ กดคีย์ F1 – PgUp หรือ F2 – PgDn เพื่อเลื่อนดูผลลัพธ์

สังเกตว่าค่าพิกัดที่ได้ (1168.228E, 2014.113N) มีความต่างจากวิธี Tienstra (1167.446E, 2016.916N)ไปพอสมควร ผมไม่แน่ใจเมื่อตรวจสอบโค้ดที่แปลงจากสูตรก็ยังคิดว่าไม่มีที่ผิด ลองไปเทียบดูจากวิธีอื่นอีกที

 

Cassini Method

ที่เมนูหลักกดคีย์ F1 – Met เพื่อเลือกวิธีการคำนวณ เลือก “Cassini” กดคีย์ F6 – OK  เพื่อออก

ที่เมนูหลักกดคีย์ F3 – Calc เพื่อทำการคำนวณ (ไม่ต้องป้อนค่าพิกัดและค่ามุมใหม่) จะได้ผลลัพธ์มาดังนี้ กดคีย์ F1 – PgUp หรือ F2 – PgDn เพื่อเลื่อนดูผลลัพธ์

 

จะได้ค่าพิกัดผลลัพธ์ออกมาจากวิธีการของ Cassini (1167.446E, 2016.916N) ซึ่งเท่ากับวิธีการของ Tienstra

Collins Method

ที่เมนูหลักกดคีย์ F1 – Met เพื่อเลือกวิธีการคำนวณ เลือก “Collins” กดคีย์ F6 – OK  เพื่อออก

ที่เมนูหลักกดคีย์ F3 – Calc เพื่อทำการคำนวณ จะได้ผลลัพธ์มาดังนี้

จะได้ค่าพิกัดผลลัพธ์ออกมาจากวิธีการของ Collins (1167.446E, 2016.916N) ซึ่งเท่ากับวิธีการของ Tienstra, Cassini

 

 

Font-Llagunes

เป็นวิธีการที่ผมชอบมากที่สุดและเคยเขียนลงแบบละเอียดในตอนก่อนหน้านี้ การใช้งานทำได้ตามขั้นตอนดังต่อไปนี้ ที่เมนูหลักกดคีย์ F1 – Met เพื่อเลือกวิธีการคำนวณ เลือก “Font-Llagunes” กดคีย์ F6 –  OK เพื่อออก

กดคีย์ F3 – Calc เพื่อทำการคำนวณ จะได้ผลลัพธ์มาดังนี้ กดคีย์ F1 – PgUp หรือ F2 – PgDn เพื่อเลื่อนดูผลลัพธ์

เช่นเดียวกันจะได้ค่าพิกัดผลลัพธ์ออกมาจากวิธีการของ Font-Llagunes (1167.446E, 2016.916N) ซึ่งเท่ากับวิธีการของ Tienstra, Cassini และ  Collins แต่บางครั้งจะต่างกับวีธีการของ Kaestner-Burkhardt ในระดับหลักเมตร

 

 

ตัวอย่างที่ 2 กำหนดค่าพิกัดจุด A (1000E, 5300N) ค่าพิกัดจุด  B (2200E, 6300N) และค่าพิกัดจุด C (3100E, 5000N) วัดมุม α = 109°18’16.2″ และมุม β = 115°3’7.2″ หาค่าพิกัดจุด P

การคำนวณผมจะใช้การรวบรัดขอเสนอแต่วิธีการของ Font-Llagunes เท่านั้น ที่เมนูหลักกดคีย์ F1 – Met เพื่อเลือกวิธีการคำนวณ เลือก Font-Llangunes จาก drop down list กดคีย์ F6 – OK เพื่อออก

ที่เมนูหลักกดคีย์ F2- Coor เพื่อป้อนค่าพิกัด เสร็จแล้วกดคีย์ F6 – OK

ที่เมนูหลักกดคีย์ F3 – Ang เพื่อป้อนมุม เสร็จแล้วกดคีย์ F6 – OK

ที่เมนูหลักกดคีย์ F4 – Calc เพื่อทำคำนวณ กดคีย์ F1 – PgUp หรือ F2 – PgDn เพื่อเลื่อนดูผลลัพธ์

จะได้ค่าพิกัดจุดเล็งสกัดย้อนมาเท่ากับ (2128.989E, 5575.375N) กดคีย์ F5 – Plot เพื่อดูแผนผัง

ก็ได้รูปการวางตัวของจุดหลักฐาน 3 จุดและจุดที่ต้องการทราบค่าคือจุด P น่าเสียดายที่ผมไม่สามารถวาดมุมแสดง dimension เพราะข้อจำกัดของเครื่องคิดเลข และต้องเตือนกันอีกนิดว่าจุด 4 จุดนี้ต้องไม่อยู่บนวงกลมเดียวกัน (โอกาสเกิดน้อยมากๆครับ) ไม่ว่าสูตรไหนก็ไม่สามารถคำนวณได้ เรียกภาวะอย่างนี้ว่าเกิดเหตุการณ์สภาวะเอกฐาน Singularity

 

สำหรับโปรแกรมในชุดเครื่องคิดเลข Casio fx-9860G II SD คงจะมีอีกหลายตอนครับ สำหรับเครดิตของโปรแกรมในชุดนี้ก็กดคีย์ F5 – Info จากเมนูหลัก ก็ติดตามกันตอนต่อไปครับ 

 

ติดปีกเครื่องคิดเลขเทพ Casio fx 9860G II SD ด้วยโปรแกรมภาษาซีบน AddIn ตอนที่ 5 โปรแกรมคำนวณ Resection ด้วยอัลกอริทึ่มสมัยใหม่

ติดปีกเครื่องคิดเลขเทพ Casio fx 9860G II SD ด้วยโปรแกรมภาษาซีบน AddIn ตอนที่ 5 โปรแกรมคำนวณ Resection ด้วยอัลกอริทึ่มสมัยใหม่

การเล็งสกัดย้อน (Resection) และความเป็นมา

ในที่สุดก็มาถึงตอนที่ 5 ตอนที่ผมใช้เวลามากที่สุดในการ implement อัลกอริทึ่มที่ใช้คำนวณปัญหา Resection จาก 3 จุดที่กำหนด (Three Points Resection Problem) เป็นที่ทราบกันดีว่าการคำนวณ Resection นั้นนักคณิตศาสตร์ได้คิดค้นกันมาหลายร้อยปีแล้ว มีอัลกอริทึ่มรวมๆกันไม่น้อยกว่า 500 อัลกอริทึ่ม แต่บางอัลกอริทึ่มนั้นอายุเก่าแก่มากใช้การคำนวณหาด้วยการวาดลงบนกระดาษ ถ้าจะคัดออกมาจริงๆที่ใช้กันในปัจจุบันมีประมาณ 18 อัลกอริทึ่มหลักๆ และสามารถนำมา implement เป็นโปรแกรมในคอมพิวเตอร์ได้ ก่อนจะไปต่อกันลึกๆมาดูกันว่า Resection คืออะไร

การเล็งสกัดย้อน(Resection) คือการวัดพิกัดจุดตั้งกล้องจากสถานีที่ทราบค่าพิกัด 3 สถานี ตามตัวอย่างได้แก A, B และ C และวัดมุมราบคือมุม α และ β ตามลำดับ

ผมคนรุ่นเก่ายังทันเครื่องมือวัดมุม Sextant ผมทัน Sextant นี้ในช่วงทำงานใหม่ๆ โดยที่ลงเรือไปในทะเลกับพี่ๆช่างสำรวจของกรมเจ้าท่า ตอนนั้นเพิ่งเรียนจบมาใหม่ ยุคนั้น GPS/GNSS ยังไม่เป็นที่รู้จัก การวัดตำแหน่งของเรือสำรวจใช้เครื่องมือ Sextant ที่อาศัยหลักการของ Resection มาประยุกต์ใช้ บนเรือสำรวจจะมีเจ้าหน้าที่ 2 คน คนแรกจะส่องสถานี A และ B เพื่อวัดมุม α และคนที่สองจะส่องสถานี B และ C เพื่อวัดมุม β สองคนนี้ตามหลักการแล้วต้องขี่คอกันแต่จริงๆคงไม่มีใครทำเพียงแต่นั่งใกล้ๆกัน การใช้ Sextant วัดตำแหน่งเรือต้องอาศัยความชำนาญอย่างสูง เพราะเรือไม่อยู่นิ่งกับที่เพราะคลื่มลม จะปะทะให้เคลื่อนไหวตลอดเวลา

เมื่อการวัดมุมเสร็จสิ้นลงทั้งสองคนจะจดค่ามุม ∝ และ ∅ พร้อมๆกัน การใช้ Sextant ควบคู่ไปกับกับใช้เครื่องมือวัดความลึกของท้องน้ำจำพวก Echo sounder งาน post processing ในออฟฟิศได้แต่การนำค่ามุม α และ β มาคำนวณหาค่าพิกัดแตละจุด จากนั้นก็จัดทำแผนที่แสดงความลึกของแม่น้ำหรือทะเลในบริเวณที่ทำการสำรวจ ถึงแม้กระนั้นเครื่องมือ Sextant จะให้ค่าความละเอียดด้านมุมไม่ดีนัก แต่ค่าพิกัดที่ได้สมัยนั้นก็เพียงพอสำหรับงานในทะเลหรือแม่น้ำ

หัวข้อต่อๆไปจะกล่าวถึงที่ไปที่มาของสูตรที่ผมใช้สำหรับเครื่องคิดเลข fx-9860G ถ้าผู้อ่านไม่สนใจก็ข้ามไปที่การใช้โปรแกรมเครื่องคิดเลขด้านท้ายๆเลยครับ

หลักการคำนวณ Resection

อัลกอริทึ่มที่ผมกล่าวไปนั้นตั้งแต่ยุคอดีตกาลนั้นมากกว่า 500 อัลกอริทึ่ม แต่ส่วนใหญ่แล้วอาศัยหลักการคล้ายๆกันคือใช้หลักวงกลมสามวงตัดกันที่จุด P วงแรกจะลากผ่านจุด A-P-B วงที่สองลากผ่านจุด B-C-P วงที่สามลากผ่าน C-P-A ดังรูปด้านล่าง

ภาวะเอกฐาน (Singularity) ที่อัลกอริทึ่มล้มเหลว

ผมขอยืมคำแปล Singularity ที่แปลว่าภาวะเอกฐานจากเรื่องหลุมดำในทฤษฎีฟิสิกส์ควอนตัมหน่อย เพราะมันได้ใจความคือภาวะที่ทฤษฎีทางคณิตศาสตร์ล้มเหลว คือเหมือนกับพลัดตกลงไปในหลุมดำประมาณนั้น

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

ภาวะเอกฐานเสมือน (Pseudo Singularity)

ภาวะเอกฐานเสมือนเป็นสภาวะที่จุด P มาอยู่บนเส้นตรงระหว่าง A-B หรือ B-C หรือ A-C ด้านล่างจะเป็นกรณีจุด P อยู่บนเส้นตรงระหว่างจุด B และ C จะทำให้มุม β มีค่ากับ π เรเดียน (หรือเท่ากับ 180 องศา) หรือถ้าขยับจุด P ให้เลยออกจากจุด B แตยังอยู่ในแนวเส้นตรง ในกรณีนี้จะได้ มุม β = 0

ภาวะเอกฐานเสมือนนี้สูตรหลายๆสูตรไม่สามารถหาค่าได้เช่นสูตร Tienstra Method

อัลกอริทึ่มสมัยใหม่ (Modern Algorithm)

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

    1. A New Three Object Triangulation Algorithm for Mobile Robot Positioning โดย Vincent Pierlot and Marc Van Droogenbroeck ทั้งสองท่านจบวิศวกรไฟฟ้า งานวิจัยนี้มีโค้ดภาษา C ด้วย แต่เนื่องจากลิขสิทธิ์ที่ระบุให้ใช้ในวงการศึกษาหรือใช้งานส่วนตัวเท่านั้น ผมจึงไม่สามารถนำโค้ดมาใช้งานได้เพราะยังกำกวม ความจริงงานทั้ง 2 ท่านได้รวบรวมอัลกอริทึ่มรวมทั้งของตัวเองด้วยทั้งหมด 18 อัลกอริทึ่มและ implement มาเป็นโค้ด พร้อมทั้งวัด benchmark ว่าใค้ดใครเร็วที่สุด ก็ตามคาดหมายโค้ดที่ทั้งสองท่านคิดค้นมานั้นเข้าวิน แต่สำหรับผมแล้วความต่างมันหนึ่งในพันส่วนของวินาทีอาจจะจำเป็นสำหรับงานให้ตำแหน่งหุ่นยนต์ที่ต้องมีการคำนวณตำแหน่งแบบ real time แต่สำหรับงานสำรวจในภาคสนามความจำเป็นกลับต่างออกไป
    2. New Method That Solves the Three-Point Resection Problem Using Straight Lines Intersection โดย Josep M. Font-Llagunes and Joaquim A. Batlle ผมชอบความคิดของสองท่านนี้ดูจากโพรไฟล์แล้วจบวิศวกรเครื่องกล แต่เนื่องจากเอกสารเข้าใจยากไปนิด ผมกลับใช้เวลาแกะอัลกอริทึมโดยใช้เวลาพอสมควรกว่าจะออกมาเป็นโค้ดได้ โปรแกรมสามารถคำนวณในสภาวะเอกฐานเสมือนได้

หลักการคำนวณโดยย่อ

ผมไม่มีเวลาที่จะศึกษาสูตรในเบื้องลึกให้กระจ่างมากนั้นแต่เน้น implement มาเป็นโค้ดภาษา C ดังนั้นความเข้าใจจึงอยู่ในระดับผิวเผิน ต่อไปผมจะบอกเล่าสิ่งที่ผมเข้าใจแบบจำกัดจำเขี่ย เราจะมาเริ่มต้น สมมติว่าตอนนี้ถ้าทราบค่าพิกัด P แล้วเราสามารถหาค่าอะซิมัทจากสถานี A, B และ C ไปยังจุด P ได้ง่ายๆ ตามรูปด้านล่าง

ค่าอะซิมัทของสถานีที่ทราบค่าพิกัด

1.คำนวณหาค่าอะซิมัทโดยประมาณ (Θ)

แต่ในชีวิตจริงค่าพิกัด P เป็นสิ่งที่เรายังไม่ทราบดังนั้นสูตรคำนวณนี้จะมีการหาค่าโดยประมาณก่อน Θ = θ – โดย  คือค่าเบี่ยงเบนไปจากค่าจริงจากที่เราประมาณ ถ้าทุกๆเส้นเบี่ยงเบนไป  เราสามารถลากเส้นไปตัดกันเป็นรู)สามเหลี่ยมเล็กๆ แต่ถ้า  ที่ประมาณการณ์ไว้มีขนาดเบี่ยงเบนไปมาก ก็จะได้ขนาดสามเหลี่ยมนี้ใหญ่ขึ้น สามเหลี่ยมนี้ทางผู้คิดค้นเรียกว่า error triangle จุดตัดแทนที่ด้วย PAB, PBC และ PAC

2.คำนวณหาค่าพิกัดของ Error Triangle

ค่าพิกัดของจุดตัด P นี้สามารถคำนวณได้จากสูตร

โดยที่ mA = cot(Θ), mB = cot(Θ – α) และ mC = cot(Θ – α -β) ไม่ลืมว่า Θ คือค่าอะซิมัทโดยประมาณ

3.คำนวณหาค่าพิกัดของ Centers Triangle

ถ้าจากจุด P ลากเส้นตรงไปหาสถานีที่ทราบค่าพิกัดแล้วแบ่งครึ่งลากเส้นตั้งจาก เราจะได้สามเหลี่ยมอีกชุดหนึ่งเรียกว่า centers triangle  และเป็นสามเหลี่ยมคล้ายสามเหลี่ยม error triangle ดังนั้นความสัมพันธ์ด้านมุมและระยะระหว่างสามเหลี่ยมสองรูปนี้สามารถคำนวณได้ ดังนั้นค่าพิกัดของ centers triangle สามารถคำนวณหาค่าพิกัดจุดตัด CAB, CBC และ CAC ได้จากสูตรดังต่อไปนี้

4.คำนวณมุมเบี่ยงเบน

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

สามารถคำนวณสมการ (9) จากระยะทางแต่ละด้านของ error triangle และ centers triangle เช่นตัวอย่าง |δθ| = arcsin(ระยะทางระหว่างจุด PAB– PBC / ระยะทางจุด CAB– CBC )

หรือในสมการ (10) สามารถใช้พื้นที่ของสามเหลี่ยมสองรูปนี้ได้

5.คำนวณหาเครื่องหมายมุมเบี่ยงเบน

ก่อนหน้านี้ที่แสดงค่าที่คำนวณได้ในสมการ (9) และ (10) จะเห็นว่าติดเครื่องหมาย absolute ไว้คือยังไม่ได้คิดเครื่องหมาย ส่วนเครื่องหมายมุมเบี่ยงเบนหาได้ดังนี้

ทางผู้พัฒนาแสดงทิศทางของ error triangle เมื่อเทียบ center triangle ตามเครื่องหมายของ error triangle ดังนี้

อาจจะดูยากไปนิดเป็นการคูณไขว้กัน ดูตัวอย่างเพื่อความง่าย

sign = (xPAC-xPBC)*(yCAC-yCBC) – (xCAC-xCBC)*(yPAC-yPBC)

ค่าของ  sign จะออกมาเป็นบวกหรือเป็นลบ แล้วจะเอาเครื่องหมายนี้ไปใส่ให้สมการในข้อต่อไป

6.คำนวณหาอะซิมัทที่ถูกต้อง

สมการ θ=Θ +sign(dθ)

7.คำนวณหาพิกัดของจุดตัด Resection

ถ้าจุดตัดไม่ตกหลุมดำ ก็สามารถคำนวณหาจุดตัดได้จาก 1 ใน 3 สมการ ของสมการ (1), (2) หรือ (3) เช่นตัวอย่าง

mA = cot(θ)
mB = cot(θ – α)
xP = (mA x xA – mB x xB – yA + yB) / (mA – mB)
yP = mA x (xP – xA) + yA

การคำนวณเมื่อจุดตัดตกภาวะเอกฐานเสมือน

จะมี 3 กรณีคือ

1) ค่า α = 180 หรือ α = 0

2)ค่า β = 180 หรือ β = 0

3)ค่ามุม α+β = 180 หรือ α+β = 0

จากการคำนวณในข้อ 3 จะสังเกตในสูตร (5) จะมีตัวคูณด้วย cot(α) อยู่ ในกรณีนี้จุดตัด P อยู่บนเส้นตรงระหว่างจุด A และ B ดังนั้นมุม α = 180 องศาจะทำให้ cot(α) ไม่สามารถคำนวณได้เพราะค่าเป็นอนันต์ (infinity)  ในเคสนี้เราจะไม่คำนวณหาจุด CAB เพราะหาไม่ได้นั่นเอง แต่จุด CBC และ CAC ก็ยังหาได้ปกติ ดังนั้นในกระบวนการสุดท้ายค่าพิกัดของจุด P สามารถคำนวณได้จากการใช้สมการอีก 2 สมการคือสมการ (2) และ (3)

ไม่ใช้สมการ (1) เพราะมีค่า (mA – mB)  = 0 ทำให้ห่าค่า xP ไม่ได้

ข้อสังเกต สามารถลากวงกลมได้แค่ 2 วงเท่านั้นคือวงกลม A-P-C และ B-P-C ส่วนอีกวงลากไ่ม่ได้เพราะว่า A-P-B เป็นเส้นตรง

ดาวน์โหลด (Download) โปรแกรมสำหรับเครื่องคิดเลข fx-9860G

ไปที่หน้าดาวน์โหลดมองหาโปรแกรม Resection เมื่อดาวน์โหลดมาแล้วจะได้ไฟล์ “RESCTION.G1A” ใช้โปรแกรม FA-124 ทำการโอนโปรแกรมเข้าเครื่องคิดเลข (ดูโพสต์เก่าได้วิธีการนี้) จะเห็นไอคอนปรากฎที่หน้า AddIn ดังรูป

กรณีที่ 1 ตัวอย่างงานรังวัดในงานสำรวจทั่วไป (Survey Engineering Example)

กำหนดค่าพิกัดของสถานี A, B และ C ดังนี้

วัดค่ามุม ∝ และ ∅ จากกล้อง total station ได้ดังนี้ ∝= 40°35’22.11“ และค่ามุม ∅ = 9°18’31.84“ ที่ไอคอนโปรแกรมกดคีย์ “EXE” เข้าไปป้อนค่าพิกัดสถานีทั้งสามดังนี้

จากนั้นป้อนมุมภายใน

โปรแกรมจะคำนวณหาค่าพิกัดของจุดตัด โดยที่แจ้งสถานะมาก่อนว่าคำนวณได้ Resection Solved…

กรณีที่ 2 ตัวอย่างงานที่จุดตัดตกอยู่ในภาวะเอกฐานเสมือน (Pseudo Singularity)

นี่เป็นกรณีพิเศษจริงๆ เพราะว่าหลายๆสูตรคำนวณด้วยวิธีนี้ไม่ได้เช่นสูตร Tienstra กำหนดค่าพิกัดสถานี  A (2639303.349mN, 231605.043mE) ค่าพิกัดสถานี B (2639271.845mN, 231419.755mE) และสถานี C (2639180.389mN, 231561.178mE) มุมที่รังวัดมา α = 180° มุม β = 105°3’14.94“

ข้อสังเกตุถ้ามุม α เท่ากับ 180 แสดงว่าจุดตัดตกอยู่บนเส้นตรงระหว่างสถานี A และ B แต่เขยิบเข้าไปใกล้ B มากกว่าเพราะว่ามุม β เป็นมุมป้าน มาดูการคำนวณจากเครื่องคิดเลข เมื่อเรียกโปรแกรมมาแล้วป้อนค่าพิกัดสถานีตามลำดับ A, B และ C แล้ว

จากนั้นป้อนมุม α และ β

ผลลัพธ์ที่ได้

กรณีที่ 3 ตัวอย่างจุดตัดตกหลุมดำในภาวะเอกฐาน (Singularity)

กรณีสุดท้าย โอกาสที่จะเจอแบบนี้คือสถานีทั้งสามสถานีอยู่บนวงกลมเดียวกันและจุดที่ตั้งกล้องที่ต้องการทราบค่าพิกัดและยังมาอยู่บนวงกลมเดียวกันทั้ง 4 จุด ในชีวิตจริงมีโอกาสน้อยมากเหมือนกับถูกล็อตเตอรีรางวัลที่ 1 ยังไงยังงั้น มาลองคำนวณดู

กำหนดค่าพิกัดสถานี A (2369180.389mN, 231561.178mE) สถานีพิกัดสถานี B (2639303.349mN, 231605.093mE) และสถานี C (2639478.455mN, 231509.233mE) วัดมุม α = 29°32’23.9“และ β = 18°48’43.9“

เมื่อเข้าไปในโปรแกรมป้อนค่าพิกัด A, B และ C ตามลำดับ

จากนั้นป้อนมุม α และ β ตามลำดับ

สุดท้ายโปรแกรมไม่สามารถคำนวณหาพิกัดจุดตัดได้และแสดงว่า Resection unsolved…

เครดิต (Credit)

ก็ยกเครดิตสำหรับอัลกอริทึ่มหรือสูตรคำนวณนี้ให้กับสองท่านคือ Josep M. Font-Llagunes and Joaquim A. Batlle.

ซอร์สโค้ดสูตรคำนวณ (Sourcecode)

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

/* Algorithm based on Josep M. Font-Llagunes and Joaquim A. Batlle.
  - Input angles are radians. 
  - Internal angles is clock-wise direction.
  - A, B and C must be located from right to left respectively.*/
bool straightLineIntersection(double *xP, double *yP,
				double alpha_AB, double alpha_BC,
				double xA, double yA, double xB, double yB, double xC, double yC)
{
  double mA, mB, mC; //slope of lines.
  double cot_12, cot_23, cot_31;
  double pAB, pAC, pBC; //Euclidean distance between station.
  double estB; //Estimated angle A-B-C.
  double xPAB, yPAB, xPBC, yPBC, xPAC, yPAC; //error triangle.
  double xCAB, yCAB, xCBC, yCBC, xCAC, yCAC; //center of triangle.
  double deltatheta;
  double theta; //first estimated and actual azimuth from P to A at the end.
  double AP, AC;
  double sign;
  double dPAC_PBC, dCAC_CBC;
  double dPAB_PBC, dCAB_CBC;
  double dPAB_PAC, dCAB_CAC;

  pAB = sqrt((xA-xB)*(xA-xB) + (yA-yB)*(yA-yB));
  pAC = sqrt((xA-xC)*(xA-xC) + (yA-yC)*(yA-yC));
  pBC = sqrt((xB-xC)*(xB-xC) + (yB-yC)*(yB-yC));

  estB = acos((pAB*pAB + pBC*pBC - pAC*pAC) / (2*pAB*pBC));
  //Check if found absolutely singularity then stop and return.
  if (((estB + alpha_AB + alpha_BC - PI) >= -0.0001) and 
      ((estB + alpha_AB + alpha_BC - PI) <= 0.0001))
    return false;

  /*first guess (theta), try to avoid for cot(angle) 
    when angle == PI or zero).*/ 
  theta = alpha_AB + alpha_BC/2.0;    
  mA = cot(theta);
  mB = cot(theta - alpha_AB);
  mC = cot(theta - alpha_AB - alpha_BC);
	
  //calc coordinates of error triangle.
  xPAB = (mA*xA - mB*xB - yA + yB) / (mA - mB);
  yPAB = mA*(xPAB - xA) + yA;  
  xPBC = (mB*xB - mC*xC - yB + yC) / (mB - mC);
  yPBC = mB*(xPBC - xB) + yB;
  xPAC = (mA*xA - mC*xC - yA + yC) / (mA - mC);
  yPAC = mA*(xPAC - xA) + yA;
	
  dPAC_PBC = sqrt((xPAC-xPBC)*(xPAC-xPBC) + (yPAC-yPBC)*(yPAC-yPBC));
  dPAB_PBC = sqrt((xPAB-xPBC)*(xPAB-xPBC) + (yPAB-yPBC)*(yPAB-yPBC));
  dPAB_PAC = sqrt((xPAB-xPAC)*(xPAB-xPAC) + (yPAB-yPAC)*(yPAB-yPAC));
  
  AP = ((xPAB - xPBC) * (yPBC - yPAC) - (xPBC - xPAC) * (yPAB - yPBC))/* / 2*/ ;
  AP = (AP < 0.0) ? -AP : AP;

  /* The next 3 Cases are psudosingularities.
    
    1st case: P is aligned with A & B.Therefore cannot calc PAB & CAB.*/
  if (alpha_AB == PI || alpha_AB == 0.0){ /* P is aligned on A & B.*/
    /* cot(alpha_AB) is infinity */
    cot_23 = cot(alpha_BC);
    cot_31 = cot(alpha_AB+alpha_BC);
   
    //calc coordinates of center triangle.
    xCBC = 0.5 * (xB + xC + (yB - yC) * cot_23);
    yCBC = 0.5 * (yB + yC + (xC - xB) * cot_23);
    xCAC = 0.5 * (xA + xC + (yA - yC) * cot_31);
    yCAC = 0.5 * (yA + yC + (xC - xA) * cot_31);

    //distance CAC to CBC (center triangle).
    dCAC_CBC = sqrt((xCAC-xCBC)*(xCAC-xCBC)+(yCAC-yCBC)*(yCAC-yCBC));

    deltatheta = asin(0.5*(dPAC_PBC/dCAC_CBC));
	deltatheta = (deltatheta < 0.0) ? -deltatheta : deltatheta; 
    sign = (xPAC-xPBC)*(yCAC-yCBC) - (xCAC-xCBC)*(yPAC-yPBC);
	if (sign < 0.0 ) deltatheta = -deltatheta ;   
    theta += deltatheta;

    mB = cot(theta - alpha_AB);
    mC = cot(theta - alpha_AB - alpha_BC);
  
    *xP = (mB * xB - mC * xC - yB + yC) / (mB - mC);
    *yP = mB * ((*xP) - xB) + yB; 
    return true;
  }else if ((alpha_BC == PI) || (alpha_BC == 0)){ 
    /* 2nd case: P is aligned on B & C.
                 cot(alpha_BC) is infinity */
    cot_12 = cot(alpha_AB);
    cot_31 = cot(alpha_AB+alpha_BC);
   
    //calc coordinates of center triangle.
    xCAB = 0.5 * (xA + xB + (yA - yB) * cot_12);
    yCAB = 0.5 * (yA + yB + (xB - xA) * cot_12);
    xCAC = 0.5 * (xA + xC + (yA - yC) * cot_31);
    yCAC = 0.5 * (yA + yC + (xC - xA) * cot_31);

    //distance CAB ot CAC (center triangle)
    dCAB_CAC = sqrt((xCAB-xCAC)*(xCAB-xCAC)+(yCAB-yCAC)*(yCAB-yCAC));

    deltatheta = asin(0.5*(dPAB_PAC/dCAB_CAC));
	deltatheta = (deltatheta < 0.0) ? -deltatheta : deltatheta; 
    sign = (xPAB-xPAC)*(yCAB-yCAC) - (xCAB-xCAC)*(yPAB-yPAC);
	if (sign < 0.0 ) deltatheta = -deltatheta ;   
    theta += deltatheta;

    mA = cot(theta);
    mB = cot(theta - alpha_AB);
  
    *xP = (mA * xA - mB * xB - yA + yB) / (mA - mB);
    *yP = mA * ((*xP) - xA) + yA; 
    return true;
  }else if (((alpha_AB + alpha_BC) == PI) || ((alpha_AB + alpha_BC) == 0)){
    /* 3rd case: P is aligned on A & C. 
       cot(alpha_AB+alpha_BC) is infinity.*/
    cot_12 = cot(alpha_AB);
    cot_23 = cot(alpha_BC);
   
    //calc coordinates of center triangle.
    xCAB = 0.5 * (xA + xB + (yA - yB) * cot_12);
    yCAB = 0.5 * (yA + yB + (xB - xA) * cot_12);
    xCBC = 0.5 * (xB + xC + (yB - yC) * cot_23);
    yCBC = 0.5 * (yB + yC + (xC - xB) * cot_23);

    //distance CAB ot CBC (center triangle)
    dCAB_CBC = sqrt((xCAB-xCBC)*(xCAB-xCBC)+(yCAB-yCBC)*(yCAB-yCBC));

    deltatheta = asin(0.5*(dPAB_PBC/dCAB_CBC));
	deltatheta = (deltatheta < 0.0) ? -deltatheta : deltatheta; 
	sign = (xPBC - xPAB) * (yCBC - yCAB) - (xCBC - xCAB) * (yPBC - yPAB);
	if (sign < 0.0 ) deltatheta = -deltatheta;   
    theta += deltatheta;

    mA = cot(theta);
    mB = cot(theta - alpha_AB);
  
	*xP = (mA * xA - mB * xB - yA + yB) / (mA - mB);
	*yP = mA * ((*xP) - xA) + yA;   
    return true;
  }else {
    /* Normal case can be calculated by other methods as well.*/
    cot_12 = cot(alpha_AB);
    cot_23 = cot(alpha_BC);
    cot_31 = cot(alpha_AB+alpha_BC);
   
    //calc coordinates of center triangle.
    xCAB = 0.5 * (xA + xB + (yA - yB) * cot_12);
    yCAB = 0.5 * (yA + yB + (xB - xA) * cot_12);
    xCBC = 0.5 * (xB + xC + (yB - yC) * cot_23);
    yCBC = 0.5 * (yB + yC + (xC - xB) * cot_23);
    xCAC = 0.5 * (xA + xC + (yA - yC) * cot_31);
    yCAC = 0.5 * (yA + yC + (xC - xA) * cot_31);

	AC = ((xCAB - xCBC) * (yCBC - yCAC) - (xCBC - xCAC) * (yCAB - yCBC))/* / 2*/ ;
	AC = (AC < 0.0) ? -AC : AC;

    deltatheta = asin(0.5*sqrt(AP/AC));
	deltatheta = (deltatheta < 0.0) ? -deltatheta : deltatheta; 
	sign = (xPBC - xPAB) * (yCBC - yCAB) - (xCBC - xCAB) * (yPBC - yPAB);
	if (sign < 0.0 ) deltatheta = -deltatheta ;   
    theta += deltatheta;

    mA = cot(theta);
    mB = cot(theta - alpha_AB);
  
	*xP = (mA * xA - mB * xB - yA + yB) / (mA - mB);
	*yP = mA * ((*xP) - xA) + yA;  
    return true;
  }
}