{"id":46520625,"url":"https://github.com/stestagg/noisytracking","last_synced_at":"2026-03-06T19:28:04.695Z","repository":{"id":335192667,"uuid":"1144268361","full_name":"stestagg/noisytracking","owner":"stestagg","description":"Bayesian tracking","archived":false,"fork":false,"pushed_at":"2026-01-29T01:24:22.000Z","size":83,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-01-29T15:29:40.522Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stestagg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-28T13:55:54.000Z","updated_at":"2026-01-29T01:24:26.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/stestagg/noisytracking","commit_stats":null,"previous_names":["stestagg/noisytracking"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/stestagg/noisytracking","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stestagg%2Fnoisytracking","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stestagg%2Fnoisytracking/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stestagg%2Fnoisytracking/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stestagg%2Fnoisytracking/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stestagg","download_url":"https://codeload.github.com/stestagg/noisytracking/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stestagg%2Fnoisytracking/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30193485,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T19:07:06.838Z","status":"ssl_error","status_checked_at":"2026-03-06T18:57:34.882Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-03-06T19:28:03.249Z","updated_at":"2026-03-06T19:28:04.625Z","avatar_url":"https://github.com/stestagg.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# noisytracking\n\nA Python library for noisytracking\n\n##  Conceptual sketch:\n\n```\nimport noisytracking as nt\n# Some things in nt:\n# Dynamics \"order\" (single source of truth)\n# CONSTANT_VALUE        = 0  # ORDER0: value persists\n# CONSTANT_RATE         = 1  # ORDER1: first derivative persists\n# CONSTANT_CURVATURE    = 2  # ORDER2: second derivative persists\n\n# Friendly aliases (pure ergonomics; map to the same integers)\n# STEADY_STATE          = CONSTANT_RATE\n\n# Optional motion-flavoured aliases (still just ints)\n# CONSTANT_POSITION     = CONSTANT_VALUE\n# CONSTANT_VELOCITY     = CONSTANT_RATE\n# CONSTANT_ACCELERATION = CONSTANT_CURVATURE\n\n\n# class OutlierHandling(Enum):\n#     NONE        = \"none\"         # plain residual (Gaussian)\n#     GATED       = \"gated\"        # reject/ignore large residuals\n#     HEAVY_TAILED= \"heavy_tailed\" # down-weight outliers smoothly\n#     MIXTURE     = \"mixture\"      # explicit inlier/outlier mixture\n\n\nmodel = nt.setup(time_field=\"timestamp\", time_units=\"sample\", sample_time_policy='sequential_buckets')\n\nuser_position = model.predicted(\n    name=\"position\",\n    kind=nt.Motion(\n        units={\"length\": \"m\", \"angle\": \"rad\"},\n        expected_change=nt.CONSTANT_VELOCITY,\n    ),\n)\n\ngps = model.sensor(\"gps\", kind=nt.Position(units=\"m\"))\ngps_heading = model.sensor(\"gps_heading\", kind=nt.Rotation(units=\"rad\"), sensor_data_format=lambda x: {'yaw': x})\ntracking = model.sensor(\n    \"tracking\",\n    kind=nt.Pose(units={\"length\": \"m/sample\", \"angle\": \"rad/sample\"}, ),\n    sensor_data_format=pose_from_matrix,\n)\n\n# Absolute anchors (observation relationships)\nuser_position.position.is_estimated_from(gps)\nuser_position.rotation.yaw.is_estimated_from(gps_heading.yaw)\n\n# Learned calibration/bias for tracking (exposes .bias and .applied)\ntracking_bias = model.learned(\n    name=\"tracking_bias\",\n    kind=nt.LearnedBias(\n        target=tracking,\n        expected_change=nt.CONSTANT_VALUE,\n        change_model=nt.ChangeModel.DRIFT_WITH_JUMPS\n    ),\n)\ntracking_bias.bias.position.is_estimated_from(gps)\ntracking_bias.bias.rotation.yaw.is_estimated_from(gps_heading.yaw)\n\n# Integrate the corrected tracking stream into the predicted position\nuser_position.is_estimated_from(tracking_bias.applied, rel=nt.Rel.delta, outlier_handling=nt.OutlierHandling.HEAVY_TAILED)\n\npredictor = model.build()\n\n...\n\npredictor.update_from_sensor(timestamp=1234567890.0, gps={'x': 52.12343456, 'y': 2.012345, 'z': 0.0})\npredictor.update_from_sensor(timestamp=1234567890.0, gps_heading=0.5, tracking=np.array([[...]]))\n\nprint(predictor.predict(timestamp=1234567892).position.position)\n```\n\n## Architecture Notes\n\nUnits module will come later (nt.units.*), but there are some concepts:\n - units dimension (one of length/time/angle/temperature etc..)\n - units are parsed into a structure that models them so we know that m/s is \u003cmeters +1\u003e, \u003cseconds -1\u003e, and we can work out relationships by integration/differentiation between them.\n - every unit belongs to a dimension, and all units can convert values to any other unit in the same  dimension.\n - units can be: defined directly during build, OR defined by dimension (i.e. {'legnth': 'cm'}) or left as default values.  Compound parameters pass units to children, but this raises errors on incompatibility (i.e. Pose(units='cm') errors because Pose.rotation has the 'angle' dimension. but Pose(units={'length': 'cm'})) results in Pose.rotation units being default, while Pose.position units = cm.\n\nevery 'variable' in the model builder should be a Parameter.  A parameter is one of:\n1. ScalarParameter (floating point variable that will be built into a prior/variable/estimated in the predictor) - has a unit (defaults to sensible default ('m'/'m/s' etc.))\n2. 'CompoundParameter', has one or more sub-parameters each of which are named and are scalar or compound parameters.\n\nParameters have a child_parameters property that returns a dict of child parameters for any parameter (scalar returns empty dict)\n\nTwo CompoundParameters can directly interact if the units and names of their parameters match.  (i.e. nt.Motion.position and nt.Position, but not nt.Motion.rotation and nt.Position) and the interaction is either handled directly, or broadcast to the matching child parameters depending on the operation.\n\n\n## Installation\n\n```bash\nuv pip install -e .\n```\n\n## Development\n\nInstall with development dependencies:\n\n```bash\nuv pip install -e \".[dev]\"\n```\n\n## Testing\n\nRun tests with pytest:\n\n```bash\npytest\n```\n\\","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstestagg%2Fnoisytracking","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstestagg%2Fnoisytracking","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstestagg%2Fnoisytracking/lists"}