Issue with Merging Rooms - RoomPlan - Seeking Guidance

Hello fellow developers,

When attempting to merge single rooms into one model, the resulting floorplan I got appears to have rooms stacked on top of each other.

I am using a single ARSession for all the scans, to my understanding, the world coordinate system remains consistent during a continuous ARSession. I can't figure out why the rooms are overlapping or positioned vertically on top of each other in the generated floorplan. I am uncertain whether this issue stems from my own code implementation.

I did the following modification to the sample code

Initiated an ARSession in RoomCaptureViewController

private var arWorldTrackingConfig: ARWorldTrackingConfiguration = ARWorldTrackingConfiguration()
private var arSession: ARSession = ARSession()

Pass ARSession to roomCaptureView

private func setupRoomCaptureView() {
    arSession.run(arWorldTrackingConfig)
    roomCaptureView = RoomCaptureView(frame: view.bounds, arSession: arSession)
    roomCaptureView.captureSession.delegate = self
    roomCaptureView.delegate = self
        
    view.insertSubview(roomCaptureView, at: 0)
}

Pause the ARSession after completion of scanning one room

private func saveSession() {
    isScanning = false
    roomCaptureView?.captureSession.stop(pauseARSession: false)
        
    setCompleteNavBar()
}
@IBAction func saveScanning(_ sender: UIBarButtonItem) {
    if isScanning { saveSession() } else { cancelScanning(sender) }
    self.exportButton?.isEnabled = false
    self.activityIndicator?.startAnimating()
}

Any experiences or insights are greatly appreciated.

Accepted Reply

This problem is solved.

In the previous implementation, cancelScanning() is called when isScanning is false

@IBAction func saveScanning(_ sender: UIBarButtonItem) {
    if isScanning { saveSession() } else { cancelScanning(sender) }
    self.exportButton?.isEnabled = false
    self.activityIndicator?.startAnimating()
}

The implementation of cancelScanning() dismiss the navigationController which cause the problem of initiating a new instance of the RoomCaptureViewController class when starting the next scanning session

@IBAction func cancelScanning(_ sender: UIBarButtonItem) {
    navigationController?.dismiss(animated: true)
}

Solution:

Just call startSession() to start the next capture session with the same ARSession.

@IBAction func saveScanning(_ sender: UIBarButtonItem) {
    if isScanning { saveSession() } else { startSession() }
    self.exportButton?.isEnabled = false
    self.activityIndicator?.startAnimating()
}
  • I tried your method, but it seems that the problem is not solved, the coordinate system of the two scans is still independent,What else can I do?Looking forward to your reply.

Add a Comment

Replies

This problem is solved.

In the previous implementation, cancelScanning() is called when isScanning is false

@IBAction func saveScanning(_ sender: UIBarButtonItem) {
    if isScanning { saveSession() } else { cancelScanning(sender) }
    self.exportButton?.isEnabled = false
    self.activityIndicator?.startAnimating()
}

The implementation of cancelScanning() dismiss the navigationController which cause the problem of initiating a new instance of the RoomCaptureViewController class when starting the next scanning session

@IBAction func cancelScanning(_ sender: UIBarButtonItem) {
    navigationController?.dismiss(animated: true)
}

Solution:

Just call startSession() to start the next capture session with the same ARSession.

@IBAction func saveScanning(_ sender: UIBarButtonItem) {
    if isScanning { saveSession() } else { startSession() }
    self.exportButton?.isEnabled = false
    self.activityIndicator?.startAnimating()
}
  • I tried your method, but it seems that the problem is not solved, the coordinate system of the two scans is still independent,What else can I do?Looking forward to your reply.

Add a Comment

i am also trying to implement it, but when i add arSession.run(arWorldTrackingConfig) , roomCaptureView = RoomCaptureView(frame: view.bounds, arSession: arSession) then the screen goes black. it's good if you share the code that you made.

Hello ThangNguyen_BZ, Could you be more specific about the issue you are getting?

To use a custom ARSession, my modification to the sample code are in the first post.

yes, im load worldMap form appdata,

        do {
            let data = try Data(contentsOf: fileURL)
            if let worldMap = try NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: data) {
                arWorldTrackingConfig.initialWorldMap = worldMap
                arSession.run(arWorldTrackingConfig)
                if #available(iOS 17.0, *) {
                    roomCaptureView = RoomCaptureView(frame: view.bounds, arSession: arSession)
                }
                else{
                    roomCaptureView = RoomCaptureView(frame: view.bounds)
                }

and use roomCaptureView?.captureSession.arSession.getCurrentWorldMap to save wordMap with let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true) try data.write(to: fileURL) but it's not working very well, sometimes I can't scan(black screen), and I can't merge data with previous room

Hello ThangNguyen_BZ,

There are two approaches for multiple room scans. The approach I was using in this post is continuous scan, and you are experiencing problems with relocalization. To get more targeted help and increase the chances of finding a solution, it's a good idea to create a separate post dedicated to the relocalization and scanning issues you're facing. This way, other developers who have encountered similar problems can chime in and offer their insights.

Here are some suggestions from me to consider:

  1. You said sometimes you can't scan. It'd be helpful to clarify if scanning works occasionally. If that's the case, please ensure you check if the worldMap is saved successfully after your first scan. You can do this by downloading the corresponding container to your app and right-clicking to select "Show Package Contents." This way, you can inspect the saved worldMap data and verify if it's being persisted correctly.

  2. When you mentioned that you can't merge different scans, is there any error messages or specific error behavior you've encountered? Having additional information about the issue will aid in identifying the cause.

  3. Assuming the worldMap is saved and loaded successfully, you might want to try setting the configuration without initializing a new RoomCaptureView.

configuration.initialWorldMap = worldMap
roomCaptureView?.captureSession.arSession.run(configuration, options: [.resetTracking])