Hello, i am working on this sample app in order to make and indoor position based on wifi fingerprint map.
this is the code:
but i dont can have updated value of RSSI when i start wifi scan. It work even when the phone stay static in the room for a period.
Can someone suggest me the solution ? If exist ?
this is the code:
code:
Sub Activity_Create(FirstTime As Boolean)
Activity.LoadLayout("Layout")
Activity.Title="BleRescuePosition"
CC.Initialize("CC")
Activity.AddMenuItem("Carica una Mappa","menu_loadmap")
Activity.AddMenuItem("Atttiva/Disattiva posiziona iBeacon","menu_ibeacon_position")
Activity.AddMenuItem("Localizzami","menu_locate")
Activity.AddMenuItem("Salva mappa referenziata","menu_savemap_geo")
mymap.Width=100%x
mymap.Height=70%y
beacons_table.Initialize(Me, "Table", 6)
beacons_table.AddToActivity(Activity, 0, mymap.Height, 100%x, 30%y)
beacons_table.SetHeader(Array As String("SISID","RSSI", "X", "Y","RIF","COL"))
beacons_table.SetColumnsWidths(Array As Int(56%x,11%x,11%x,11%x,11%x,0%x))
beacons_table.RowHeight=110
wifi.Initialize("wifi")
wifi_scanned_list.Initialize
currentData.Initialize
trainingData.Initialize
Dim rp As RuntimePermissions
Dim p As Phone
Dim AndroidVersion As Int = p.SdkVersion
If AndroidVersion > 22 Then
Dim permOK As Int = 0
rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
Wait For Activity_PermissionResult (Permission As String, ResultP1 As Boolean)
If ResultP1 Then permOK = permOK + 1
rp.CheckAndRequest(rp.PERMISSION_ACCESS_COARSE_LOCATION)
Wait For Activity_PermissionResult (Permission As String, ResultP2 As Boolean)
If ResultP2 Then permOK = permOK + 1
If permOK < 2 Then
Log("Permissions failed")
Else
Log("permissions OK")
End If
End If
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub wifi_WifiEnabled(IsEnabled As Boolean)
If IsEnabled Then
wifi.GetNewReadingWifi
Else
ToastMessageShow("Abilita il Wifi!", True)
End If
End Sub
Sub menu_loadmap_Click
CC.Show("image/*", "Choose image")
End Sub
Sub menu_ibeacon_position_Click
iBeaconPosition=Not(iBeaconPosition)
Log(iBeaconPosition)
If iBeaconPosition=True Then
Activity.Title="Posiziona iBeacon"
Else
Activity.Title="BleRescuePosition"
End If
End Sub
Sub menu_savemap_geo_Click
beacons_table.SaveTableToCSV(File.DirInternal,"mappa.csv")
Dim bmp As Bitmap=mymap.Image
Dim Out As OutputStream
Out = File.OpenOutput(File.DirInternal, "mappa.png", False)
bmp.WriteToStream(Out, 100, "PNG")
Out.Close
End Sub
Sub menu_locate_Click
currentData.Clear
trainingData.Clear
If File.Exists(File.DirInternal,"mappa.png") And File.Exists(File.DirInternal,"mappa.csv") Then
mymap.Image=LoadBitmap(File.DirInternal,"mappa.png")
Dim bmp As Bitmap=mymap.Image
mymap.Image=bmp
beacons_table.LoadTableFromCSV(File.DirInternal,"mappa.csv",True)
beacons_table.SetColumnsWidths(Array As Int(56%x,11%x,11%x,11%x,11%x,0%x))
beacons_table.RowHeight=110
Log("map exist")
Dim ap_list As List=File.ReadList(File.DirInternal,"mappa.csv")
If ap_list.Size>0 Then
Log(ap_list)
For i=1 To ap_list.Size-1
Dim parts() As String
parts = Regex.Split(",",ap_list.Get(i))
If IsNumber(parts(1)) Then
trainingData.Add(CreateWiFiRecord(parts(1).As(Int),parts(0),parts(2).As(Int),parts(3).As(Int)))
End If
Next
Log(trainingData)
knn = 3 ' Adjust the parameter based on your needs
ProBar.mBase.Visible=True
ProBar.Show
wifi.StartWifi
'Wait For wifi_Scan
Sleep(10000)
ProBar.mBase.Visible=False
ProBar.Hide
If wifi_scanned_list.Size> 0 Then
For i=0 To wifi_scanned_list.Size-1
Dim reading As ABWifiReading = wifi_scanned_list.Get(i)
currentData.Add(CreateWiFiRecord(reading.Level,reading.SSID,-1,-1)) ' Sample current WiFi data with -1 for X and Y
Next
Dim predictedCoordinates As List = KNNPredict(trainingData, currentData)
' Display the predicted coordinates or perform further actions
Activity.Title="Coordinates: X=" & predictedCoordinates.Get(0) & ", Y=" & predictedCoordinates.Get(1)
mymap.CircleColor=Colors.Black
mymap.CircleWidth=1
mymap.CircleXPixels=predictedCoordinates.Get(0)*mymap.Scale
mymap.CircleYPixels=predictedCoordinates.Get(1)*mymap.Scale
mymap.EnableCircleScale=True
mymap.EnableCircle=True
mymap.ResetScaleAndCenter
wifi.StopWifi
End If
End If
End If
End Sub
Sub CC_Result (Success As Boolean, Dir As String, FileName As String)
If Success Then
mymap.Image=LoadBitmap(Dir,FileName)
Dim bmp As Bitmap=mymap.Image
mymap.Image=bmp
Else
ToastMessageShow("No image selected", True)
End If
End Sub
Private Sub mymap_Click 'The user has tapped on the view. Use ClickImage or ClickView for the coordinates.
If iBeaconPosition=True Then
Log("qui")
CircleColor=GenerateEnoughColor
Dim x As Double =mymap.ClickImageX
Dim y As Double=mymap.ClickImageY
mymap.CircleColor=CircleColor
mymap.CircleXPixels=mymap.ClickImageX
mymap.CircleYPixels=mymap.ClickImageY
mymap.EnableCircleScale=True
mymap.EnableCircle=True
mymap.ResetScaleAndCenter
Msgbox2Async("Confermi il posizionamento di un iBeacon a queste coordinate: [" & NumberFormat(mymap.ClickImageX,0,0) & "," & NumberFormat(mymap.ClickImageY,0,0) & "] ?", "Posizionamento iBeacon", "Si", "", "No", Null, False)
Wait For Msgbox_Result (Result As Int)
If Result = DialogResponse.POSITIVE Then
ProBar.mBase.Visible=True
ProBar.Show
wifi.StartWifi
Sleep(10000)
ProBar.mBase.Visible=False
ProBar.Hide
If wifi_scanned_list.size>0 Then
For i=0 To wifi_scanned_list.size-1
Dim reading As ABWifiReading = wifi_scanned_list.Get(i)
beacons_table.AddRow(Array As String(reading.SSID,reading.Level,NumberFormat(x,0,0),NumberFormat(y,0,0)," ",CircleColor))
Next
Dim bmp As Bitmap=mymap.Image
mymap.Image=bmp
mymap.EnableCircle=False
mymap.ResetScaleAndCenter
wifi.StopWifi
End If
Else
mymap.EnableCircle=False
mymap.ResetScaleAndCenter
End If
End If
End Sub
Private Sub mymap_LongClick 'The user has long pressed the view. Use ClickImage or ClickView for the coordinates.
End Sub
Sub wifi_FoundReadings(readings As List)
Dim i As Int
Dim s As String
For i = 0 To readings.Size - 1
Dim reading As ABWifiReading = readings.Get(i)
Log("---------------------------------")
'Log("BSSID: " & reading.BSSID)
Log("Level: " & reading.Level)
'Log("IsConnected: " & reading.IsConnected)
'Log("Frequency: " & reading.Frequency)
'Log("IsBestSignal: " & reading.IsBestSignal)
Log("SSID: " & reading.SSID)
'Log("Capabilities: " & reading.Capabilities)
s = s & "---------------------------------" & CRLF
s = s & "BSSID: " & reading.BSSID & CRLF
s = s & "Level: " & reading.Level & CRLF
s = s & "IsConnected: " & reading.IsConnected & CRLF
s = s & "Frequency: " & reading.Frequency & CRLF
s = s & "IsBestSignal: " & reading.IsBestSignal & CRLF
s = s & "SSID: " & reading.SSID & CRLF
s = s & "Capabilities: " & reading.Capabilities & CRLF
Next
If readings.Size>0 Then
wifi_scanned_list=readings
wifi.StopWifi
Else
wifi.GetNewReadingWifi
End If
End Sub
Sub CreateWiFiRecord(RSSI As Int, SSID As String, X As Double, Y As Double) As WiFiRecord
' Helper function to create a WiFiRecord
Dim wifiRecord As WiFiRecord
wifiRecord.RSSI = RSSI
wifiRecord.SSID = SSID
wifiRecord.X = X
wifiRecord.Y = Y
Return wifiRecord
End Sub
Sub KNNPredict(Data As List, inputData As List) As List
' Function to predict coordinates (X, Y) using KNN algorithm
' Check if the trainingData and inputData lists are not empty
If Data.Size = 0 Or inputData=Null Then
Log("Error: Empty trainingData or inputData")
Return
End If
' Create lists to store distances and their corresponding indices
Dim distances As List
distances.Initialize
Dim distanceIndices As List
distanceIndices.Initialize
' Calculate distances between inputData and trainingData
Dim i As Int
For i = 0 To Data.Size - 1
Dim distance As Double = EuclideanDistance(inputData, Data.Get(i))
distances.Add(distance)
distanceIndices.Add(i) ' Keep track of the original index
Next
' Sort distances and their corresponding indices in ascending order
SortDistances(distances, distanceIndices)
' Get the k-nearest neighbors
Dim neighbors As List
neighbors.Initialize
Dim maxIndex As Int = Min(knn, distances.Size) - 1
For i = 0 To maxIndex
' Get the index of the nearest neighbor in trainingData
Dim index As Int = distanceIndices.Get(i)
' Access the WiFiRecord at the corresponding index in trainingData
Dim trainingPoint As WiFiRecord = Data.Get(index)
neighbors.Add(Array(trainingPoint.X, trainingPoint.Y))
Next
' Perform the average for coordinate prediction
Dim predictedCoordinates As List = Average(neighbors)
Return predictedCoordinates
End Sub
Sub SortDistances(distances As List, indices As List)
' Function to sort distances and their corresponding indices in ascending order
For i = 0 To distances.Size - 2
For j = i + 1 To distances.Size - 1
If distances.Get(i) > distances.Get(j) Then
' Swap distances
Dim tempDistance As Double = distances.Get(i)
distances.Set(i, distances.Get(j))
distances.Set(j, tempDistance)
' Swap corresponding indices
Dim tempIndex As Int = indices.Get(i)
indices.Set(i, indices.Get(j))
indices.Set(j, tempIndex)
End If
Next
Next
End Sub
Sub EuclideanDistance(data1 As List, data2 As WiFiRecord) As Double
' Function to calculate Euclidean distance between two WiFiRecords
Dim sum As Double = 0
For i = 0 To data1.Size - 1
Dim inputRecord As WiFiRecord = data1.Get(i)
Dim diff As Double = inputRecord.RSSI - data2.RSSI
sum = sum + Power(diff, 2)
Next
Return Sqrt(sum)
End Sub
Sub Average(coordinatesList As List) As List
' Function to calculate the average of a list of coordinates
If coordinatesList.Size = 0 Then Return Null
Dim sumX As Double = 0
Dim sumY As Double = 0
For i = 0 To coordinatesList.Size - 1
Dim coordinates() As Object = coordinatesList.Get(i)
sumX = sumX + coordinates(0)
sumY = sumY + coordinates(1)
Next
Dim averageX As Double = sumX / coordinatesList.Size
Dim averageY As Double = sumY / coordinatesList.Size
Return Array(averageX, averageY)
End Sub
Sub GenerateEnoughColor As Int
Dim R,G,B As Int
R = Rnd( 0, 256)
G= Rnd( 0, 256)
B = Rnd( 0, 256)
Return Colors.RGB(R,G,B)
End Sub
but i dont can have updated value of RSSI when i start wifi scan. It work even when the phone stay static in the room for a period.
Can someone suggest me the solution ? If exist ?