Results 1 to 4 of 4

Thread: [RESOLVED] Linear regression

Threaded View

  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  

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