Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
4f70181
update secrets
JapjotS Mar 31, 2026
f87f0ca
GNSS positioning updates (WGS84, transform to the easting/northing sp…
JapjotS Mar 31, 2026
a39fce9
Initialise estimation (from GNSS, WiFi, others, no user selection)
JapjotS Mar 31, 2026
98f48bc
Auto-Initialisation (No User Input) bug fixes
JapjotS Mar 31, 2026
ec76f5d
Add particle filter prediction & sensor hooks
JapjotS Mar 31, 2026
52152b2
Add GNSS update and init for particle filter
JapjotS Mar 31, 2026
d962f25
Integrate particle filter + WiFi/GNSS fusion
JapjotS Mar 31, 2026
cd54598
map_data_guards
luoyue192-create Mar 31, 2026
fa4e257
Merge pull request #1 from JapjotS/particle_filter
JapjotS Mar 31, 2026
b788aed
Merge remote-tracking branch 'origin/particle_filter' into map_data_g…
luoyue192-create Mar 31, 2026
37d4a8d
map_matching_1
luoyue192-create Mar 31, 2026
00436a5
Data_Display_wifi_not_working
gayathrikjp Apr 1, 2026
c9b3236
map_matching_2
luoyue192-create Apr 1, 2026
7168af2
basic as
JapjotS Apr 1, 2026
ddfcd0e
Merge pull request #2 from JapjotS/bringing_color_back
JapjotS Apr 1, 2026
17d5575
Add wall collisions & floor-change handling
JapjotS Apr 1, 2026
d4608ef
Update TrajectoryMapFragment.java
JapjotS Apr 1, 2026
1666c28
Merge pull request #3 from JapjotS/Data_display_3.3
JapjotS Apr 1, 2026
9978e23
changed
JapjotS Apr 1, 2026
1ceb219
Merge pull request #4 from JapjotS/map_data_guards
JapjotS Apr 1, 2026
c82e8db
Improve indoor visuals, floorplan fetch & autofloor
JapjotS Apr 1, 2026
421e1db
Set GNSS/WiFi/PDR switches on and load walls
JapjotS Apr 1, 2026
41c9898
41m
JapjotS Apr 1, 2026
6b06f7b
Updated UI
gayathrikjp Apr 1, 2026
353ec1d
Update with settings icon
gayathrikjp Apr 1, 2026
007d885
Improve WiFi handling, particle reset, PDR init
JapjotS Apr 1, 2026
71bf2db
Merge branch 'main' into Updated_UI
JapjotS Apr 1, 2026
77e0d1a
Merge pull request #5 from JapjotS/Updated_UI
JapjotS Apr 1, 2026
6b05109
fixed the map
JapjotS Apr 1, 2026
ce6f4a8
Always render API vector floor shapes
JapjotS Apr 1, 2026
7836814
Update IndoorMapManager.java
JapjotS Apr 1, 2026
738128b
Improve indoor tracking visuals & particle logic
JapjotS Apr 1, 2026
32b6f6d
Avoid consuming first point if map not ready
JapjotS Apr 1, 2026
132013c
Improve floor detection and particle filter robustness
JapjotS Apr 1, 2026
eb7d52a
Refine sensor fusion WiFi/GNSS handling and logs
JapjotS Apr 1, 2026
205acb7
Align walls to PF origin; sync PDR; reject GNSS
JapjotS Apr 1, 2026
b537a1c
Align walls to PF origin; sync PDR; reject GNSS
JapjotS Apr 1, 2026
e1871f7
Improve PDR, wall handling, and autofloor logic
JapjotS Apr 1, 2026
5874e72
Update TrajectoryMapFragment.java
JapjotS Apr 1, 2026
2fb2fec
fixed initial draggable marker
Davidhqm Apr 1, 2026
4474475
Refine PDR, auto-floor, heading and wall checks
JapjotS Apr 1, 2026
f86d385
Merge branch 'good_branch' of https://github.com/JapjotS/ewireless_cw…
JapjotS Apr 1, 2026
5c60756
comment fixes
JapjotS Apr 1, 2026
d2cc951
changes
JapjotS Apr 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@
.cxx
local.properties
/.idea/
.claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,18 @@ public ReplayPoint(LatLng pdrLocation, LatLng gnssLocation, float orientation, f
}
}

/** Represents an IMU (Inertial Measurement Unit) data record used for orientation calculations. */
private static class ImuRecord {
public long relativeTimestamp;
public float accX, accY, accZ; // Accelerometer values
public float gyrX, gyrY, gyrZ; // Gyroscope values
public float rotationVectorX, rotationVectorY, rotationVectorZ, rotationVectorW; // Rotation quaternion
}

/** Represents a Pedestrian Dead Reckoning (PDR) data record storing position shifts over time. */
private static class PdrRecord {
public long relativeTimestamp;
public float x, y; // Position relative to the starting point
}

/** Represents a GNSS (Global Navigation Satellite System) data record with latitude/longitude. */
private static class GnssRecord {
public long relativeTimestamp;
public double latitude, longitude; // GNSS coordinates
Expand Down Expand Up @@ -199,7 +196,6 @@ public static List<ReplayPoint> parseTrajectoryData(String filePath, Context con

return result;
}
/** Parses IMU data from JSON. */
private static List<ImuRecord> parseImuData(JsonArray imuArray) {
List<ImuRecord> imuList = new ArrayList<>();
if (imuArray == null) return imuList;
Expand All @@ -209,7 +205,7 @@ private static List<ImuRecord> parseImuData(JsonArray imuArray) {
imuList.add(record);
}
return imuList;
}/** Parses PDR data from JSON. */
}
private static List<PdrRecord> parsePdrData(JsonArray pdrArray) {
List<PdrRecord> pdrList = new ArrayList<>();
if (pdrArray == null) return pdrList;
Expand All @@ -219,7 +215,7 @@ private static List<PdrRecord> parsePdrData(JsonArray pdrArray) {
pdrList.add(record);
}
return pdrList;
}/** Parses GNSS data from JSON. */
}
private static List<GnssRecord> parseGnssData(JsonArray gnssArray) {
List<GnssRecord> gnssList = new ArrayList<>();
if (gnssArray == null) return gnssList;
Expand All @@ -229,17 +225,17 @@ private static List<GnssRecord> parseGnssData(JsonArray gnssArray) {
gnssList.add(record);
}
return gnssList;
}/** Finds the closest IMU record to the given timestamp. */
}
private static ImuRecord findClosestImuRecord(List<ImuRecord> imuList, long targetTimestamp) {
return imuList.stream().min(Comparator.comparingLong(imu -> Math.abs(imu.relativeTimestamp - targetTimestamp)))
.orElse(null);

}/** Finds the closest GNSS record to the given timestamp. */
}
private static GnssRecord findClosestGnssRecord(List<GnssRecord> gnssList, long targetTimestamp) {
return gnssList.stream().min(Comparator.comparingLong(gnss -> Math.abs(gnss.relativeTimestamp - targetTimestamp)))
.orElse(null);

}/** Computes the orientation from a rotation vector. */
}
private static float computeOrientationFromRotationVector(float rx, float ry, float rz, float rw, Context context) {
float[] rotationVector = new float[]{rx, ry, rz, rw};
float[] rotationMatrix = new float[9];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,29 @@ public static class MapShapeFeature {
private final String indoorType;
private final String geometryType;
private final List<List<LatLng>> parts;
private final String strokeColor; // hex string from API, e.g. "#666666", or null
private final String fillColor; // hex string from API, or null
private final float strokeWidth; // 0 means not specified by API

/**
* Constructs a MapShapeFeature.
*
* @param indoorType feature type from properties (e.g. "wall", "room")
* @param geometryType GeoJSON geometry type (e.g. "MultiLineString", "MultiPolygon")
* @param parts coordinate lists: each inner list is a line or polygon ring
* @param strokeColor stroke colour from API properties, or null
* @param fillColor fill colour from API properties, or null
* @param strokeWidth stroke width from API properties, 0 if not set
*/
public MapShapeFeature(String indoorType, String geometryType,
List<List<LatLng>> parts) {
List<List<LatLng>> parts,
String strokeColor, String fillColor, float strokeWidth) {
this.indoorType = indoorType;
this.geometryType = geometryType;
this.parts = parts;
this.strokeColor = strokeColor;
this.fillColor = fillColor;
this.strokeWidth = strokeWidth;
}

/** Returns the indoor feature type (e.g. "wall", "room"). */
Expand All @@ -74,6 +84,15 @@ public MapShapeFeature(String indoorType, String geometryType,

/** Returns coordinate parts: lines for MultiLineString, rings for MultiPolygon. */
public List<List<LatLng>> getParts() { return parts; }

/** Returns the API-provided stroke colour string, or null if not set. */
public String getStrokeColor() { return strokeColor; }

/** Returns the API-provided fill colour string, or null if not set. */
public String getFillColor() { return fillColor; }

/** Returns the API-provided stroke width, or 0 if not set. */
public float getStrokeWidth() { return strokeWidth; }
}

/**
Expand Down Expand Up @@ -444,7 +463,27 @@ private MapShapeFeature parseMapShapeFeature(JSONObject feature) {
return null;
}

return new MapShapeFeature(indoorType, geoType, parts);
// Parse visual properties — try the same field names the private repo uses
String strokeColor = null;
String fillColor = null;
float strokeWidth = 0f;
if (properties != null) {
// stroke colour: stroke_color → line_color → color
if (properties.has("stroke_color")) strokeColor = properties.optString("stroke_color", null);
else if (properties.has("line_color")) strokeColor = properties.optString("line_color", null);
else if (properties.has("color")) strokeColor = properties.optString("color", null);

// fill colour: fill_color → fill
if (properties.has("fill_color")) fillColor = properties.optString("fill_color", null);
else if (properties.has("fill")) fillColor = properties.optString("fill", null);

// stroke width: stroke_width → line_width → width
if (properties.has("stroke_width")) strokeWidth = (float) properties.optDouble("stroke_width", 0.0);
else if (properties.has("line_width")) strokeWidth = (float) properties.optDouble("line_width", 0.0);
else if (properties.has("width")) strokeWidth = (float) properties.optDouble("width", 0.0);
}

return new MapShapeFeature(indoorType, geoType, parts, strokeColor, fillColor, strokeWidth);
} catch (JSONException e) {
Log.e(TAG, "Failed to parse map_shapes feature", e);
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,36 +13,20 @@
import com.openpositioning.PositionMe.R;
import com.openpositioning.PositionMe.sensors.SensorFusion;
import com.openpositioning.PositionMe.service.SensorCollectionService;
import com.openpositioning.PositionMe.presentation.fragment.StartLocationFragment;
import com.openpositioning.PositionMe.presentation.fragment.RecordingFragment;
import com.openpositioning.PositionMe.presentation.fragment.CorrectionFragment;


/**
* The RecordingActivity manages the recording flow of the application, guiding the user through a sequence
* of screens for location selection, recording, and correction before finalizing the process.
* <p>
* This activity follows a structured workflow:
* <ol>
* <li>StartLocationFragment - Allows users to select their starting location.</li>
* <li>RecordingFragment - Handles the recording process and contains a TrajectoryMapFragment.</li>
* <li>CorrectionFragment - Enables users to review and correct recorded data before completion.</li>
* </ol>
* <p>
* The activity ensures that the screen remains on during the recording process to prevent interruptions.
* It also provides fragment transactions for seamless navigation between different stages of the workflow.
* <p>
* This class is referenced in various fragments such as HomeFragment, StartLocationFragment,
* RecordingFragment, and CorrectionFragment to control navigation through the recording flow.
* Manages the recording flow: name dialog → live recording → correction.
* The start location is anchored automatically from the first GPS fix;
* no manual pin-drop screen is required.
*
* @see StartLocationFragment The first step in the recording process where users select their starting location.
* @see RecordingFragment Handles data recording and map visualization.
* @see CorrectionFragment Allows users to review and make corrections before finalizing the process.
* @see com.openpositioning.PositionMe.R.layout#activity_recording The associated layout for this activity.
* @see RecordingFragment live map and sensor data during walking.
* @see CorrectionFragment review/correct before upload.
*
* @author ShuGu
*/

public class RecordingActivity extends AppCompatActivity {

@Override
Expand All @@ -51,32 +35,18 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.activity_recording);

if (savedInstanceState == null) {
// Show trajectory name input dialog before proceeding to start location
showTrajectoryNameDialog();
}

// Keep screen on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

/**
* {@inheritDoc}
* Re-registers sensor listeners so that IMU, step detection, barometer and other
* movement sensors remain active while this activity is in the foreground.
* Without this, sensors are unregistered when {@link MainActivity#onPause()} fires
* during the activity transition, leaving PDR and elevation updates dead.
*/
@Override
protected void onResume() {
super.onResume();
SensorFusion.getInstance().resumeListening();
}

/**
* {@inheritDoc}
* Stops sensor listeners when this activity is no longer visible, unless
* the foreground {@link SensorCollectionService} is running (recording in progress).
*/
@Override
protected void onPause() {
super.onPause();
Expand All @@ -86,9 +56,8 @@ protected void onPause() {
}

/**
* Shows an AlertDialog prompting the user to enter a trajectory name.
* The name is stored in SensorFusion as trajectory_id and later written to the protobuf.
* After input, proceeds to StartLocationFragment.
* Prompts for a trajectory name, then starts recording immediately.
* The GPS anchor is written automatically on the first location fix.
*/
private void showTrajectoryNameDialog() {
EditText input = new EditText(this);
Expand All @@ -101,56 +70,40 @@ private void showTrajectoryNameDialog() {
.setMessage("Enter a name for this recording session:")
.setView(input)
.setCancelable(false)
.setPositiveButton("Save", (dialog, which) -> {
.setPositiveButton("Start", (dialog, which) -> {
String name = input.getText().toString().trim();
if (name.isEmpty()) {
// Default name based on timestamp
name = "traj_" + System.currentTimeMillis();
}
SensorFusion.getInstance().setTrajectoryId(name);
showStartLocationScreen();
if (name.isEmpty()) name = "traj_" + System.currentTimeMillis();
SensorFusion sf = SensorFusion.getInstance();
sf.setTrajectoryId(name);
sf.startRecording();
showRecordingScreen();
})
.setNegativeButton("Skip", (dialog, which) -> {
// Use default name
SensorFusion.getInstance().setTrajectoryId(
"traj_" + System.currentTimeMillis());
showStartLocationScreen();
SensorFusion sf = SensorFusion.getInstance();
sf.setTrajectoryId("traj_" + System.currentTimeMillis());
sf.startRecording();
showRecordingScreen();
})
.show();
}

/**
* Show the StartLocationFragment (beginning of flow).
*/
public void showStartLocationScreen() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.mainFragmentContainer, new StartLocationFragment());
ft.commit();
}

/**
* Show the RecordingFragment, which contains the TrajectoryMapFragment internally.
*/
/** Show the RecordingFragment (live map + sensors). */
public void showRecordingScreen() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.mainFragmentContainer, new RecordingFragment());
ft.addToBackStack(null);
ft.commit();
}

/**
* Show the CorrectionFragment after the user stops recording.
*/
/** Show the CorrectionFragment after the user stops recording. */
public void showCorrectionScreen() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.mainFragmentContainer, new CorrectionFragment());
ft.addToBackStack(null);
ft.commit();
}

/**
* Finish the Activity (or do any final steps) once corrections are done.
*/
/** Finish the Activity once corrections are done. */
public void finishFlow() {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
finish();
Expand Down
Loading