Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotation issues with globe anchors that have names matching previously deleted globe anchors #493

Closed
r-veenstra opened this issue Oct 17, 2023 · 6 comments · Fixed by #496
Assignees

Comments

@r-veenstra
Copy link
Contributor

r-veenstra commented Oct 17, 2023

I'm programatically creating multiple globe anchors with child prims. I'm setting the latitude and longitude prim attributes and expecting the globe anchor to position itself on the globe and correctly align with the earths surface.

This works as expected on the first attempt, see image below

image

However, if I delete these prims and run my script again, the anchors position correctly but are rotated incorrectly

image

If I rename the prims in my script (eg. append a suffix) the new anchors work fine again. However, if I delete them and run the script again with the same name, it will fail again, so reusing names appears to be an issue.

Tested against the latest globe anchors branch including open-saved-anchors branch

To run my script, use USD Composer and go to window > script editor, paste in the script and hit run

from cesium.omniverse.bindings import acquire_cesium_omniverse_interface

locations = [
    {"name": "NewYork", "latitude": 40.7128, "longitude": -74.0060, "population": 8336817},
    {"name": "LosAngeles", "latitude": 34.0522, "longitude": -118.2437, "population": 39776830},
    {"name": "Chicago", "latitude": 41.8781, "longitude": -87.6298, "population": 2716000},
    {"name": "Houston", "latitude": 29.7604, "longitude": -95.3698, "population": 2320257},
    {"name": "Phoenix", "latitude": 33.4484, "longitude": -112.0740, "population": 1680992},
    {"name": "Philadelphia", "latitude": 39.9526, "longitude": -75.1652, "population": 1584064},
    {"name": "SanAntonio", "latitude": 29.4241, "longitude": -98.4936, "population": 1547253},
    {"name": "SanDiego", "latitude": 32.7157, "longitude": -117.1611, "population": 1423851},
    {"name": "Dallas", "latitude": 32.7767, "longitude": -96.7970, "population": 1343573},
    {"name": "SanJose", "latitude": 37.3541, "longitude": -121.9552, "population": 1030119},
]

ctx = omni.usd.get_context()
stage = ctx.get_stage()

cesium_omniverse_interface = acquire_cesium_omniverse_interface()

for location in locations:

    anchor_path = "/World/" + location["name"] + "_anchor"
    geom_path = anchor_path + "/" + location["name"]

    # Create the anchor prim
    omni.kit.commands.execute(
        "CreateMeshPrimWithDefaultXform", prim_type="Cylinder", prim_path=anchor_path
    )

    # Creat the actual prim geometry - keep object scaling separate from the globe anchor
    omni.kit.commands.execute(
        "CreateMeshPrimWithDefaultXform", prim_type="Cylinder", prim_path=geom_path
    )

    anchor_prim = stage.GetPrimAtPath(anchor_path)
    geom_prim = stage.GetPrimAtPath(geom_path)

    cesium_omniverse_interface.add_global_anchor_to_prim(str(anchor_path))

    anchor_prim.GetAttribute("cesium:anchor:geographicCoordinates").Set(
        (location["latitude"], location["longitude"], 0.0)
    )

    geom_prim = stage.GetPrimAtPath(geom_path)
    geom_prim.GetAttribute("xformOp:scale").Set(
        (50000.0, 1000000.0, 50000.0)
    )

@weegeekps
Copy link
Contributor

Oh, I think I get what is going on here. The Globe Anchors registry is based on path so if you change the paths, such as renaming, things will break. Let me try some things.

@weegeekps
Copy link
Contributor

@r-veenstra How are you deleting the prims?

@weegeekps
Copy link
Contributor

@r-veenstra Okay, so I don't think this is a bug. The issue is our old friend, "USD notification race conditions." If you try the below version of the script where I wait a frame before updating the latitude and location it works. The reason for this is how the notifications work. The create process also creates latitude and longitude update events, which causes a race when you immediately set the latitude and longitude.

In fact, on my machine they never got placed properly in the first case on the first run. Subsequent runs would work... most of the time. There was still a random element based on background usage.

I'm going to close this issue for now but feel free to reopen it if you think there's anything else at work here.

from asyncio import ensure_future
from cesium.omniverse.bindings import acquire_cesium_omniverse_interface

locations = [
    {"name": "NewYork", "latitude": 40.7128, "longitude": -74.0060, "population": 8336817},
    {"name": "LosAngeles", "latitude": 34.0522, "longitude": -118.2437, "population": 39776830},
    {"name": "Chicago", "latitude": 41.8781, "longitude": -87.6298, "population": 2716000},
    {"name": "Houston", "latitude": 29.7604, "longitude": -95.3698, "population": 2320257},
    {"name": "Phoenix", "latitude": 33.4484, "longitude": -112.0740, "population": 1680992},
    {"name": "Philadelphia", "latitude": 39.9526, "longitude": -75.1652, "population": 1584064},
    {"name": "SanAntonio", "latitude": 29.4241, "longitude": -98.4936, "population": 1547253},
    {"name": "SanDiego", "latitude": 32.7157, "longitude": -117.1611, "population": 1423851},
    {"name": "Dallas", "latitude": 32.7767, "longitude": -96.7970, "population": 1343573},
    {"name": "SanJose", "latitude": 37.3541, "longitude": -121.9552, "population": 1030119},
]

ctx = omni.usd.get_context()
stage = ctx.get_stage()

cesium_omniverse_interface = acquire_cesium_omniverse_interface()

async def main():
    for location in locations:

        anchor_path = "/World/" + location["name"] + "_anchor"
        geom_path = anchor_path + "/" + location["name"]

        # Create the anchor prim
        omni.kit.commands.execute(
            "CreateMeshPrimWithDefaultXform", prim_type="Cylinder", prim_path=anchor_path
        )

        # Creat the actual prim geometry - keep object scaling separate from the globe anchor
        omni.kit.commands.execute(
            "CreateMeshPrimWithDefaultXform", prim_type="Cylinder", prim_path=geom_path
        )

        anchor_prim = stage.GetPrimAtPath(anchor_path)
        geom_prim = stage.GetPrimAtPath(geom_path)

        cesium_omniverse_interface.add_global_anchor_to_prim(str(anchor_path))

        for i in range(0, 1):
            await omni.kit.app.get_app().next_update_async()

        anchor_prim.GetAttribute("cesium:anchor:geographicCoordinates").Set(
            (location["latitude"], location["longitude"], 0.0)
        )

        geom_prim = stage.GetPrimAtPath(geom_path)
        geom_prim.GetAttribute("xformOp:scale").Set(
            (50000.0, 1000000.0, 50000.0)
        )

ensure_future(main())

@r-veenstra
Copy link
Contributor Author

@weegeekps I tried your script, however I'm still seeing the issue. See repro video below.

Screen.sharing.-.2023-10-18.7_00_27.AM.mp4

@r-veenstra r-veenstra reopened this Oct 17, 2023
@weegeekps
Copy link
Contributor

As discussed I think I might have an alternative that might be safer, and we're going to create the first bit of the Cesium Omniverse Python API. I'll be creating a function that allows you to pass in a path, latitude, longitude, and altitude to safely create an anchor on a Prim.

@r-veenstra
Copy link
Contributor Author

@weegeekps okay, rebuild everything and it looks like my issue was due to running latest code in the globe anchors branch vs actual main (my bad!)

I can confirm now that I 100% always get the race condition as you are experiencing too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants