Also run a sudo tune2fs -l /dev/mmcblk0p2
(note that “-l” is a lower-case “L”)
This will list all the current attributes of the partition. Post it here.
Also run a sudo tune2fs -l /dev/mmcblk0p2
(note that “-l” is a lower-case “L”)
This will list all the current attributes of the partition. Post it here.
You can also put a generic file system into Dave temporarily, then insert the card using an SD card USB adapter and fsck it there.
Note that there are two utilities that should be installed on every linux system, including the robots:
sudo apt-get install gparted gddrescue
will get them for you. This should be a standard part of your initial setup routine.
pi@GoPi5Go:~/GoPi5Go $ ls
config Graphics LICENSE logs plib README.md saved status.sh systests utils
pi@GoPi5Go:~/GoPi5Go $ sudo tune2fs -l /dev/mmcblk0p2
tune2fs 1.47.0 (5-Feb-2023)
Filesystem volume name: rootfs
Last mounted on: /
Filesystem UUID: fc7a1f9e-4967-4f41-a1f5-1b5927e6c5f9
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file dir_nlink extra_isize metadata_csum
Filesystem flags: unsigned_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Remount read-only
Filesystem OS type: Linux
Inode count: 1886976
Block count: 7659648
Reserved block count: 382982
Free blocks: 5810832
Free inodes: 1709668
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 321
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8064
Inode blocks per group: 504
Flex block group size: 16
Filesystem created: Fri Mar 15 11:11:08 2024
Last mount time: Thu Mar 28 07:27:57 2024
Last write time: Thu Mar 28 09:28:10 2024
Mount count: 4
Maximum mount count: 5
Last checked: Wed Mar 27 12:49:21 2024
Check interval: 604800 (1 week)
Next check after: Wed Apr 3 12:49:21 2024
Lifetime writes: 63 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 32
Desired extra isize: 32
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: 754db390-ca56-4b3a-b935-14c23d4e6fdb
Journal backup: inode blocks
Checksum type: crc32c
Checksum: 0
That looks OK, now you need to move it to another system, (or Dave with a copy of GoPiGoO/S), and run a sudo fsck -f -v -D /dev/mmcblk0p2
You might want to run it the first time with a “-n” just to see what it would do. Ultimately you’re going to run it as listed to actually fix it.
Tested with journalctf -kf
running and got a hit after only 6 rotations of Dave:
********* GoPi5Go-Dave STATUS *****
2024-03-28 09:53:36 up 2:25, 3 users, load average: 0.24, 0.05, 0.02
Current Battery 12.3v (Reading 11.55v)
5v Supply: 4.98
Processor Temp: 46.6'C
Clock Frequency: 1.50 GHz
throttled=0x0
********* GoPi5Go-Dave STATUS *****
Traceback (most recent call last):
File "/home/pi/GoPi5Go/plib/status.py", line 131, in <module>
File "/home/pi/GoPi5Go/plib/status.py", line 119, in main
File "/home/pi/GoPi5Go/plib/status.py", line 79, in printStatus
File "/home/pi/GoPi5Go/plib/status.py", line 74, in getUptime
File "<frozen os>", line 987, in popen
File "/usr/lib/python3.11/subprocess.py", line 1024, in __init__
File "/usr/lib/python3.11/subprocess.py", line 1901, in _execute_child
OSError: [Errno 5] Input/output error: '/bin/sh'
./status.sh: error reading input file: Input/output error
pi@GoPi5Go:~/GoPi5Go $ journalctl -kf
Mar 28 07:27:59 GoPi5Go kernel: macb 1f00100000.ethernet: gem-ptp-timer ptp clock registered.
Mar 28 07:27:59 GoPi5Go kernel: Bluetooth: BNEP (Ethernet Emulation) ver 1.3
Mar 28 07:27:59 GoPi5Go kernel: Bluetooth: BNEP filters: protocol multicast
Mar 28 07:27:59 GoPi5Go kernel: Bluetooth: BNEP socket layer initialized
Mar 28 07:27:59 GoPi5Go kernel: Bluetooth: MGMT ver 1.22
Mar 28 07:27:59 GoPi5Go kernel: NET: Registered PF_ALG protocol family
Mar 28 07:27:59 GoPi5Go kernel: brcmfmac: brcmf_cfg80211_set_power_mgmt: power save enabled
Mar 28 07:28:13 GoPi5Go kernel: Bluetooth: RFCOMM TTY layer initialized
Mar 28 07:28:13 GoPi5Go kernel: Bluetooth: RFCOMM socket layer initialized
Mar 28 07:28:13 GoPi5Go kernel: Bluetooth: RFCOMM ver 1.11
Mar 28 09:53:35 GoPi5Go kernel: mmc0: Card stuck being busy! __mmc_poll_for_busy
My rotation program continues to operate just fine because it does not invoke anything that needs to access the sdcard.
You need to know the status of the SD card and/or filesystem. There is a distinct possibility that the SD card has begun to go all pear-shaped.
Have you tried removing it and cleaning all the contacts with a clean eraser? Do that and then fsck it.
Interesting - As part of the recovery from that “mmc0: Card stuck being busy!” (exclamation point theirs…), I plugged the sdcard directly into the Pi5, rather than the sdcard extender.
Also since the mount count was at 4, restarted twice to trigger the fsck:
pi@GoPi5Go:~/GoPi5Go $ utils/last_fsck.sh
Filesystem: /dev/mmcblk0p2 (/)
Last checked: Thu Mar 28 10:08:53 2024
pi@GoPi5Go:~/GoPi5Go $ sudo tune2fs -l /dev/mmcblk0p2
tune2fs 1.47.0 (5-Feb-2023)
Filesystem volume name: rootfs
Last mounted on: /
Filesystem UUID: fc7a1f9e-4967-4f41-a1f5-1b5927e6c5f9
Filesystem magic number: 0xEF53
Filesystem revision #: 1 (dynamic)
Filesystem features: has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file dir_nlink extra_isize metadata_csum
Filesystem flags: unsigned_directory_hash
Default mount options: user_xattr acl
Filesystem state: clean
Errors behavior: Remount read-only
Filesystem OS type: Linux
Inode count: 1886976
Block count: 7659648
Reserved block count: 382982
Free blocks: 5808805
Free inodes: 1709688
First block: 0
Block size: 4096
Fragment size: 4096
Reserved GDT blocks: 321
Blocks per group: 32768
Fragments per group: 32768
Inodes per group: 8064
Inode blocks per group: 504
Flex block group size: 16
Filesystem created: Fri Mar 15 11:11:08 2024
Last mount time: Thu Mar 28 10:08:56 2024
Last write time: Thu Mar 28 10:08:53 2024
Mount count: 1
Maximum mount count: 5
Last checked: Thu Mar 28 10:08:53 2024
Check interval: 604800 (1 week)
Next check after: Thu Apr 4 10:08:53 2024
Lifetime writes: 63 GB
Reserved blocks uid: 0 (user root)
Reserved blocks gid: 0 (group root)
First inode: 11
Inode size: 256
Required extra isize: 32
Desired extra isize: 32
Journal inode: 8
Default directory hash: half_md4
Directory Hash Seed: 754db390-ca56-4b3a-b935-14c23d4e6fdb
Journal backup: inode blocks
Checksum type: crc32c
Checksum: 0x76313ff1
Going to try test again with SDcard in the Pi5 rather than extender… 20 rotations so far no busy notice… maybe… (30 spin360 completed and Dave is only 2 to 3 degrees off original heading… not too shabby)
450 rotations no “card busy!” issues - only the GoPiGo3 EasyGoPiGo3.target_reached() issue when the 32-bit encoder values roll over, which happens 2.7 times faster with a 16-tick GoPiGo3!
Probably not the best idea to have the sdCard extender ribbon cable going right between those high current motor wires and high frequency encoder wires:
The good thing about all this testing, I have refined Dave’s WHEEL_BASE by 0.03mm making his turns just a little more accurate, and added “o Spin opposite direction” command to my wheelBaseRotateTest.py program. New WHEEL_BASE=105.09mm and WHEEL_DIAMETER=66.05mm
While we’re talking about filesystem mount options. . . . I discovered this while looking at the ext4 mount options man page:
The man page does not say if it is enabled or disabled by default, so I have to assume it is NOT enabled.
So, it looks like auto_da_alloc
is a useful thing to append to the root filesystem’s fstab entry to make sure things get forced to disk in a timely manner - especially using robots because of the possibilities of strange things happening.
In ten years of programming robots on Raspberry Pi in Python, I have never explicitly closed or renamed a file, much prefer to use Python logging for appending a single line to a file:
lifeLog.logger.info(strToLog)
or Python with
for writing whole files:
with open(outFileName,'w') as fOut:
fOut.writelines(lineList)
Both of these are wrapped with layers of protection for the myriad of possible issues that only OS and kernel geeks are aware of. I have never had need to rename files.
Other than the life.log, speak.log, wheel.log, voiceAction.log, carlData.json, and the rare batteryLife.csv files, my robots do not explicitly manipulate files. Carl uses the bullet-proof RoundRobinDataTool to store metrics for his RPI-Monitor:
While I appreciate your interest in Dave’s health, I have put my trust in the Raspberry Pi Foundation, the Debian community, and the Python Software Foundation to configure the OS and programming tools, with the addition of routine backups for dynamic files. In reality, my robots are not “mission critical” applications either.
When playtime is less than recharge time, it means time to order a new set of Eneloop White NiMH 2000mAh AA cells. The current cells are 1 year 7 days old and have undergone 869 cycles.
Well. . . .
It’s up to you if you are interested or not. I’m just making it available.
In my own case, while dinking around with filesystems, boot methods, various media and add-on hats, (etc.), I’ve seen Charlie go brain-dead on occasion for whatever reason.
I might start including that, as well as “discard”, but your milage, (and needs), will most certainly vary.
Have you considered a freelance job with Consumer Reports? Or maybe the FTC investigating potential false advertising and product safety?
Your statistics should be worth their weight in plutonium! (Without the radiation hazard, of course!)
Call me superstitious on this one: Is this error connected to those six gopigo3.py lines I commented out (that set up SPI)?
Last night, GoPi5Go-Dave had two Python programs accessing the GoPiGo3 red-board via SPI periodically: status.py
and safetyShutdown.py
. They both are sending SPI_MESSAGE_TYPE: GET_VOLTAGE_VCC over the SPI bus to read a 16 bit value from the serial interface.
Supposedly the SPI bus using the Python package spidev
has multi-thread protection. That’s on the software side, but does the RPi SPI chip select need a software configured pull down that I commented out?
I have seen posts that suggest WiringPi
might be the desired replacement for pigpiod
. I’m going to have to take another look at those six lines of pigpiod
code.
Luckily, this error just killed the GoPiGo3 status.py
program, leaving the robot healthy and accessible.
********* GoPi5Go-Dave STATUS *****
2024-03-30 03:49:52 up 13:42, 2 users, load average: 0.01, 0.02, 0.00
Current Battery 12.3v (Reading 11.79v)
Traceback (most recent call last):
File "/home/pi/GoPi5Go/plib/status.py", line 131, in <module>
main()
File "/home/pi/GoPi5Go/plib/status.py", line 119, in main
printStatus(egpg)
File "/home/pi/GoPi5Go/plib/status.py", line 81, in printStatus
if battery.on_last_leg(egpg):
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/pi/GoPi5Go/plib/battery.py", line 40, in on_last_leg
vBatt, _ = vBatt_vReading(egpg)
^^^^^^^^^^^^^^^^^^^^
File "/home/pi/GoPi5Go/plib/battery.py", line 22, in vBatt_vReading
vReading = egpg.volt()
^^^^^^^^^^^
File "/home/pi/GoPi5Go/plib/noinit_easygopigo3.py", line 145, in volt
voltage = self.get_voltage_battery()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.11/dist-packages/gopigo3-1.3.2.1-py3.11.egg/gopigo3.py", line 617, in get_voltage_battery
File "/usr/local/lib/python3.11/dist-packages/gopigo3-1.3.2.1-py3.11.egg/gopigo3.py", line 303, in spi_read_16
OSError: No SPI response
Driven by my C++ keyboard controlled drive program, GoPi5Go-Dave attempted his first docking:
Discovered I cannot have a Python GoPiGo3 battery monitor program active while the C++ program is driving Dave - Unexpected behaviors will occur.
Oh no. It was looking so good until the very ending.
I think that’s one of the reason the turtlebots were designed wider and flatter.
/K
Dave’s CG is purposely close to the wheels to improve turn_degrees() accuracy. I’m going to have to re-evaluate the central battery pack location.
(The TurtleBot 4 had a honkin’ counterweight in the whole back of the accessory drawer.) Indeed if I was a 3D printing wizard, I would print up a wider GoPiGo3 base plate and use the raw encoders instead of the GoPiGo3 API which only returns whole degree precision. WIder would give better heading measurement accuracy as well as turn accuracy.
New battery location (did not affect turn accuracy that was previously fine tuned with wheelBaseRotateTest.py):
Guess my C++ days are feeling less exciting now that I have the Python GoPiGo3 API running on the Pi 5.
In the fashion of the ROS 2 teleop_keyboard node, the speeds are in meters/second and radians/second.
(Not that meters/second and radians per second are any more intuitive to me than degrees per second.)
This program takes keypresses from the keyboard to drive the GoPiGo3 robot
using the EasyGoPiGo3 API. It works best with a US keyboard layout.
---------------------------
Moving around:
forward i
spin ccw j k l spin cw
backward ,
STOP: k or spacebar
q/z : increase/decrease max speeds by 10%
w/x : increase/decrease only linear speed by 10%
e/c : increase/decrease only angular speed by 10%
The neatest thing about the program is the Python keypress capture method. Much better than my previous Python style of setting tts raw and resetting it back (hopefully).
Which deserves to be tested, no?
Of course it all started with trying an algorithm to detect when to stop (backing onto his dock) by watching the average battery voltage and the change in average battery voltage.
Update: the plan changed when I got Python working…: