Skip to content
Open
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
51a5a4c
the odometry form the wheel sucks big time, need to work on that. how…
muhtasim001 May 26, 2025
ea5b8b2
fixed wheel odom node, it has drift, but it looks good enough, after …
muhtasim001 May 27, 2025
7f0adb2
just added a toggle for broadcasting the transform
muhtasim001 May 27, 2025
1a28b3c
the ekf package is now working, needs to be tuned and tested still
muhtasim001 May 27, 2025
903b628
finished up the ekf node, need to debug the ekf node, something going…
muhtasim001 Jun 7, 2025
5b6d137
the node works kinda, the state esimtation needs the parameters tuned…
muhtasim001 Jun 7, 2025
c5afce9
the nan issue seems to have fixed it self after a added a block to ch…
muhtasim001 Jun 7, 2025
ff507ea
made most of the changes from the pull request
muhtasim001 Jun 10, 2025
e2ec71d
fixed the docker issue
muhtasim001 Jun 10, 2025
b04c933
work in progress
muhtasim001 Jun 12, 2025
aacd048
ekf and odom are in good working order, the peformance of ekf is not …
muhtasim001 Jun 13, 2025
e049718
added in some stuff for amcl, and modefied the process model of ekf t…
muhtasim001 Jun 17, 2025
cb1d1a7
modefied the prcess model, jacobian and observation model
muhtasim001 Jun 18, 2025
a6a7aa5
reverted some changes
muhtasim001 Jun 19, 2025
5ea4af1
pf is working, just crashes after a bit, need to investigate that
muhtasim001 Jun 20, 2025
3a7267e
particle filter is working properlty
muhtasim001 Jun 21, 2025
4bb6821
work in prgoress
muhtasim001 Jun 21, 2025
28dd967
working particle filter
muhtasim001 Jun 21, 2025
c060190
added a missing run apt-get update on line 48 of the robot docker fil…
muhtasim001 Jun 22, 2025
f33e222
removing logs
muhtasim001 Jun 22, 2025
2c744ff
added the means ot test and validate the ekf
muhtasim001 Jun 22, 2025
7f5c4a2
clean up and making docs
muhtasim001 Jun 24, 2025
4c8bab1
test out the amcl form nav2, performance is not very good
muhtasim001 Jun 24, 2025
8229b89
running gui apps clefification
muhtasim001 Jun 25, 2025
898f90f
revamping the wheel odom
muhtasim001 Jun 27, 2025
916cc7a
clean up the wheel odom, and fixed the issue of jagged output
muhtasim001 Jul 3, 2025
0fb1b80
layed the foundation for the new ekf
muhtasim001 Jul 4, 2025
de7956f
ekf_rt wip
muhtasim001 Jul 9, 2025
8221114
wip
muhtasim001 Jul 10, 2025
9dcbc1f
wip ekf new version
muhtasim001 Jul 12, 2025
1b9e374
wip
muhtasim001 Jul 16, 2025
8dc3166
wip
muhtasim001 Jul 17, 2025
2e0bd89
finished the code need to debug new ekf
muhtasim001 Jul 18, 2025
0cbd2c5
updated the controller for real car
muhtasim001 Aug 1, 2025
6816103
controller update
muhtasim001 Aug 8, 2025
4679c36
added the ackerman converter
muhtasim001 Aug 8, 2025
12daff4
testing
muhtasim001 Aug 13, 2025
1684788
ekf fixing in progress
muhtasim001 Aug 16, 2025
e47c6d4
finishing up ekf
muhtasim001 Aug 18, 2025
dd23e90
all the ekf calculation are correct, but the sigma keeps corupting
muhtasim001 Aug 20, 2025
e225938
the sigma_t is the prediction step is still corrupting
muhtasim001 Aug 20, 2025
5330ff8
still implementing the numirical stability fixes
muhtasim001 Aug 21, 2025
e70931c
the filter is comming togeather, the values make sense in a straight …
muhtasim001 Aug 22, 2025
57e5772
finished the ekf. it is fully functional, however a nasty bug presist…
muhtasim001 Aug 22, 2025
bcb6c99
fixed the wierd timming issue, it was a non issue and was happning du…
muhtasim001 Aug 24, 2025
f540b4c
data testing in progress
muhtasim001 Sep 5, 2025
a46c381
fixed the docker files, and added some benchmaking tools to it
muhtasim001 Sep 17, 2025
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 @@ -3,3 +3,4 @@ __pycache__
.vscode/

watod-config.local.sh
/log
115 changes: 115 additions & 0 deletions config/ekf_testing.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
{
"configById": {
"RawMessages!1fqah6": {
"diffEnabled": false,
"diffMethod": "custom",
"diffTopicPath": "",
"showFullMessageForDiff": false,
"topicPath": "/ekf/odom",
"fontSize": 12
},
"Plot!18f3n3x": {
"paths": [
{
"timestampMethod": "receiveTime",
"value": "/autodrive/f1tenth_1/ips.x",
"enabled": true,
"color": "#4e98e2",
"label": "Ground Truth X"
},
{
"timestampMethod": "receiveTime",
"value": "/wheel_odom.pose.pose.position.x",
"enabled": true,
"color": "#f5774d"
},
{
"timestampMethod": "receiveTime",
"value": "/ekf/odom.pose.pose.position.x",
"enabled": true,
"color": "#80f772"
}
],
"showXAxisLabels": true,
"showYAxisLabels": true,
"showLegend": true,
"legendDisplay": "floating",
"showPlotValuesInLegend": false,
"isSynced": true,
"xAxisVal": "timestamp",
"sidebarDimension": 240
},
"RawMessages!13gpg4b": {
"diffEnabled": false,
"diffMethod": "custom",
"diffTopicPath": "",
"showFullMessageForDiff": false,
"topicPath": "/autodrive/f1tenth_1/ips",
"fontSize": 12
},
"Plot!2qhv9dy": {
"paths": [
{
"timestampMethod": "receiveTime",
"value": "/autodrive/f1tenth_1/ips.y",
"enabled": true,
"color": "#4e98e2",
"label": "Ground truth Y"
},
{
"timestampMethod": "receiveTime",
"value": "/wheel_odom.pose.pose.position.y",
"enabled": true,
"color": "#f5774d"
},
{
"timestampMethod": "receiveTime",
"value": "/ekf/odom.pose.pose.position.y",
"enabled": true,
"color": "#80f772"
}
],
"showXAxisLabels": true,
"showYAxisLabels": true,
"showLegend": true,
"legendDisplay": "floating",
"showPlotValuesInLegend": false,
"isSynced": true,
"xAxisVal": "timestamp",
"sidebarDimension": 240
}
},
"globalVariables": {},
"userNodes": {
"cec2ab24-3fb7-4faf-b079-3ff35cf0d557": {
"sourceCode": "import { Input, Message } from \"./types\";\n\ntype Output = {\n data: boolean; // Qualification status\n};\n\n// Input topics\nexport const inputs = [\n \"/autodrive/f1tenth_1/lap_count\",\n \"/autodrive/f1tenth_1/collision_count\",\n];\n\n// Output topic\nexport const output = \"/autodrive/f1tenth_1/qualification_status\";\n\n// Variables\nlet lapCount = 0;\nlet collisionCount = 0;\nlet collisionsDuringWarmup = 0; // Collisions during warmup lap (0)\nlet collisionsDuringRace = 0; // Collisions during race laps (1-10)\n\n// Script\nexport default function script(\n event:\n | Input<\"/autodrive/f1tenth_1/lap_count\">\n | Input<\"/autodrive/f1tenth_1/collision_count\">,\n): Output {\n if (event.topic === \"/autodrive/f1tenth_1/lap_count\") {\n // Read event.message fields expected for /autodrive/f1tenth_1/lap_count messages\n lapCount = event.message.data;\n } else {\n // Read event.message fields expected for /autodrive/f1tenth_1/collision_count messages\n collisionCount = event.message.data;\n }\n\n // Debugging\n // log(event.message.data);\n\n // Define the qualification status logic\n let qualificationStatus = true;\n\n if (lapCount < 1) {\n // Ignore collisions during warmup lap (0)\n collisionsDuringRace = 0;\n collisionsDuringWarmup = collisionCount;\n qualificationStatus = true;\n } else if (lapCount >= 1 && lapCount <= 10) {\n // Calculate collisions during race laps (1 to 10)\n collisionsDuringRace = collisionCount - collisionsDuringWarmup;\n qualificationStatus = collisionsDuringRace <= 10;\n }\n\n // Debugging\n // log(collisionsDuringWarmup);\n // log(collisionsDuringRace);\n // log(qualificationStatus);\n\n // Return the qualification status as the output\n return {\n data: qualificationStatus,\n };\n}\n",
"name": "Qualification Status"
},
"a5eb1ac9-8dba-4b05-8e9f-a0c3ecdc3953": {
"sourceCode": "import { Input, Message } from \"./types\";\n\ntype Output = {\n data: number; // Race time (seconds)\n};\n\n// Input topics\nexport const inputs = [\n \"/autodrive/f1tenth_1/lap_count\",\n \"/autodrive/f1tenth_1/last_lap_time\",\n];\n\n// Output topic\nexport const output = \"/autodrive/f1tenth_1/race_time\";\n\n// Variables\nlet lapCount = 0;\nlet lastLapCount = -1; // Track the previous lap count\nlet lastLapTime = 0; // Track the previous lap time\nlet raceTime = 0; // Time elapsed during race laps (1-10)\n\n// Script\nexport default function script(\n event:\n | Input<\"/autodrive/f1tenth_1/lap_count\">\n | Input<\"/autodrive/f1tenth_1/last_lap_time\">,\n): Output {\n if (event.topic === \"/autodrive/f1tenth_1/lap_count\") {\n // Read event.message fields expected for /autodrive/f1tenth_1/lap_count messages\n lapCount = event.message.data;\n } else {\n // Read event.message fields expected for /autodrive/f1tenth_1/last_lap_time messages\n lastLapTime = event.message.data;\n }\n\n // Debugging\n // log(event.message.data);\n\n // Check time only for race laps\n if (lapCount >= 3 && lapCount <= 12) {\n // Only add time once per lap increment\n if (lapCount > lastLapCount) {\n raceTime += lastLapTime;\n lastLapCount = lapCount;\n }\n }\n\n // Debugging\n // log(lastLapTime);\n // log(raceTime);\n\n // Return the total race time as the output\n return {\n data: raceTime,\n };\n}\n",
"name": "Race Time"
},
"125add07-11e4-46e5-8c4e-84954294e443": {
"sourceCode": "import { Input, Message } from \"./types\";\n\ntype Output = {\n data: number; // Adjusted race time (seconds)\n};\n\n// Input topics\nexport const inputs = [\n \"/autodrive/f1tenth_1/lap_count\",\n \"/autodrive/f1tenth_1/collision_count\",\n \"/autodrive/f1tenth_1/last_lap_time\",\n];\n\n// Output topic\nexport const output = \"/autodrive/f1tenth_1/adjusted_race_time\";\n\n// Variables\nlet lapCount = 0; // Current lap count\nlet collisionCount = 0; // Current collision count\nlet collisionsDuringWarmup = 0; // Collisions during warmup lap (0)\nlet collisionsDuringRace = 0; // Collisions during race laps (1-10)\nlet lastLapCount = -1; // Track the previous lap count\nlet lastLapTime = 0; // Track the previous lap time\nlet raceTime = 0; // Time elapsed during race laps (1-10)\nlet adjustedRaceTime = 0; // Race time with penalties\n\n// Script\nexport default function script(\n event:\n | Input<\"/autodrive/f1tenth_1/lap_count\">\n | Input<\"/autodrive/f1tenth_1/collision_count\">\n | Input<\"/autodrive/f1tenth_1/last_lap_time\">,\n): Output {\n if (event.topic === \"/autodrive/f1tenth_1/lap_count\") {\n // Read event.message fields expected for /autodrive/f1tenth_1/lap_count messages\n lapCount = event.message.data;\n } else if (event.topic === \"/autodrive/f1tenth_1/collision_count\") {\n // Read event.message fields expected for /autodrive/f1tenth_1/collision_count messages\n collisionCount = event.message.data;\n } else {\n // Read event.message fields expected for /autodrive/f1tenth_1/last_lap_time messages\n lastLapTime = event.message.data;\n }\n\n // Debugging\n // log(event.message.data);\n\n // Calculate collisions only for race laps\n if (lapCount < 1) {\n // Ignore collisions during warmup lap (0)\n collisionsDuringRace = 0;\n collisionsDuringWarmup = collisionCount;\n } else if (lapCount >= 1 && lapCount <= 10) {\n // Calculate collisions during race laps (1 to 10)\n collisionsDuringRace = collisionCount - collisionsDuringWarmup;\n }\n\n // Check time only for race laps\n if (lapCount >= 3 && lapCount <= 12) {\n // Only add time once per lap increment\n if (lapCount > lastLapCount) {\n raceTime += lastLapTime;\n lastLapCount = lapCount;\n }\n }\n\n // Calculate adjusted race time\n if (lapCount > 11) {\n adjustedRaceTime = raceTime + 10 * collisionsDuringRace;\n }\n\n // Debugging\n // log(collisionsDuringWarmup);\n // log(collisionsDuringRace);\n // log(lastLapTime);\n // log(raceTime);\n // log(adjustedRaceTime);\n\n // Return the qualification status as the output\n return {\n data: adjustedRaceTime,\n };\n}\n",
"name": "Adjusted Race Time"
}
},
"playbackConfig": {
"speed": 1
},
"layout": {
"first": {
"first": "RawMessages!1fqah6",
"second": "Plot!18f3n3x",
"direction": "column",
"splitPercentage": 40.728476821192054
},
"second": {
"first": "RawMessages!13gpg4b",
"second": "Plot!2qhv9dy",
"direction": "column",
"splitPercentage": 40.728476821192054
},
"direction": "row"
}
}
Binary file added config/images/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added config/images/image2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added config/images/image3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added config/images/image4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added config/images/image5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added config/images/localize.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added config/images/mapping.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
39 changes: 39 additions & 0 deletions docker/robot/robot.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ FROM ${BASE_IMAGE} AS source

WORKDIR ${AMENT_WS}/src

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Clean up and update apt-get, then update rosdep
RUN sudo apt-get clean && \
sudo apt-get update && \
Expand All @@ -16,6 +19,10 @@ RUN sudo apt-get clean && \
COPY src/robot .

# Scan for rosdeps

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
| grep 'apt-get install' \
Expand All @@ -26,6 +33,10 @@ RUN apt-get -qq update && rosdep update && \
FROM ${BASE_IMAGE} AS dependencies

# Clean up and update apt-get, then update rosdep

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

RUN sudo apt-get clean && \
sudo apt-get update && \
sudo rosdep update
Expand All @@ -35,6 +46,7 @@ RUN sudo apt-get install libeigen3-dev

# Install Rosdep requirements
COPY --from=source /tmp/colcon_install_list /tmp/colcon_install_list
RUN apt-get update
RUN apt-fast install -qq -y --no-install-recommends $(cat /tmp/colcon_install_list)

# Copy in source code from source stage
Expand All @@ -50,6 +62,10 @@ RUN apt-get -qq autoremove -y && apt-get -qq autoclean && apt-get -qq clean && \
FROM dependencies AS build

# Clean up and update apt-get, then update rosdep

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

RUN sudo apt-get clean && \
sudo apt-get update && \
sudo rosdep update
Expand All @@ -63,6 +79,29 @@ RUN . /opt/ros/$ROS_DISTRO/setup.sh && \
# Source and Build Artifact Cleanup
RUN rm -rf src/* build/* devel/* install/* log/*

#add the slam toolbox, localizaiton and rviz2
RUN sudo apt-get update
RUN sudo apt-get install -y ros-humble-rviz2
RUN sudo apt-get install -y ros-humble-navigation2
RUN sudo apt-get install -y ros-humble-slam-toolbox

#add controler support to the container
RUN sudo apt-get install -y ros-humble-joy
RUN sudo apt-get install -y jstest-gtk
RUN mkdir -p /root/.config/jstest-gtk

#add the nesscary depends for particle filter
RUN sudo apt-get install -y pip
RUN sudo pip3 install cython

RUN mkdir -p /tmp/build && \
cd /tmp/build && \
git clone https://github.com/f1tenth/range_libc.git && \
cd range_libc/pywrapper && \
python3 setup.py install && \
cd / && rm -rf /tmp/build


# Entrypoint will run before any CMD on launch. Sources ~/opt/<ROS_DISTRO>/setup.bash and ~/ament_ws/install/setup.bash
COPY docker/wato_ros_entrypoint.sh ${AMENT_WS}/wato_ros_entrypoint.sh
ENTRYPOINT ["./wato_ros_entrypoint.sh"]
4 changes: 4 additions & 0 deletions docker/samples/cpp_aggregator.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ COPY src/samples/cpp/aggregator aggregator
COPY src/wato_msgs/sample_msgs sample_msgs

# Scan for rosdeps

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
| grep 'apt-get install' \
Expand Down
3 changes: 3 additions & 0 deletions docker/samples/cpp_producer.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ WORKDIR ${AMENT_WS}/src
COPY src/samples/cpp/producer producer
COPY src/wato_msgs/sample_msgs sample_msgs

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Scan for rosdeps
RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
Expand Down
3 changes: 3 additions & 0 deletions docker/samples/cpp_transformer.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ WORKDIR ${AMENT_WS}/src
COPY src/samples/cpp/transformer transformer
COPY src/wato_msgs/sample_msgs sample_msgs

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Scan for rosdeps
RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
Expand Down
3 changes: 3 additions & 0 deletions docker/samples/py_aggregator.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ WORKDIR ${AMENT_WS}/src
COPY src/samples/python/aggregator aggregator
COPY src/wato_msgs/sample_msgs sample_msgs

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Scan for rosdeps
RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
Expand Down
4 changes: 4 additions & 0 deletions docker/samples/py_producer.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ARG BASE_IMAGE=ghcr.io/watonomous/robot_base/base:humble-ubuntu22.04


################################ Source ################################
FROM ${BASE_IMAGE} AS source

Expand All @@ -9,6 +10,9 @@ WORKDIR ${AMENT_WS}/src
COPY src/samples/python/producer producer
COPY src/wato_msgs/sample_msgs sample_msgs

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Scan for rosdeps
RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
Expand Down
3 changes: 3 additions & 0 deletions docker/samples/py_transformer.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ WORKDIR ${AMENT_WS}/src
COPY src/samples/python/transformer transformer
COPY src/wato_msgs/sample_msgs sample_msgs

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Scan for rosdeps
RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
Expand Down
7 changes: 7 additions & 0 deletions docker/vis_tools/foxglove.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
ARG BASE_IMAGE=ghcr.io/watonomous/robot_base/base:humble-ubuntu22.04


################################ Source ################################
FROM ${BASE_IMAGE} AS source

Expand All @@ -8,6 +9,9 @@ WORKDIR ${AMENT_WS}/src
# Copy in source code
COPY src/wato_msgs wato_msgs

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Scan for rosdeps
RUN apt-get -qq update && rosdep update && \
rosdep install --from-paths . --ignore-src -r -s \
Expand All @@ -18,6 +22,9 @@ RUN apt-get -qq update && rosdep update && \
################################# Dependencies ################################
FROM ${BASE_IMAGE} AS dependencies

RUN apt-get update && apt-get install -y curl \
&& curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg

# Install Foxglove Deps
RUN apt-get update && apt-get install -y curl ros-humble-ros2bag ros-humble-rosbag2* ros-humble-foxglove-msgs&& \
rm -rf /var/lib/apt/lists/*
Expand Down
Loading