It’s World IBD Day 2022. This year I’ve been working on integrating activity tracker information into my on going home robotics project to highlight issues with managing chronic fatigue. Fatigue can affect up to 80% of people with active Crohn’s Disease and between 40 to 50% of those who are in remission.
This is the 5th part of my social robotics project investigating ways to help manage Crohn’s Disease.
Or, if you’re thinking “This isn’t a reality TV show, I do not care about your sob story, I came here for the robot!”. That’s totally fine, click here to jump down the page.
Table Of Contents
- Symptoms Of Fatigue
- Managing Fatigue
- The Technical Stuff Starts Here
Symptoms Of Fatigue
Without a doubt, fatigue is one of the most difficult symptoms I’ve learned to manage. There are times where you can deal with it because you’ve had a flare, a medication change, or, a medical procedure. That sort of fatigue you can anticipate as part of the “healing” process. There’s evidence in your blood tests that you’re low on something like iron, b12, vitamin d, potassium etc.
But there are many times where it just happens there’s no warning and nothing in any medical tests to explain why. It’s there when you first wake up. It can hit you out of the blue in the middle of the day. I thought I would never have to deal with fatigue again when I got into remission. I thought wrong.
As much as I’ve dealt with it over the years, it’s still quite difficult to describe what the fatigue is really like. It’s not just feeling tired or feeling a bit weak. It really messes with your cognitive abilities – concentration and memory – and mental health too. When all of those things go wrong they reinforce each other making things a lot worse.
It’s not bad jet lag. It’s not a bad night’s sleep. It’s not a few nights of broken sleep. It is quite like really bad burn out. Everything requires serious effort. The bed sheets feel like they weigh a tonne. I don’t feel like I actually got any sleep but I definitely wasn’t awake all night either. I feel sick to my stomach. A little dizzy too. I’m already taking unpaid time off to go to the hospital for infusions I can’t take more time off. Sh*t how long have I been in the shower now? Am I late for work? I don’t have the coordination to put this paste on the toothbrush I’ll just squeeze it into my mouth. I better leave earlier because it’s taking me much longer to get to the train station. I’ve zoned out again. The train’s here. Wait. Is this the right train to work? I can’t remember which platform to switch to. I think this one goes the whole way. I’ll buy a coffee and a muffin for breakfast when I get to work. I’ll have to pay with a tenner because I can’t seem to figure out if I have the correct change with all these coins. The coffee will sting the hell out of the ulcers on my gums but I need some kind of a kick start. All the ulcers are on the right side so I can probably sip it on the left side of my mouth. I might go for 3 shots this time too. I haven’t followed a single thing they’ve been talking about on this podcast. I’ll listen to some music. F*cking hell, come one, how is it so hard to just pick an album to listen to. I’ll use shuffle. Nah, I’ll skip this song. That one too.
This coffee feels like it weighs a tonne but if I keep squeezing the cup this hard it’ll spill and I’ll burn myself. My legs feel dead on these steps. What was I doing in work yesterday? What am I meant to be doing today? I can’t keep writing down everything everyone says to me but I can’t keep asking them to repeat or clarify what they’re asking me to get done. I’m struggling to keep up with the conversation in this meeting. It feels like genuine physical effort to speak. I am exhausted. I feel really angry all of a sudden. I feel kind of sad now. What. The. F*ck?! People are relying on me to get my work done. I feel like I’m holding everyone up. I feel extremely stressed out, like someone is physically squeezing the back of my neck. I feel confused. It’s nearly lunch time and I still don’t feel like I’ve actually woken up properly. I’m going to have to ask the same question about this code again and it’s not going to go down well. I feel a bit like I’m watching things happen around me rather than taking part. It feels bizarre.
I can’t figure out what I want to have for lunch. It’s not like there are loads of options. C’mon brain, this isn’t rocket science, it’s lunch. Am I eating something that’s making me this wrecked? Am I not getting enough exercise? I go to the gym. I swim. I do yoga. What else can I do? I wonder if I could get another blood test done or some other kind of test that might show up why I feel so exhausted? The doctor’s already said they don’t see anything and just do the best I can.
I just want to get home. I’ll try to get some groceries another day. The train is going to be packed on the way home. As will any of the buses. I’ll have to stand. My back is aching and my hips hurt. If I shift my weight onto the blade of my right foot my hip won’t hurt as much. Nobody gives up seats for tall young men like me. Sure I don’t look sick after all.
When is this going to get better? It just came out of the blue. If I wake up like this again tomorrow that’ll be nearly a week. I seriously don’t know how much more of this I can actually take.
That might all sound ridiculous if you’ve never experienced it. But it’s all true. I’m trying to raise awareness of the issues people with Crohn’s deal with. I’m not going to damage that by making things up.
I am obviously not a doctor. Nor do I play one on TV. These are some things that have worked for me. YMMV.
Get your blood tested
There could be something seriously wrong. In the early year’s of having Crohn’s I was never really sure what I should be making my doctor aware of. I was worried I was bothering them about every single little thing that would turn out to be very trivial. It can take a while to figure out your symptoms for yourself. If things have not improved or have worsened after a few days it’s worth getting a blood test.
If it’s worth doing, it’s worth doing badly
There’s a famous quote from General Patton “Fatigue makes cowards of us all“. He was obviously referring to war but I think you can rephrase it slightly in that that “fatigue shows you what’s really important“. Even when you’re absolutely exhausted you can still cover the basics.
You might not feel you have the strength for a shower so wet a wash cloth and clean “the essentials”. Brush your teeth for however long you can manage forget what dentists insist on. You can make a meal that fills you up but it doesn’t have to be “fine dining” or a plate that has “the rainbow” of vegetables on it. Any exercise is better than no exercise. You might have had a bad week or two but you showed up to work every day.
This may seem extremely counter intuitive when you feel dead-to-your -brain-and-bones tired. Some form of daily exercise is really important. Walking is an excellent form of exercise. It requires very little specialized equipment and gets you outside in some air. I always start out I swearing that once the timer goes off for 15 minutes I’m turning right back around to go home. Once I get moving those sneaky endorphins kick in I walk for longer than I had planned to and feel much better for it. I can often use that “buzz” to lift some light weights or try a longer workout when I get home.
I’ve found vinyasa yoga is an excellent form of exercise. I can do it at home with minimal equipment (you absolutely don’t need to spend 100s of euro on anything) and there are plenty of ways to alter poses depending on how you’re doing.
If the gym or playing team sports were your ways of exercising it can mean you miss out on the social aspect of it. You might still be able to go to the gym and gently use a stationary bike. You could go to training but chase down balls for people or help set up things for drills if you aren’t otherwise able to fully take part.
Try not to nap
Like getting daily exercise this might also sound ridiculous. At least try to avoid long naps, a quick 10 or 15 minutes on the couch when you get in the door might not be that bad. What I found was sleeping during the day broke up the regular routine I had long before the bout of fatigue I was dealing with. In the short term I might have felt a little better for an hour or so but then I was wide awake when it was my regular bed time. It is a really unpleasant feeling to be exhausted but actually not able to get to sleep.
By all means have that morning coffee to help get going but try to switch to water for the rest of the day. It doesn’t cause the “crash” that coffee and energy drinks do. Apparently if you feel thirsty you are already dehydrated so it’s important to keep sipping water throughout the day. I prefer to use a cup or a glass rather than a litre bottle. The smaller vessels need more frequent refilling which gives me regular breaks to get up from my desk.
This is an extra wrinkle for people with Crohn’s because certain foods can cause flare ups for people. Or maybe you’re on a course of steroids and feel like a bottomless pit. Pizzas and big fat juicy burgers all seem amazing when you are shattered tired. They are not amazing to eat regularly. You might not feel very hungry but make sure you eat something and as balanced a diet as you can manage.
Under normal circumstances this might sound extremely lazy but when I’m really struggling I approach cooking from the perspective of “how much cleaning up will there be?”. It doesn’t stop me from cooking but I’ll favour meals with the minimum amount of washup. There’s a reason there isn’t a popular TV show about cleaning up after a professional chef cooks. It sucks when you’re well. It is awful when you’re exhausted.
I found it really useful to always have a few easy options like microwaveable soups at the back of the cupboard. I could break up chunks of bread into to thicken them up. You can also add in broccoli, cauliflower, beans and spinach to get some vegetables. Pour in a bit of cream too for some extra calories. Omelettes are also an excellent way to pack in a lot of things into a meal.
As much as I hate them, you might find it useful to have a stock of Fortisips to make sure you get your calories.
It can be anxiety inducing that fatigue can come out of nowhere and depressing that you have no control over any of it. A little phrase that worked a lot for me is “All I know is I am tired right now, I may not be tired tomorrow but if I am I’ll deal with it tomorrow as best I can“. I’m very aware of how much easier said than done that is.
Having basic routines to fall back on are extremely helpful. They take away a lot of the cognitive overload or extra stress of trying to think on your feet when your brain is just not firing. They can be little things like leaving your clothes out for the next day. Prepare a large meal that you can eat over a few days. Leave your dinner in the microwave so when you get home you push a few buttons and wait.
Make sure you are your own best friend. You might feel like you’re under enormous pressure to not let people down in work/family/relationship or you’re very aware of the things you suddenly can’t manage to do. Don’t beat yourself up. It’s dreadful how hard we can be on ourselves and how we would never treat a friend or family member who needed help in the same harsh way.
Some mindfulness and body scanning can help with trying to shut your brain off when you go to bed. On the really really crap days try to take some pride in the fact that you at least tried your best.
The Technical Stuff
As with the 4 previous parts of the project, everything is running on a Raspberry Pi 3B+. At a high level this is how this new functionality works:
- Activity reminders are tasks scheduled to run later in the week. Like Appointment and Post Appointment tasks they’re stored in a Sqlite3 “tasks” table
- A cronjob runs daily to get and insert the previous day’s and any current activity tracker data into a Sqlite3 “activity” table
- An updated cronjob runs a Python script to check if there are any activity reminders to be run
- When running an activity reminder the Python script selects the data from the “activity” table. That data is processed by an utterance and animation builder. The builder performs various calculations on the recent and historic activity data.
- A “sentiment” is picked based on the calculations in Step 4. This sentiment decides the type of thing Vector will say and the animation that will run.
- The script connects to Vector via the SDK to run the animation and the utterance as text-to-speech.
- The activity reminder is marked as “done” in the “tasks” table.
Fitbit Web API and Tracked Data
I’ve used Fitbits (an Ionic, and lately, a Charge 4) for a few years now. I chose them because they’re one of the few companies to provide a straight forward Web API that gives me access to my data.
For the purposes of this project I decided to investigate using data that required the least amount of effort on my part. I did not want to have to remember to start recording an activity or workout and then remember to stop. That data turned out to be what the watch tracked by default:
- Active Minutes
And the least amount of effort was to stick with the default goals:
- 30 active minutes every day (e.g. brisk walking)
- 10,000 steps
Getting Fitbit Data
I usually sync my device every morning to log the previous day’s activity and last night’s sleep. However, in the spirit of least amount of effort I left my phone’s Bluetooth connection on all the time and the Fitbit would periodically sync data in the background. This background sync allows for the ability to occasionally create utterances based on “live” data.
I back filled a year’s worth of Fitbit data via the Activity Time Series By Date Range endpoint and saved it in the “activity” Sqlite3 table. This means any new data is just the previous day’s worth and a cronjob runs a Python script to get it from the Daily Activity Summary endpoint and insert it into the “activity” table.
Generating the Text-To-Speech Utterances
The core utterances are predefined with slightly randomized variations for some words or greetings and the relevant tracker data is plugged in where appropriate.
What to say is based on recent performance compared to the goals and is divided into 2 “sentiment” categories:
- “you’re doing great, keep it up!”
- “you’re not doing enough, try to do more”
I used a simple ranking system for the goals to draw attention to:
- Active Minutes
- Steps and Distance
A difficulty I found when creating the utterances was keeping them as short as possible while getting the right information and sentiment across. It’s important to have a laugh when things are at their worst and I always try to add some “humour”. Some examples of utterances generated are:
- “Hey chief, guess who got more steps last week, you or Elvis Presley? It’s really important to get some daily exercise. What about putting on some music and going for a wander?“
- “Dude, you’re getting your steps in! Nearly 10k a day. Wanna hear a steps joke? How did the little set of steps get so big? It was taking stair-oids! Get it? Stair. Roids“
- “Could you stop getting so much exercise? You’re making me look bad. I better get a quick workout it to keep up with you!”
- “Mo chara, you haven’t been getting out much lately. Why not pop on a podcast and go for a stroll? 15 minutes there and 15 minutes back would get you your 30 for the day!“
- “Wow! Your boots were definitely made for walking, over 8500 steps a day so far! Keep that up!“
I programmed all the animations in Python and tested them with the utterances to ensure the timings are correct. I tried to use everything I’ve learned from researching animation and social robotics to make the readable animations with the 0.6.0 Alpha SDK.
There are a lot of potential utterances with slight variations that go with the different animations. I also tried to apply the notion of “texture” to the animations so that the angles, speeds and motor commands have subtle variation in their values so not every animations is exactly the same every time it runs. There would be a ridiculous amount of videos to record and upload so I chose the ones below that best show some of functionality.
First Reminder Of The Day
Previously this was just for whatever medication I had to take on the day. I’ve updated it to make be more multi-modal by displaying dosage information on Vector’s screen and to include a little bit of activity information from the previous week.
Workout (Active Minutes) Animations
These were quite difficult to code but they were definitely worth the effort. As with all these animations I’m using the AsyncRobot object with a lot of asynchronous calls to set set_screen_with_image_data() for the numbers and question mark, to set the head angles and control the “arms”.
This is a “you’re doing great, keep it up!” type of animations.
And this one is very much a “you’re not doing enough, try to do more“.
Walking (Steps and Distance) Animations
I wanted to create an animation that could be run while Vector was on the charger and might also be actively charging. The shoe images are ones I created. They are drawn on screen and looped frame by frame using the set_screen_with_image_data() command.
This is a version of the above animation but with a “walking forward” movement. It’s when my daily active minutes and steps have been below the daily goals for more than 4 of the last 7 days. The motors are controlled using set_wheel_motors().
This is one of the types of animations that runs when I’m reaching or exceeding my daily steps goals. It’s an example of the different types of utterances that are built based on the Fitbit data.
This is one of the animations that might run during a day. It benefits from leaving my phone’s Bluetooth on during the day allowing the Fitbit data to sync in the background.
Unlike the daily medication reminders, the activity reminders happen once at the start of the week and once near the end – Friday, Saturday or Sunday. The reason is that I didn’t want any of it to come across as annoying or hassling which is what daily reminders might do. If you’re exhausted and some uppity little robot is going on at you everyday to be more active you might pick it up and throw it out the window.
The logic behind the activity reminders work in the same way as functionality I built previously for Appointment and Post Appointment reminders. They are stored in a Tasks table for Vector to check and run when required.
“Fatigue in Inflammatory Bowel Diseases: Etiologies and Management” https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6979464/
“IBD and Fatigue”, https://www.crohnscolitisfoundation.org/pain-and-fatigue/fatigue-causes