Results 1 to 4 of 4

Thread: [RESOLVED] Linear regression

  1. #1

    Thread Starter
    Member
    Join Date
    Mar 2008
    Location
    East Kent, UK
    Posts
    34

    Resolved [RESOLVED] Linear regression

    Has anyone done any linear regression algorithms in VB.NET?

    I have a laser sensor which streams distance measurements via TCP. The minimum dimension is 700mm and the maximum is 3000mm. It takes measurements every 0.25degrees, from 55 degrees to 125 degrees - a total of 70 degrees => 280 measurements per scan. Sometimes the laser will not take a true reading, and will return 0mm.

    When the laser has performed its scan, I need to evaluate all the measurements to find two "edges" which are perpendicular to each other. Once I have found these lines and proved that they are perpendicular, I can calculate the X and Y offset, and rotation, of the two edges. This information will then be passed by serial to a robot to perform a pick-and-place operation.

    The point where the two "edges" meet will always (in theory) be the closest point to the laser centre.

    Here's a totally stripped down version - the sample set of measurements is in the next post. A screenshot (with lines removed) is also attached.

    The problem I have is that I am not sure how to do the linear regression lines without including some of the obviously invalid points. This is where I could do with some help (which would be GREATLY appreciated )


    Code:
    Option Explicit On
    Option Strict On
    
    Imports System.Drawing.Drawing2D
    
    Public Class Form1
    
        Structure MEASUREDVALUE
            Public Distance As Integer
            Public X As Integer
            Public Y As Integer
        End Structure
    
        Public MeasuredPoints(280) As MEASUREDVALUE
    
        Private iSmallestMeasurementFromLeft As Integer = Integer.MaxValue
        Private iSmallestMeasurementScanNumberLeft As Integer = 0
    
        Private iSmallestMeasurementFromRight As Integer = Integer.MaxValue
        Private iSmallestMeasurementScanNumberRight As Integer = 0
    
        Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
            Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
            Me.SetStyle(ControlStyles.UserPaint, True)
            Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    
            Me.WindowState = FormWindowState.Maximized
    
            For i As Integer = 1 To 280
                MeasuredPoints(i).Distance = 0
                MeasuredPoints(i).X = 0
                MeasuredPoints(i).Y = 0
            Next
    
            SetupSampleData()
    
        End Sub
    
        Private Sub SetupSampleData()
             'see next post
        End Sub
    
        Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
            With e.Graphics
                Dim mYFlip As Matrix = New Matrix(1, 0, 0, -1, 0, 0)
    
                .Transform = mYFlip
    
                .TranslateTransform(CSng(Me.ClientRectangle.Width / 2), 0 - (Me.ClientRectangle.Height - 100))
                .ScaleTransform(0.2, 0.2)
    
                .DrawEllipse(Pens.Black, -25, -25, 50, 50)
    
                .DrawLine(Pens.Black, CSng(0 + (700 * Math.Cos(DTR(90 + 35)))), CSng(0 + (700 * Math.Sin(DTR(90 + 35)))), CSng(0 + (3000 * Math.Cos(DTR(90 + 35)))), CSng(0 + (3000 * Math.Sin(DTR(90 + 35)))))
                .DrawLine(Pens.Black, CSng(0 - (700 * Math.Cos(DTR(90 + 35)))), CSng(0 + (700 * Math.Sin(DTR(90 + 35)))), CSng(0 - (3000 * Math.Cos(DTR(90 + 35)))), CSng(0 + (3000 * Math.Sin(DTR(90 + 35)))))
    
                .DrawArc(Pens.Black, 0 - 3000S, 0 - 3000S, 3000S * 2, 3000S * 2, 90 - 35, 70)
                .DrawArc(Pens.Black, 0 - 700S, 0 - 700S, 700S * 2, 700S * 2, 90 - 35, 70)
    
                Dim Angle As Single = 0
                For i As Integer = 1 To UBound(MeasuredPoints)
                    Angle = CSng((140 - i) * 0.25)
                    If MeasuredPoints(i).Distance >= 700 AndAlso MeasuredPoints(i).Distance <= 3000 Then
                        .DrawLine(Pens.Black, CSng(0 - (MeasuredPoints(i).Distance * Math.Cos(DTR(90 - Angle)))), CSng(0 + (MeasuredPoints(i).Distance * Math.Sin(DTR(90 - Angle)))), CSng(0 - (MeasuredPoints(i).Distance * Math.Cos(DTR(90 - Angle)))), CSng(0 + (MeasuredPoints(i).Distance * Math.Sin(DTR(90 - Angle)))) + 1)
                    End If
    
                    'if you want to identify a measured point, add a NumericUpDown control
                    'and set its minimum value to 1 and its maximum value to 280
                    If i = NumericUpDown1.Value Then
                        If MeasuredPoints(i).Distance >= 700 AndAlso MeasuredPoints(i).Distance <= 3000 Then
                            .DrawLine(Pens.Red, 0, 0, CSng(0 - (MeasuredPoints(i).Distance * Math.Cos(DTR(90 - Angle)))), CSng(0 + (MeasuredPoints(i).Distance * Math.Sin(DTR(90 - Angle)))) + 1)
                        Else
                            .DrawLine(Pens.Red, 0, 0, CSng(0 - (3000 * Math.Cos(DTR(90 - Angle)))), CSng(0 + (3000 * Math.Sin(DTR(90 - Angle)))) + 1)
                        End If
                    End If
                Next
    
                'find the smallest measurement working from left to right
                iSmallestMeasurementFromLeft = Integer.MaxValue
                iSmallestMeasurementScanNumberLeft = 0
                For i As Integer = 1 To 280
                    If MeasuredPoints(i).Distance >= 700 AndAlso MeasuredPoints(i).Distance <= 3000 AndAlso MeasuredPoints(i).Distance < iSmallestMeasurementFromLeft Then
                        iSmallestMeasurementFromLeft = MeasuredPoints(i).Distance
                        iSmallestMeasurementScanNumberLeft = i
                    End If
                Next
                Angle = CSng((140 - iSmallestMeasurementScanNumberLeft) * 0.25)
                .DrawLine(Pens.Green, 0, 0, CSng(0 - (MeasuredPoints(iSmallestMeasurementScanNumberLeft).Distance * Math.Cos(DTR(90 - Angle)))), CSng(0 + (MeasuredPoints(iSmallestMeasurementScanNumberLeft).Distance * Math.Sin(DTR(90 - Angle)))) + 1)
    
                'TODO: calculate the linear regression line to the left
    
    
                'find the smallest measurement working from left to right
                iSmallestMeasurementFromRight = Integer.MaxValue
                iSmallestMeasurementScanNumberRight = 0
                For i As Integer = 280 To 1 Step -1
                    If MeasuredPoints(i).Distance >= 700 AndAlso MeasuredPoints(i).Distance <= 3000 AndAlso MeasuredPoints(i).Distance < iSmallestMeasurementFromRight Then
                        iSmallestMeasurementFromRight = MeasuredPoints(i).Distance
                        iSmallestMeasurementScanNumberRight = i
                    End If
                Next
                Angle = CSng((140 - iSmallestMeasurementScanNumberRight) * 0.25)
                .DrawLine(Pens.Green, 0, 0, CSng(0 - (MeasuredPoints(iSmallestMeasurementScanNumberRight).Distance * Math.Cos(DTR(90 - Angle)))), CSng(0 + (MeasuredPoints(iSmallestMeasurementScanNumberRight).Distance * Math.Sin(DTR(90 - Angle)))) + 1)
    
                'TODO: calculate the linear regression line to the right
    
            End With
        End Sub
    
        Private Function DTR(ByVal whatDegrees As Double) As Double
            DTR = (whatDegrees * Math.PI) / 180
        End Function
    
        Private Function RTD(ByVal whatRadians As Double) As Double
            RTD = (whatRadians * 180) / Math.PI
        End Function
    
        Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
            Me.Invalidate()
        End Sub
    
    End Class
    Attached Images Attached Images  

  2. #2

    Thread Starter
    Member
    Join Date
    Mar 2008
    Location
    East Kent, UK
    Posts
    34

    Re: Linear regression

    Code:
            MeasuredPoints(2).Distance = 1855
            MeasuredPoints(3).Distance = 1855
            MeasuredPoints(4).Distance = 1855
            MeasuredPoints(5).Distance = 1917
            MeasuredPoints(6).Distance = 1912
            MeasuredPoints(7).Distance = 1904
            MeasuredPoints(8).Distance = 1899
            MeasuredPoints(9).Distance = 1894
            MeasuredPoints(10).Distance = 1889
            MeasuredPoints(11).Distance = 1884
            MeasuredPoints(12).Distance = 1880
            MeasuredPoints(13).Distance = 1875
            MeasuredPoints(14).Distance = 1870
            MeasuredPoints(15).Distance = 1867
            MeasuredPoints(16).Distance = 1863
            MeasuredPoints(17).Distance = 1860
            MeasuredPoints(18).Distance = 1861
            MeasuredPoints(19).Distance = 1868
            MeasuredPoints(20).Distance = 1882
            MeasuredPoints(21).Distance = 1899
            MeasuredPoints(22).Distance = 1911
            MeasuredPoints(23).Distance = 1855
            MeasuredPoints(24).Distance = 1855
            MeasuredPoints(25).Distance = 1855
            MeasuredPoints(26).Distance = 1855
            MeasuredPoints(27).Distance = 1959
            MeasuredPoints(28).Distance = 1975
            MeasuredPoints(29).Distance = 1995
    
            MeasuredPoints(37).Distance = 1955
            MeasuredPoints(38).Distance = 1912
            MeasuredPoints(39).Distance = 1904
            MeasuredPoints(40).Distance = 1903
            MeasuredPoints(41).Distance = 1905
            MeasuredPoints(42).Distance = 1903
            MeasuredPoints(43).Distance = 1901
            MeasuredPoints(44).Distance = 1898
            MeasuredPoints(45).Distance = 1891
            MeasuredPoints(46).Distance = 1884
            MeasuredPoints(47).Distance = 1880
            MeasuredPoints(48).Distance = 1880
            MeasuredPoints(49).Distance = 1881
            MeasuredPoints(50).Distance = 1882
            MeasuredPoints(51).Distance = 1879
            MeasuredPoints(52).Distance = 1868
            MeasuredPoints(53).Distance = 1866
            MeasuredPoints(54).Distance = 1867
            MeasuredPoints(55).Distance = 1867
            MeasuredPoints(56).Distance = 1863
            MeasuredPoints(57).Distance = 1859
            MeasuredPoints(58).Distance = 1853
            MeasuredPoints(59).Distance = 1841
            MeasuredPoints(60).Distance = 1803
            MeasuredPoints(61).Distance = 1599
            MeasuredPoints(62).Distance = 1512
            MeasuredPoints(63).Distance = 1355
            MeasuredPoints(64).Distance = 1350
            MeasuredPoints(65).Distance = 1346
            MeasuredPoints(66).Distance = 1345
            MeasuredPoints(67).Distance = 1343
            MeasuredPoints(68).Distance = 1344
            MeasuredPoints(69).Distance = 1344
            MeasuredPoints(70).Distance = 1349
            MeasuredPoints(71).Distance = 1355
            MeasuredPoints(72).Distance = 1370
            MeasuredPoints(73).Distance = 1378
            MeasuredPoints(74).Distance = 1378
            MeasuredPoints(75).Distance = 1374
            MeasuredPoints(76).Distance = 1365
            MeasuredPoints(77).Distance = 1358
            MeasuredPoints(78).Distance = 1350
            MeasuredPoints(79).Distance = 1347
            MeasuredPoints(80).Distance = 1340
            MeasuredPoints(81).Distance = 1335
            MeasuredPoints(82).Distance = 1326
            MeasuredPoints(83).Distance = 1322
            MeasuredPoints(84).Distance = 1316
            MeasuredPoints(85).Distance = 1313
            MeasuredPoints(86).Distance = 1306
            MeasuredPoints(87).Distance = 1299
            MeasuredPoints(88).Distance = 1294
            MeasuredPoints(89).Distance = 1288
            MeasuredPoints(90).Distance = 1283
            MeasuredPoints(91).Distance = 1278
            MeasuredPoints(92).Distance = 1274
            MeasuredPoints(93).Distance = 1267
            MeasuredPoints(94).Distance = 1262
            MeasuredPoints(95).Distance = 1257
            MeasuredPoints(96).Distance = 1249
            MeasuredPoints(97).Distance = 1245
            MeasuredPoints(98).Distance = 1242
            MeasuredPoints(99).Distance = 1238
            MeasuredPoints(100).Distance = 1233
            MeasuredPoints(101).Distance = 1229
            MeasuredPoints(102).Distance = 1223
            MeasuredPoints(103).Distance = 1219
            MeasuredPoints(104).Distance = 1213
            MeasuredPoints(105).Distance = 1209
            MeasuredPoints(106).Distance = 1205
            MeasuredPoints(107).Distance = 1198
            MeasuredPoints(108).Distance = 1196
            MeasuredPoints(109).Distance = 1193
            MeasuredPoints(110).Distance = 1189
            MeasuredPoints(111).Distance = 1185
            MeasuredPoints(112).Distance = 1181
            MeasuredPoints(113).Distance = 1177
            MeasuredPoints(114).Distance = 1173
            MeasuredPoints(115).Distance = 1167
            MeasuredPoints(116).Distance = 1165
            MeasuredPoints(117).Distance = 1161
            MeasuredPoints(118).Distance = 1157
            MeasuredPoints(119).Distance = 1153
            MeasuredPoints(120).Distance = 1148
            MeasuredPoints(121).Distance = 1145
            MeasuredPoints(122).Distance = 1141
            MeasuredPoints(123).Distance = 1139
            MeasuredPoints(124).Distance = 1135
            MeasuredPoints(125).Distance = 1132
            MeasuredPoints(126).Distance = 1126
            MeasuredPoints(127).Distance = 1124
            MeasuredPoints(128).Distance = 1124
            MeasuredPoints(129).Distance = 1126
            MeasuredPoints(130).Distance = 1132
            MeasuredPoints(131).Distance = 1139
            MeasuredPoints(132).Distance = 1148
            MeasuredPoints(133).Distance = 1156
            MeasuredPoints(134).Distance = 1164
            MeasuredPoints(135).Distance = 1172
            MeasuredPoints(136).Distance = 1181
            MeasuredPoints(137).Distance = 1192
            MeasuredPoints(138).Distance = 1197
            MeasuredPoints(139).Distance = 1208
            MeasuredPoints(140).Distance = 1215
            MeasuredPoints(141).Distance = 1225
            MeasuredPoints(142).Distance = 1234
            MeasuredPoints(143).Distance = 1244
            MeasuredPoints(144).Distance = 1253
            MeasuredPoints(145).Distance = 1263
            MeasuredPoints(146).Distance = 1273
            MeasuredPoints(147).Distance = 1281
            MeasuredPoints(148).Distance = 1294
            MeasuredPoints(149).Distance = 1301
            MeasuredPoints(150).Distance = 1311
            MeasuredPoints(151).Distance = 1319
            MeasuredPoints(152).Distance = 1334
            MeasuredPoints(153).Distance = 1342
            MeasuredPoints(154).Distance = 1356
            MeasuredPoints(155).Distance = 1368
            MeasuredPoints(156).Distance = 1378
            MeasuredPoints(157).Distance = 1390
            MeasuredPoints(158).Distance = 1403
            MeasuredPoints(159).Distance = 1343
            MeasuredPoints(160).Distance = 1343
            MeasuredPoints(161).Distance = 1343
            MeasuredPoints(162).Distance = 1452
            MeasuredPoints(163).Distance = 1470
            MeasuredPoints(164).Distance = 1514
            MeasuredPoints(165).Distance = 1516
            MeasuredPoints(166).Distance = 1516
            MeasuredPoints(167).Distance = 1514
    
            MeasuredPoints(171).Distance = 1509
            MeasuredPoints(172).Distance = 1509
    
            MeasuredPoints(189).Distance = 1353
            MeasuredPoints(190).Distance = 1354
            MeasuredPoints(191).Distance = 1354
            MeasuredPoints(192).Distance = 1351
            MeasuredPoints(193).Distance = 1353
            MeasuredPoints(194).Distance = 1353
            MeasuredPoints(195).Distance = 1358
            MeasuredPoints(196).Distance = 1358

  3. #3
    Only Slightly Obsessive jemidiah's Avatar
    Join Date
    Apr 2002
    Posts
    2,431

    Re: [RESOLVED] Linear regression

    Since this is apparently resolved, I'm curious how you picked out the two linear sections of the graph above. It seems like that would be difficult, though I guess with the condition you gave, that the meeting point would be the closest one to the sensor, you could start do linear regressions starting at that point and including more and more points to the left of that closest point and perform regressions until you add an outlier point (perhaps one that increases your R^2 error), at which time you know you've added all of the data points connected to the left surface. You'd do the same for the right side afterwards.
    The time you enjoy wasting is not wasted time.
    Bertrand Russell

    <- Remember to rate posts you find helpful.

  4. #4

    Thread Starter
    Member
    Join Date
    Mar 2008
    Location
    East Kent, UK
    Posts
    34

    Re: [RESOLVED] Linear regression

    I didnt actually start from the nearest point - I found a better way. Here's how I achieved it.

    Starting from the left point, I kept adding points to a list and performing a linear regression on the list, until the sigma value went into (and then out of) acceptable limits. I then took the last point away from the list, so I had a list of points that made one acceptable linear regression line.

    I repeated this until all points had been evaluated. This gave me one, two or several acceptable regression lines.

    Lines with a small number of points were then eliminated as 'random lines' (say, for example, the grouping on the left). As the lines are meant to be perpendicular, I then evaluated the slopes of all the lines to find the best matched pair.

    It's working fine, and tracking the edges perfectly

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width