{"id":13703653,"url":"https://github.com/peci1/robot_body_filter","last_synced_at":"2026-02-05T08:06:31.355Z","repository":{"id":45049948,"uuid":"178760100","full_name":"peci1/robot_body_filter","owner":"peci1","description":"Filters the robot's body out of point clouds and laser scans.","archived":false,"fork":false,"pushed_at":"2024-07-29T14:33:56.000Z","size":604,"stargazers_count":84,"open_issues_count":5,"forks_count":22,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-11-13T10:38:02.897Z","etag":null,"topics":["filter","laser","pointcloud","ros","scan"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"tpet/robot_self_filter","license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/peci1.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.rst","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","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},"funding":{"github":["peci1"],"custom":["https://btc.com/1CQEGaeP8k6TftvJjEwo59iSktBefeVArc"]}},"created_at":"2019-04-01T00:54:30.000Z","updated_at":"2024-11-03T11:26:32.000Z","dependencies_parsed_at":"2024-11-13T10:41:44.863Z","dependency_job_id":null,"html_url":"https://github.com/peci1/robot_body_filter","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peci1%2Frobot_body_filter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peci1%2Frobot_body_filter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peci1%2Frobot_body_filter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/peci1%2Frobot_body_filter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/peci1","download_url":"https://codeload.github.com/peci1/robot_body_filter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252458428,"owners_count":21751036,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["filter","laser","pointcloud","ros","scan"],"created_at":"2024-08-02T21:00:58.376Z","updated_at":"2026-02-05T08:06:26.329Z","avatar_url":"https://github.com/peci1.png","language":"C++","funding_links":["https://github.com/sponsors/peci1","https://btc.com/1CQEGaeP8k6TftvJjEwo59iSktBefeVArc"],"categories":["Sensor Processing"],"sub_categories":["Lidar and Point Cloud Processing","Point Cloud Processing"],"readme":"# robot_body_filter\n\nFilters the robot's body out of point clouds and laser scans.\n\n## Tutorial\n\nCheck out the webinar recording where a lot of options for this filter are explained and demonstrated! https://www.youtube.com/watch?v=j0ljV0uZy3Q\n\n## Changes vs [PR2/robot_self_filter](https://github.com/PR2/robot_self_filter):\n- Now the package is a normal `filters::FilterBase` filter and not a standalone node.\n- Using both containment and ray-tracing tests. \n- Using all collision elements for each link instead of only the first one.\n- Enabling generic point type, removing PCL dependency and unnecessary params.\n- Using bodies.h and shapes.h from geometric_shapes.\n- As a by-product, the filter can compute robot's bounding box or sphere.\n\n## Build Status\n\n\n\n\nDevelopment versions:\n[![Github Actions](https://github.com/peci1/robot_body_filter/workflows/CI/badge.svg?branch=master)](https://github.com/peci1/robot_body_filter/actions?query=workflow%3ACI)\n[![Dev melodic](http://build.ros.org/job/Mdev__robot_body_filter__ubuntu_bionic_amd64/badge/icon?subject=melodic)](http://build.ros.org/job/Mdev__robot_body_filter__ubuntu_bionic_amd64)\n[![Dev noetic](http://build.ros.org/job/Ndev__robot_body_filter__ubuntu_focal_amd64/badge/icon?subject=noetic)](http://build.ros.org/job/Ndev__robot_body_filter__ubuntu_focal_amd64)\n\nRelease jobs Melodic\n[![Melodic version](https://img.shields.io/ros/v/melodic/robot_body_filter)](http://packages.ros.org/ros/ubuntu/pool/main/r/ros-melodic-robot-body-filter/):\n[![Bin melodic-amd64](https://build.ros.org/job/Mbin_uB64__robot_body_filter__ubuntu_bionic_amd64__binary/badge/icon?subject=bionic+amd64)](https://build.ros.org/job/Mbin_uB64__robot_body_filter__ubuntu_bionic_amd64__binary/)\n[![Bin melodic-arm64](https://build.ros.org/job/Mbin_ubv8_uBv8__robot_body_filter__ubuntu_bionic_arm64__binary/badge/icon?subject=bionic+arm64)](https://build.ros.org/job/Mbin_ubv8_uBv8__robot_body_filter__ubuntu_bionic_arm64__binary/)\n[![Bin melodic-armhf](https://build.ros.org/job/Mbin_ubhf_uBhf__robot_body_filter__ubuntu_bionic_armhf__binary/badge/icon?subject=bionic+armhf)](https://build.ros.org/job/Mbin_ubhf_uBhf__robot_body_filter__ubuntu_bionic_armhf__binary/)\n\nRelease jobs Noetic\n[![Noetic version](https://img.shields.io/ros/v/noetic/robot_body_filter)](http://packages.ros.org/ros/ubuntu/pool/main/r/ros-noetic-robot-body-filter/):\n[![Bin noetic focal-amd64](https://build.ros.org/job/Nbin_uF64__robot_body_filter__ubuntu_focal_amd64__binary/badge/icon?subject=focal+amd64)](https://build.ros.org/job/Nbin_uF64__robot_body_filter__ubuntu_focal_amd64__binary/)\n[![Bin noetic focal-arm64](https://build.ros.org/job/Nbin_ufv8_uFv8__robot_body_filter__ubuntu_focal_arm64__binary/badge/icon?subject=focal+arm64)](https://build.ros.org/job/Nbin_ufv8_uFv8__robot_body_filter__ubuntu_focal_arm64__binary/)\n[![Bin noetic focal-armhf](https://build.ros.org/job/Nbin_ufhf_uFhf__robot_body_filter__ubuntu_focal_armhf__binary/badge/icon?subject=focal+armhf)](https://build.ros.org/job/Nbin_ufhf_uFhf__robot_body_filter__ubuntu_focal_armhf__binary/)\n\n## Basic Operation\n\n### `filters::FilterBase` API\n\nThe basic workings of this filter are done via the [`filters::FilterBase` API](http://wiki.ros.org/filters) implemented for `sensor_msgs::LaserScan` and `sensor_msgs::PointCloud2` types. This means you can load this filter into a FilterChain along other filters as usual. Different from the standard filters, this one can also publish several interesting topics and subscribes to TF.\n\n### General overview\n\nThis filter reads robot model and the filter config, subscribes to TF, waits\nfor data (laserscans or point clouds) and then cleans them from various\nartifacts (this is called data filtering).\n\nIt can perform 3 kinds of data filters: **clip** the data based on the provided\nsensor limits (parameter `filter/do_clipping`), **remove points that are inside\nor on the surface** of the robot body (parameter `filter/do_contains_test`) and\n**remove points that are seen through a part of the robot body** (parameter\n`filter/do_shadow_test`). These kinds of tests are further referenced as \n\"clipping\", \"contains test\" and \"shadow test\".\n\nIf working with point clouds, the filter automatically recognizes whether it\nworks with organized or non-organized clouds. In organized clouds, it marks\nthe filtered-out points as `NaN`. In non-organized clouds, it removes the\nfiltered-out points. In laserscans, removal is not an option, so the\nfiltered-out points are marked with `NaN` (some guides suggest that\n`max_range + 1` should be used for marking invalid points, but this filter uses\n`NaN` as a safer option).\n\n#### Performance tips\nIn general, the filter will be computationally expensive (clipping is fast,\ncontains test is medium CPU intensive and shadow test is the most expensive\npart, because it basically performs raytracing). You can limit the required CPU\npower by limiting the filter only to parts that matter. E.g. if the robot has a\nlink that can never be seen by the sensor, put it in the list of ignored links.\nThe less links are processed, the better performance. If you're only interested\nin removing a few links, consider using the `only_links` parameter.\n\nTo speed up shadow filtering, you can set `filter/max_shadow_distance`, which\nlimits the number of points considered for shadow tests just to points close to\nthe sensor. Setting this to e.g. three times the diameter of the robot should\nremove all of the shadow points caused by refraction by a part of the robot body.\nBut you have to test this with real data.\n\nPerformance also strongly depends on representation of the robot model.\nThe filter reads `\u003ccollision\u003e` tags from the robot URDF. You can use boxes,\nspheres and cylinders (which are fast to process), or you can use **convex**\nmeshes (these are much worse performance-wise). If you pass a non-convex mesh,\nits convex hull will be used for the tests. Don't forget that each link\ncan have multiple `\u003ccollision\u003e` tags. If you do not have time to convert your\nmeshes to the basic shapes, try to at least reduce the number of triangles\nin your meshes. You can use your high-quality meshes in `\u003cvisual\u003e` tags. To simplify your model to primitive shapes, you can either manually edit the URDF, or you can utilize [ColliderGen](https://github.com/cole-bsmr/collidergen).\n\n#### Model inflation\n\nYou can utilize the builtin model inflation mechanism to slightly alter the\nsize of the model. You will probably want to add a bit \"margin\" to the contains\nand shadow tests so that points that are millimeters outside the robot body will\nanyways get removed. You can set a default scale and padding which are used for\nall collisions. Different inflation can be used for contains tests and for\nshadow tests. Inflation can also be specified differently for each link. Look\nat the `body_model/inflation/*` parameters for details.\n\nScaling means multiplying the shape dimensions by the given\nfactor (with its center staying in the same place). Padding means adding the\nspecified metric distance to each \"dimension\" of the shape. Padding a sphere\nby `p` just adds `p` to its radius; padding a cylinder adds `p` to its radius\nand `2p` to its length (you pad both the top and the bottom of the cylinder);\npadding a box adds `2p` to all its extents (again, you pad both of the opposing\nsides); padding a mesh pads each vertex of its convex hull by `p` along the\ndirection from the mesh center to the vertex (mesh center is the center\nspecified in the mesh file, e.g. DAE). Have a good look at the effects of mesh\npadding, as the results can be non-intuitive.\n\n#### Data acquisition modes\n\nThe filter supports data captured in two modes - all at once (e.g. RGBD cameras),\nor each point at a different time instant (mostly lidars). This is handled by\n`sensor/point_by_point` setting. Each mode supports both laser scans and point\ncloud input (although all-at-once laserscans aren't that common). Point-by-point\npointclouds are e.g. the output of 3D lidars like Ouster (where more points can\nhave the same timestamp, but not all). If you want to use the point-by-point\nmode with pointclouds, make sure they contain not only the usual `x`, `y` and\n`z` fields, but also a `float32` field `stamps` (with time difference from the\ntime in the header) and `float32` fields `vp_x`, `vp_y` and `vp_z` which contain\nthe viewpoint (position of the sensor in filtering frame) from which the robot\nsaw that point. \n\nWhen filtering in the point-by-point mode, the robot posture has to be updated\nseveral times during processing a single scan (to reflect the motion the robot\nhas performed during acquiring the scan). The frequency of these updates can\nalso have a significant impact on performance. Use parameter\n`filter/model_pose_update_interval` to set the interval for which the robot is\nconsidered stationary. The positions of the robot at the beginning and at the\nend of the scan are queried from TF. The intermediate positions are linearly\ninterpolated between these two positions.\n\n#### TF frames\n\nThe filter recognizes four logical TF frames (some of which may be the same\nphysical frames).\n\n**Fixed frame** is a frame that doesn't change within the duration of the\nprocessed scan. This means for all-at-once scans, this frame is not needed\nbecause the duration of the scan is zero. For point-by-point scans, it depends\non the particular scenario. In static installations (like manipulators with\nsensors not attached to them), it can be the sensor frame. For stationary robots\nwith the sensor attached to a movable part of their body, `base_link` will be a\ngood choice. For completely mobile robots, you will need an external frame, e.g.\n`odom` or `map` (beware of cyclic dependencies - if the map is built from the\nfiltered scans, you obviously cannot use `map` as the fixed frame for filtering\nthe scans...).\n\n**Sensor frame** is the frame in which the data were captured. Generally, it\nwould be whatever is in `header.frame_id` field of the processed messages. You\ncan use the filter for data from multiple sensors - in that case, you can leave\nthe sensor frame unfilled and each message will be processed in the frame it has\nin its header.\n\n**Filtering frame** is the frame in which the data filtering is done. For\npoint-by-point scans, it has to be a fixed frame (possibly different from the\nfixed frame set in `frames/fixed`). For pointcloud scans, it should be the\nsensor frame (if all data are coming from a single sensor), or any other frame.\nIt is also used as the frame in which all debugging outputs are published.\n\n**Output frame** can only be used with pointcloud scans, and allows to transform\nthe filtered pointcloud to a different frame before being published. It is just\na convenience which can save you launching a transformation nodelet. By default,\nfiltered pointclouds are output in the filtering frame.\n\n#### Bounding shapes\n\nAs a byproduct, the filter can also compute various bounding shapes of the robot\nmodel. There are actually four robot models - one for contains test, one\nfor shadow test, one for bounding sphere computation and one for bounding box\n(these models can differ by inflation and considered links).\nAll bounding shapes are published in the filtering frame. For point-by-point scans,\nthe bounding shapes correspond to the\ntime instant specified in the header of the processed scan. The computation of\nbounding shapes is off by default, but enabling it is cheap (performance-wise).\n\nThe **bounding sphere** is easy - the smallest sphere that contains the whole\ncollision model for bounding sphere computation (with the specified exclusions removed).\n\nThe **bounding box** is the smallest axis-aligned bounding box aligned to the\nfiltering frame. It is built from the model for bounding box computation.\n\nThe **local bounding box** is the smallest axis-aligned bounding box aligned to\nthe frame specified in `local_bounding_box/frame_id`. It is especially useful\nwith mobile robots when the desired frame is `base_link`. It is built from the model\nfor bounding box computation.\n\nThe **oriented bounding box** should be the smallest box containing the\ncollision model. However, its computation is very bad conditioned, so the\nresults can be very unsatisfactory. Currently, the oriented bounding box of each\nof the basic collision shapes is \"tight\", but merging the boxes is not optimal.\nA good algorithm would probably require costly and advanced iterative methods.\nThe current implementation uses FCL in the background and merges the boxes using\n`fcl::OBB::operator+=()` without any further optimizations. It is built from the\nmodel for bounding box computation.\n\nThe filter also supports publishing auxiliary pointclouds which \"cut out\" each\nof these bounding shapes. These are the input data converted to pointcloud in\nfiltering frame from which all points belonging to the bounding shape are\nremoved. Please note that the \"base\" used for cutting out is the input\npointcloud, not the filtered one.\n\n#### First setup/debugging\n\nThe filter offers plenty of debugging outputs to make sure it does exactly\nwhat you want it to do. All the options are described in the last part of\nthis page. Generally, you should look at the pointclouds visualizing which\npoints got filtered out and you should also check the robot models used for\nfiltering.\n\nAlso, have a look in the [examples] folder to get some inspiration.\n\n### Usage\n\nThis is a standard `filters::FilterBase\u003cT\u003e`-based filter which implements the\n`configure()` and `update(const T\u0026, T\u0026)` methods. This means it can be loaded\ne.g. as a part of a filter chain via the\n[`laser_filters`](https://github.com/ros-perception/laser_filters) package or\nthe relatively new [`sensor_filters`](https://github.com/ctu-vras/sensor_filters).\nThis means the input and output data are not supplied in the form of topics,\nbut they are instead passed to the `update()` method via the C++ API.\n\nThis filter is a bit unusual - it subscribes and publishes several topics.\nNormally, filters only operate via the `update()` method and are not expected\nto publish anything. This filter is different, it requires a working ROS node\nhandle, and can publish a lot of auxiliary or debug data.\n\n### Subscribed Topics\n\n- `/tf`, `/tf_static`\n\n    Transforms\n- `dynamic_robot_model_server/parameter_updates` (`dynamic_reconfigure/Config`)\n\n    Dynamic reconfigure topic on which updated robot model can be subscribed. \n    The model is read from a field defined by parameter \n    `body_model/dynamic_robot_description/field_name`.\n\n### Published Topics\n\n- `scan_point_cloud_no_bsphere` (`sensor_msgs/PointCloud2`)\n    \n    Point cloud with points inside body bounding sphere removed.\n    Turned on by `bounding_sphere/publish_cut_out_pointcloud` parameter.\n    Published in filtering frame.\n- `scan_point_cloud_no_bbox` (`sensor_msgs/PointCloud2`)\n\n    Point cloud with points inside filtering frame axis-aligned bounding box\n    removed. Turned on by `bounding_box/publish_cut_out_pointcloud` parameter.\n    Published in filtering frame.\n- `scan_point_cloud_no_oriented_bbox` (`sensor_msgs/PointCloud2`)\n\n    Point cloud with points inside oriented bounding box removed. Turned on by\n    `oriented_bounding_box/publish_cut_out_pointcloud` parameter.\n    Published in filtering frame. Please read the remarks above in the overview -\n    the results can be non-satisfying.\n- `scan_point_cloud_no_local_bbox` (`sensor_msgs/PointCloud2`)\n\n    Point cloud with points inside `local_bounding_box/frame_id` axis-aligned\n    bounding box removed. Turned on by\n    `local_bounding_box/publish_cut_out_pointcloud` parameter. Published in\n    filtering frame.\n- `robot_bounding_sphere` (`robot_body_filter/SphereStamped`) \n\n    Bounding sphere of the robot body. Turned on by \n    `bounding_sphere/compute` parameter. Published in filtering frame.\n- `robot_bounding_box` (`geometry_msgs/PolygonStamped`) \n\n    Axis-aligned bounding box of the robot body aligned to the filtering frame.\n    First point is the minimal point, second one is the maximal point. Turned on\n    by `bounding_box/compute` parameter. Published in filtering frame.\n- `robot_oriented_bounding_box` (`robot_body_filter/OrientedBoundingBoxStamped`)\n\n    Oriented bounding box of the robot body. Turned on by\n    `oriented_bounding_box/compute` parameter. Please read the remarks above\n    in the overview - the results can be non-satisfying. Published in filtering\n    frame.\n- `robot_local_bounding_box` (`geometry_msgs/PolygonStamped`) \n\n    Axis-aligned bounding box of the robot body aligned to frame\n    `local_bounding_box/frame_id`. First point is the minimal point, second one\n    is the maximal point. Turned on by `local_bounding_box/compute` parameter.\n    Published in frame `local_bounding_box/frame_id`.\n\n### Provided Services\n\n- `~reload_model` (`std_srvs/Trigger`)\n\n    Call this service to re-read the URDF model from parameter server.\n\n### Filter Parameters\n\nHave a look in the [examples](examples) folder to get inspiration for \nconfiguration of your filter. \n\n- `sensor/point_by_point` (`bool`, default: `false` for PointCloud2 version, \n   `true` for LaserScan)\n    \n    If true, suppose that every point in the scan was captured at a\n    different time instant. Otherwise, the scan is assumed to be taken at\n    once. If this is true, the processing pipeline expects the pointcloud\n    to have fields int32 index, float32 stamps, and float32 vp_x, vp_y\n    and vp_z viewpoint positions. If one of these fields is missing,\n    computeMask() throws runtime exception.\n- `frames/fixed` (`string`, default: `\"base_link\"`)\n\n    The fixed frame. Usually base_link for stationary robots (or sensor\n    frame if both robot and sensor are stationary). For mobile robots, it\n    can be e.g. odom or map. Only needed for point-by-point scans.\n- `frames/sensor` (`string`, default `\"\"`)\n\n    Frame of the sensor. If set to empty string, it will be read from\n    `header.frame_id` of each incoming message. In LaserScan version, if\n    nonempty, it has to match the `frame_id` of the incoming scans.\n    In PointCloud2 version, the data can come in a different frame from\n    `frames/sensor`.\n- `frames/filtering` (`string`, default: `frames/fixed`)\n\n    Frame in which the filter is applied. For point-by-point scans, it\n    has to be a fixed frame, otherwise, it can be the sensor frame or\n    any other frame. Setting to sensor frame will save some computations,\n    but this frame cannot be empty string, so sensor frame can only be\n    used if all data are coming from a single sensor and you know the scan\n    frame in advance.\n- `frames/output` (`string`, default: `frames/filtering`)\n\n    Frame into which output data are transformed. Only applicable in\n    PointCloud2 version.\n- `sensor/min_distance` (`float`, default: `0.0 m`)\n\n    The minimum distance of points from the laser to keep them.\n- `sensor/max_distance` (`float`, default: `0.0 m`)\n\n    The maximum distance of points from the laser to keep them. Set to zero\n    to disable this limit.\n- `filter/keep_clouds_organized` (`bool`, default `true`)\n\n    Whether to keep pointclouds organized (if they were). Organized cloud has \n    `height \u003e 1`.\n- `filter/model_pose_update_interval` (`float`, default `0.0 s`)\n\n    The interval between two consecutive model pose updates when processing a \n    pointByPointScan. If set to zero, the model will be updated for each point \n    separately (might be computationally exhaustive). If non-zero, it will only \n    update the model once in this interval, which makes the masking algorithm a \n    little bit less precise but more computationally affordable.\n- `filter/do_clipping` (`bool`, default `true`)\n\n    If `true`, the filter will mark points outside `sensor/(min|max)_distance` \n    as `CLIP`. If `false`, such points will be marked `OUTSIDE`.\n- `filter/do_contains_test` (`bool`, default `true`)\n\n    If `true`, the filter will mark points inside robot body \n    as `INSIDE`. If `false`, such points will be marked `OUTSIDE`.\n- `filter/do_shadow_test` (`bool`, default `true`)\n\n    If `true`, the filter will mark points shadowed by robot body \n    as `SHADOW`. If `false`, such points will be marked `OUTSIDE`.\n- `filter/max_shadow_distance` (`float`, default is the value of `sensor/max_distance`)\n\n    If greater than zero, specifies the maximum distance of a point from the sensor\n    frame within which the point can be considered for shadow testing. All further\n    points are classified as `OUTSIDE`. Setting this parameter to a low value may \n    greatly improve performance of the shadow filtering.\n- `body_model/inflation/scale` (`float`, default `1.0`)\n\n    A scale that is applied to the collision model for the purposes of\n    collision checking.\n- `body_model/inflation/padding` (`float`, default `0.0 m`)\n\n    Padding to be added to the collision model for the purposes of collision \n    checking.\n- `body_model/inflation/contains_test/scale` (`float`, default `body_model/inflation/scale`)\n\n    A scale that is applied to the collision model used for contains tests.\n- `body_model/inflation/contains_test/padding` (`float`, default `body_model/inflation/padding`)\n\n    Padding to be added to the collision model used for contains tests.\n- `body_model/inflation/shadow_test/scale` (`float`, default `body_model/inflation/scale`)\n\n    A scale that is applied to the collision model used for shadow tests.\n- `body_model/inflation/shadow_test/padding` (`float`, default `body_model/inflation/padding`)\n\n    Padding to be added to the collision model used for shadow tests.\n- `body_model/inflation/bounding_sphere/scale` (`float`, default `body_model/inflation/scale`)\n\n    A scale that is applied to the collision model used for bounding sphere computation.\n- `body_model/inflation/bounding_sphere/padding` (`float`, default `body_model/inflation/padding`)\n\n    Padding to be added to the collision model used for bounding sphere computation.\n- `body_model/inflation/bounding_box/scale` (`float`, default `body_model/inflation/scale`)\n\n    A scale that is applied to the collision model used for bounding box computation.\n- `body_model/inflation/bounding_box/padding` (`float`, default `body_model/inflation/padding`)\n\n    Padding to be added to the collision model used for bounding box computation.\n- `body_model/inflation/per_link/scale` (`dict[str:float]`, default `{}`)\n\n    A scale that is applied to the specified links for the purposes of\n    collision checking. Links not specified here will use the default scale\n    set in `body_model/inflation/contains_test/scale` or\n    `body_model/inflation/shadow_test/scale`. Keys are names, values are scale.\n    Names can be either names of links (`link`), names of collisions (\n    `*::my_collision`), a combination of link name and zero-based collision\n    index (`link::1`), or link name and collision name, e.g.\n    `link::my_collision`. Any such name can have suffix `::contains`, \n    `::shadow`, `::bounding_sphere` or `::bounding_box`, which will only change\n    the scale for contains or shadow tests or for bounding sphere or box computation.\n    If a collision is matched by multiple entries, they have priority\n    corresponding to the order they were introduced here (the entries do not\n    \"add up\", but replace each other).\n- `body_model/inflation/per_link/padding` (`dict[str:float]`, default `{}`)\n\n    Padding to be added to the specified links for the purposes of collision \n    checking. Links not specified here will use the default padding set in\n    `body_model/inflation/contains_test/padding` or\n    `body_model/inflation/shadow_test/padding`. Keys are names, values are\n    padding. Names can be either names of links (`link`), names of collisions (\n    `*::my_collision`), a combination of link name and zero-based collision\n    index (`link::1`), or link name and collision name, e.g.\n    `link::my_collision`. Any such name can have suffix `::contains`,\n    `::shadow`, `::bounding_sphere` or `::bounding_box`, which will only change\n    the padding for contains or shadow tests or for bounding sphere or box computation.\n    If a collision is matched by multiple entries, they have priority\n    corresponding to the order they were introduced here (the entries do not\n    \"add up\", but replace each other).\n    \n- `body_model/robot_description_param` (`string`, default: `\"robot_description\"`)\n\n    Name of the parameter where the robot model can be found.\n- `transforms/buffer_length` (`float`, default `60.0 s`)\n\n    Duration for which transforms will be stored in TF buffer.\n- `transforms/timeout/reachable` (`float`, default `0.1 s`)\n\n    How long to wait while getting reachable TF (i.e. transform which was \n    previously available). Please note that this timeout is computed not from\n    the lookup start time, but from the scan timestamp - this allows you to tell\n    how old scans you still want to process.\n- `transforms/timeout/unreachable` (`float`, default `0.2 s`)\n    \n    How long to wait while getting unreachable TF.\n- `transforms/require_all_reachable` (`bool`, default `false`)\n\n   If true, the filter won't publish anything until all transforms are reachable.\n- `ignored_links/bounding_sphere` (`list[string]`, default `[]`)\n\n    List of links to be ignored in bounding sphere computation. Can be either \n    names of links (`link`), names of collisions (`*::my_collision`), a\n    combination of link name and zero-based collision index (`link::1`), or link\n    name and collision name, e.g. `link::my_collision`.\n- `ignored_links/bounding_box` (`list[string]`, default `[]`)\n\n    List of links to be ignored in bounding box computation. Same naming rules \n    as above.\n- `ignored_links/contains_test` (`list[string]`, default `[]`)\n\n    List of links to be ignored when testing if a point is inside robot body. \n    Same naming rules as above.\n- `ignored_links/shadow_test` (`list[string]`, default `['laser']`)\n\n    List of links to be ignored when testing if a point is shadowed by robot \n    body. Same naming rules as above. It is essential that this list contains \n    the sensor link - otherwise all points would be shadowed by the sensor \n    itself. \n- `ignored_links/bounding_sphere` (`list[string]`, default `[]`)\n\n    List of links to be ignored when computing the bounding sphere.\n    Same naming rules as above.\n- `ignored_links/bounding_box` (`list[string]`, default `[]`)\n\n    List of links to be ignored when computing the bounding box.\n    Same naming rules as above.\n- `ignored_links/everywhere` (`list[string]`, default `[]`)\n\n    List of links to be completely ignored. Same naming rules as above.\n- `only_links` (`list[string]`, default `[]`)\n\n    If non-empty, only the specified links will be processed. The \n    above-mentioned `ignored_links/*` filters will still be applied.\n- `bounding_sphere/compute` (`bool`, default `false`)\n\n    Whether to compute and publish bounding sphere.\n- `bounding_box/compute` (`bool`, default `false`)\n \n    Whether to compute and publish axis-aligned bounding box aligned to\n    filtering frame.\n- `oriented_bounding_box/compute` (`bool`, default `false`)\n \n    Whether to compute and publish oriented bounding box (see the remarks in\n    the overview above; the result might be pretty bad).\n- `local_bounding_box/compute` (`bool`, default `false`)\n \n    Whether to compute and publish axis-aligned bounding box aligned to\n    frame `local_bounding_box/frame_id`.\n- `local_bounding_box/frame_id` (`str`, default: `frames/fixed`)\n \n    The frame to which local bounding box is aligned.\n- `bounding_sphere/publish_cut_out_pointcloud` (`bool`, default `false`)\n\n    Whether to compute and publish pointcloud from which points in the\n    bounding sphere are removed. Will be published on \n    `scan_point_cloud_no_bsphere`. Implies `bounding_sphere/compute`.\n    The \"base\" point cloud before cutting out are the input data,\n    not the filtered data.\n- `bounding_box/publish_cut_out_pointcloud` (`bool`, default `false`)\n\n    Whether to compute and publish pointcloud from which points in the\n    bounding box are removed. Will be published on `scan_point_cloud_no_bbox`.\n    Implies `bounding_box/compute`. The \"base\" point cloud before cutting out\n    are the input data, not the filtered data.\n- `oriented_bounding_box/publish_cut_out_pointcloud` (`bool`, default `false`)\n\n    Whether to compute and publish pointcloud from which points in the\n    oriented bounding box are removed. Will be published on\n    `scan_point_cloud_no_oriented_bbox`. Implies `oriented_bounding_box/compute`.\n    The \"base\" point cloud before cutting out are the input data, not the\n    filtered data.\n- `local_bounding_box/publish_cut_out_pointcloud` (`bool`, default `false`)\n\n    Whether to compute and publish pointcloud from which points in the local\n    bounding box are removed. Will be published on\n    `scan_point_cloud_no_local_bbox`. Implies `local_bounding_box/compute`. The\n    \"base\" point cloud before cutting out are the input data, not the filtered\n    data.\n- `body_model/dynamic_robot_description/field_name` (`string`, \n    default `robot_model`)\n\n    If robot model is published by dynamic reconfigure, this is the name of the \n    Config message field which holds the robot model.\n- `cloud/point_channels` (`list[string]`, default `[\"vp_\"]`)\n\n    List of channels of the incoming pointcloud that should be transformed as\n    positional data. The 3D positions channel given by fields `x`, `y` and `z`\n    is always transformed. This list contains prefixes of fields that form another\n    channel(s). E.g. to transform the channel given by fields `vp_x`, `vp_y` and\n    `vp_z`, add item `\"vp_\"` to the list. If a channel is not present in the cloud,\n    nothing happens. This parameter is only available in the `PointCloud2` version\n    of the filter.\n- `cloud/direction_channels` (`list[string]`, default `[\"normal_\"]`)\n\n    List of channels of the incoming pointcloud that should be transformed as\n    directional data. This list contains prefixes of fields that form channel(s).\n    E.g. to transform the channel given by fields `normal_x`, `normal_y` and\n    `normal_z`, add item `\"normal_\"` to the list. If a channel is not present in the cloud,\n    nothing happens. This parameter is only available in the `PointCloud2` version\n    of the filter.\n\n## Debug Operation\n\nThese options are there to help correctly set up and debug the filter operation and should be turned off in production environments since they can degrade performance of the filter.\n\n### Published Topics\n\n- `robot_bounding_sphere_marker` (`visualization_msgs/Marker`) \n\n    Marker of the bounding sphere of the robot body. Turned on by \n    `bounding_sphere/marker` parameter. Published in filtering frame.\n- `robot_bounding_box_marker` (`visualization_msgs/Marker`) \n\n    Marker of the bounding box of the robot body. Turned on by \n    `bounding_box/marker` parameter. Published in filtering frame.\n- `robot_oriented_bounding_box_marker` (`visualization_msgs/Marker`) \n\n    Marker of the oriented bounding box of the robot body. Turned on by \n    `oriented_bounding_box/marker` parameter. Published in filtering frame.\n- `robot_local_bounding_box_marker` (`visualization_msgs/Marker`) \n\n    Marker of the local bounding box of the robot body. Turned on by \n    `local bounding_box/marker` parameter. Published in frame\n    `local_bounding_box/frame_id`.\n- `robot_bounding_sphere_debug` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the bounding sphere for each collision element.\n    Turned on by `bounding_sphere/debug` parameter. Published in filtering frame.\n- `robot_bounding_box_debug` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the bounding box for each collision element.\n    Turned on by `bounding_box/debug` parameter. Published in filtering frame.\n- `robot_oriented_bounding_box_debug` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the oriented bounding box for each collision element.\n    Turned on by `oriented_bounding_box/debug` parameter. Published in filtering frame.\n- `robot_local_bounding_box_debug` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the local bounding box for each collision element.\n    Turned on by `local_bounding_box/debug` parameter. Published in frame\n    `local_bounding_box/frame_id`.\n- `robot_model_for_contains_test` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the exact robot model used for contains tests.\n    Turned on by `debug/marker/contains` parameter.\n- `robot_model_for_shadow_test` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the exact robot model used for shadow tests.\n    Turned on by `debug/marker/shadow` parameter.\n- `robot_model_for_bounding_sphere` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the exact robot model used for computation of\n    bounding sphere. Turned on by `debug/marker/bounding_sphere` parameter.\n- `robot_model_for_bounding_box` (`visualization_msgs/MarkerArray`)\n\n    Marker array containing the exact robot model used for computation of\n    bounding box. Turned on by `debug/marker/bounding_box` parameter.\n- `scan_point_cloud_inside` (`sensor_msgs/PointCloud2`)\n\n    Debugging pointcloud with points classified as `INSIDE`. Turned on by\n    `debug/pcl/inside` parameter.\n- `scan_point_cloud_clip` (`sensor_msgs/PointCloud2`)\n\n    Debugging pointcloud with points classified as `CLIP`. Turned on by\n    `debug/pcl/clip` parameter.\n- `scan_point_cloud_shadow` (`sensor_msgs/PointCloud2`)\n\n    Debugging pointcloud with points classified as `SHADOW`. Turned on by\n    `debug/pcl/shadow` parameter.\n\n### Filter Parameters\n\n- `bounding_sphere/marker` (`bool`, default `false`)\n\n    Whether to publish a marker representing the bounding sphere.\n- `bounding_box/marker` (`bool`, default `false`)\n\n    Whether to publish a marker representing the axis-aligned bounding box\n    aligned to the filtering frame.\n- `oriented_bounding_box/marker` (`bool`, default `false`)\n\n    Whether to publish a marker representing the oriented bounding box.\n- `local_bounding_box/marker` (`bool`, default `false`)\n\n    Whether to publish a marker representing the axis-aligned bounding box\n    aligned to frame `local_bounding_box/frame_id`.\n- `bounding_sphere/debug` (`bool`, default `false`)\n\n    Whether to compute and publish debug bounding spheres (marker array of \n    spheres for each collision).\n- `bounding_box/debug` (`bool`, default `false`)\n\n    Whether to compute and publish debug bounding boxes (marker array of\n    axis-aligned boxes for each collision).\n- `oriented_bounding_box/debug` (`bool`, default `false`)\n\n    Whether to compute and publish debug oriented bounding boxes (marker array\n    of oriented boxes for each collision).\n- `local_bounding_box/debug` (`bool`, default `false`)\n\n    Whether to compute and publish debug axis-aligned bounding boxes aligned to\n    frame `local_bounding_box/frame_id` (marker array of axis-aligned boxes for\n    each collision).\n- `debug/pcl/inside` (`bool`, default `false`)\n\n    Whether to publish debugging pointcloud with points marked as `INSIDE`.\n- `debug/pcl/clip` (`bool`, default `false`)\n\n    Whether to publish debugging pointcloud with points marked as `CLIP`.\n- `debug/pcl/shadow` (`bool`, default `false`)\n\n    Whether to publish debugging pointcloud with points marked as `SHADOW`.\n- `debug/marker/contains` (`bool`, default `false`)\n\n    Whether to publish debugging marker array containing the exact robot body \n    model used for containment test.\n- `debug/marker/shadow` (`bool`, default `false`)\n\n    Whether to publish debugging marker array containing the exact robot body \n    model used for shadow test.\n- `debug/marker/bounding_sphere` (`bool`, default `false`)\n\n    Whether to publish debugging marker array containing the exact robot body \n    model used for computing the bounding sphere.\n- `debug/marker/bounding_box` (`bool`, default `false`)\n\n    Whether to publish debugging marker array containing the exact robot body \n    model used for computing the bounding box.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeci1%2Frobot_body_filter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeci1%2Frobot_body_filter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeci1%2Frobot_body_filter/lists"}