Announcement

Collapse
No announcement yet.

Any way to get around read-only file system?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Any way to get around read-only file system?

    I want to write a CSV (comma separated values) text file that can quickly be used to graph data after running an autonomous opmode.

    I assumed that the file system could be written to, because I have an example OpenCV opmode that takes a webcam snapshot and writes it to the control hub file system under the "FIRST/data" directory.

    Yet when I try to use FileWriter to create a text file, I get an exception: "Read-only file system".

    Is there a way around this? Or is there another way to log data that can quickly be graphed? I know I can log ADB data to the giant log file, and I could filter out my lines of interest and do post-processing to get a nice CSV file, but I'd prefer something cleaner than that.

    Thanks!
    Ed (mentor for Browncoats in Huntsville AL)

  • #2
    My guess is you're not passing the correct path to the FileWriter. For instance, if you pass "/FIRST/data/mylog.txt" it will fail. Try the following:


    String logFilePath = String.format("%s/FIRST/data/mylog.txt", Environment.getExternalStorageDirectory().getAbsolutePath());

    Comment


    • #3
      Thanks for the suggestion. That seems to have gotten me part way there. It is now creating the file, but it is empty despite the fact that I have several write statements executed and a close at the end.

      To be sure, I put a writer.write("testing") statement right after the FileWriter constructor call so I would know at least one write operation would be called. It is not throwing any exceptions on the file create or the file writes. This feels like something I've run into in the past with C#, where a "using" or a "with" block was needed to encapsulate the whole file opening/writing/closing operation. Any thoughts?

      Comment


      • #4
        Ed, what happens if you run the following command?

        Code:
        adb shell cat /sdcard/FIRST/data/mylog.txt

        Comment


        • #5
          Noah, Something I did recently got it working. Previously, the file was 0 length, now it is 43 bytes. I tried your statement and changed the name from mylog.txt to the name of my csv file. It printed out what I expected it to contain (though I had neglected to add line delimiters). Coincidentally, I hadn't looked in my FileBrowser since it had been fixed, so I wondered if the "cat" command was operating differently. But when I went back to the FileExplorer, I saw the size was now being reported as 43 bytes, and when I opened it in Notepad, it had the contents I expected. It may be that I was neglecting to call the function that contained my writer.close statement. That is the only thing I can think of, even though I thought sure I had checked after modifying that.

          Thanks you Noah and 4634.

          Comment


          • #6
            For any Blocks programmers wishing to do something like this, see this example. It's part of a larger tutorial on myBlocks, which are custom Blocks created with OnBotJava or Android Studio. This capability is now offered in the official FTC apps.

            To get you started, the tutorial's simple example writes a single value to a file on the Robot Controller. An expanded version could write multiple values, similar to the specialized log file described in this post.

            Perhaps the OP edholder could post a focused version of the Java code that eventually worked?

            Comment


            • #7
              Here is the approach I got working using Android Studio/Java. I simplified the approach by simply creating and writing the file at the end during shutdown. I used a StringBuffer to collect my log records during the run.

              I used a mechanism class to encapsulate all the hardware-specific code. In that class:

              Code:
              StringBuffer m_csvLogString = new StringBuffer();
              In the init function, this buffer needs to be reset as follows:

              Code:
              m_csvLogString.setLength(0);
              I created a function for logging a single string as a CSV record as follows:

              Code:
              public void logCsvString(String record) {
                    m_csvLogString.append(record + "\n");
              }
              I also have a stopRobot function in my mechanism class. Here is that function:

              Code:
              public String stopRobot() {
                   String rv = "Stop complete";
                   if (m_csvLogString.length() > 0) {
                        String csvPath = String.format("%s/FIRST/data/robot-data.csv",
                                       Environment.getExternalStorageDirectory().getAbsolutePath());
                        try (FileWriter csvWriter = new FileWriter(csvPath, "false")) {
              csvWriter.write(m_csvLogString.toString());
              }
              catch (IOException e) {
              rv = e.getMessage();
              }
              }
              return rv;
              }
              This allows the opmode code to print the result of this function to telemetry in case something goes wrong on shutdown, like this:

              Code:
              telemetry.addData("Stop", mechanism.stopRobot());
              telemetry.update();
              sleep(5000);  // To allow time for reading the telemetry.
              To log data from an opmode is like this:

              Code:
              mechanism.logCsvString(var1 + ", " + var2 + ", " + var3);
              If you bring up a file explorer in Windows with the Robot Controller connected, you should be able to navigate to the USB device that is like an external USB drive for the PC. Inside there, you should find a FIRST folder, and inside there a data folder, and insider there you should have a "robot-data.csv" file.

              Comment


              • #8
                edholder Yeah, because of the way the MTP protocol works, changes to files on the device might not show up on the computer, potentially until the device is restarted. The Robot Controller app does have some code to try to help mitigate this, but that doesn't mean you won't have any issues.

                The Device File Explorer in Android Studio is a more reliable way to access files on the device.

                Comment


                • #9
                  Originally posted by 4634 Programmer View Post
                  My guess is you're not passing the correct path to the FileWriter. For instance, if you pass "/FIRST/data/mylog.txt" it will fail. Try the following:


                  String logFilePath = String.format("%s/FIRST/data/mylog.txt", Environment.getExternalStorageDirectory().getAbsolutePath());
                  Is the path required different on the Control Hub? I've kept some code that Bob Atkinson had in a previous SDK that has -

                  private DebugFile capture = new DebugFile("/sdcard/FIRST/John.rtf");

                  in the opmode. That path is used in the FileWriter create a file line in his DebugFile class.
                  I just tried his code on a phone and it works, I don't have a Control hub to test with, they're all out with students.

                  Comment


                  • #10
                    Originally posted by 3805Mentor View Post

                    Is the path required different on the Control Hub? I've kept some code that Bob Atkinson had in a previous SDK that has -

                    private DebugFile capture = new DebugFile("/sdcard/FIRST/John.rtf");

                    in the opmode. That path is used in the FileWriter create a file line in his DebugFile class.
                    I just tried his code on a phone and it works, I don't have a Control hub to test with, they're all out with students.
                    Hardcoding "/sdcard/FIRST" will work fine. It's not the "proper" way to do things, but it works just fine.

                    Comment


                    • #11
                      Originally posted by 4634 Programmer View Post

                      Hardcoding "/sdcard/FIRST" will work fine. It's not the "proper" way to do things, but it works just fine.
                      Perhaps an SDK class, akin to RobotLog, is needed, say "OpModeLog". OpModeLog creates and manages OpMode specific log file(s) in a designated folder of the underlying platform, and ensures that logging is performed in a non-blocking manner.
                      ULTIMATE GOAL robot reveal coming soon to https://www.facebook.com/groups/ninejabots

                      Comment

                      Working...
                      X