-
-
Save julenka/20ece5141e821cb6d0a9cb530d3dc96d to your computer and use it in GitHub Desktop.
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Text; | |
using System.Threading.Tasks; | |
using UnityEngine; | |
#if WINDOWS_UWP | |
using Windows.Storage; | |
#endif | |
namespace holoutils | |
{ | |
/// <summary> | |
/// Component that Logs data to a CSV. | |
/// Assumes header is fixed. | |
/// Copy and paste this logger to create your own CSV logger. | |
/// CSV Logger breaks data up into settions (starts when application starts) which are folders | |
/// and instances which are files | |
/// A session starts when the application starts, it ends when the session ends. | |
/// | |
/// In Editor, writes to MyDocuments/SessionFolderRoot folder | |
/// On Device, saves data in the Pictures/SessionFolderRoot | |
/// | |
/// How to use: | |
/// Find the csvlogger | |
/// if it has not started a CSV, create one. | |
/// every frame, log stuff | |
/// Flush data regularly | |
/// | |
/// **Important: Requires the PicturesLibrary capability!** | |
/// </summary> | |
public class CSVLogger : MonoBehaviour | |
{ | |
#region Constants to modify | |
private const string DataSuffix = "data"; | |
private const string CSVHeader = "Timestamp,SessionID,RecordingID," + | |
"blah,blah,blah"; | |
private const string SessionFolderRoot = "CSVLogger"; | |
#endregion | |
#region private members | |
private string m_sessionPath; | |
private string m_filePath; | |
private string m_recordingId; | |
private string m_sessionId; | |
private StringBuilder m_csvData; | |
#endregion | |
#region public members | |
public string RecordingInstance => m_recordingId; | |
#endregion | |
// Use this for initialization | |
async void Start() | |
{ | |
await MakeNewSession(); | |
} | |
async Task MakeNewSession() | |
{ | |
m_sessionId = DateTime.Now.ToString("yyyyMMdd_HHmmss"); | |
string rootPath = ""; | |
#if WINDOWS_UWP | |
StorageFolder sessionParentFolder = await KnownFolders.PicturesLibrary | |
.CreateFolderAsync(SessionFolderRoot, | |
CreationCollisionOption.OpenIfExists); | |
rootPath = sessionParentFolder.Path; | |
#else | |
rootPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), SessionFolderRoot); | |
if (!Directory.Exists(rootPath)) Directory.CreateDirectory(rootPath); | |
#endif | |
m_sessionPath = Path.Combine(rootPath, m_sessionId); | |
Directory.CreateDirectory(m_sessionPath); | |
Debug.Log("CSVLogger logging data to " + m_sessionPath); | |
} | |
public void StartNewCSV() | |
{ | |
m_recordingId = DateTime.Now.ToString("yyyyMMdd_HHmmssfff"); | |
var filename = m_recordingId + "-" + DataSuffix + ".csv"; | |
m_filePath = Path.Combine(m_sessionPath, filename); | |
if (m_csvData != null) | |
{ | |
EndCSV(); | |
} | |
m_csvData = new StringBuilder(); | |
m_csvData.AppendLine(CSVHeader); | |
} | |
public void EndCSV() | |
{ | |
if (m_csvData == null) | |
{ | |
return; | |
} | |
using (var csvWriter = new StreamWriter(m_filePath, true)) | |
{ | |
csvWriter.Write(m_csvData.ToString()); | |
} | |
m_recordingId = null; | |
m_csvData = null; | |
} | |
public void OnDestroy() | |
{ | |
EndCSV(); | |
} | |
public void AddRow(List<String> rowData) | |
{ | |
AddRow(string.Join(",", rowData.ToArray())); | |
} | |
public void AddRow(string row) | |
{ | |
m_csvData.AppendLine(row); | |
} | |
/// <summary> | |
/// Writes all current data to current file | |
/// </summary> | |
public void FlushData() | |
{ | |
using (var csvWriter = new StreamWriter(m_filePath, true)) | |
{ | |
csvWriter.Write(m_csvData.ToString()); | |
} | |
m_csvData.Clear(); | |
} | |
/// <summary> | |
/// Returns a row populated with common start data like | |
/// recording id, session id, timestamp | |
/// </summary> | |
/// <returns></returns> | |
public List<String> RowWithStartData() | |
{ | |
List<String> rowData = new List<String>(); | |
rowData.Add(Time.timeSinceLevelLoad.ToString("##.000")); | |
rowData.Add(m_recordingId); | |
rowData.Add(m_recordingId); | |
return rowData; | |
} | |
} | |
} |
Hello, I was using your code for two projects without issues, but recently, the call to Directory.CreateDirectory(m_sessionPath)
on line 74 stopped working very similar to the above. I updated the MakeNewSession code to m_sessionId = DateTime.Now.ToString("yyyyMMdd_HHmmss"); string rootPath = ""; m_sessionPath = Path.Combine(SessionFolderRoot, m_sessionId); #if WINDOWS_UWP StorageFolder sessionParentFolder = await KnownFolders.PicturesLibrary .CreateFolderAsync(m_sessionPath, CreationCollisionOption.OpenIfExists); rootPath = sessionParentFolder.Path; UnityEngine.Debug.Log("Logger logging data to " + sessionParentFolder.Path); #endif
and it now seems to work. Maybe something changed in the .NET namespace?
Hello, thank you for the code it works well in unity but the data is quite delayed on the Hololens. At first, I didn't include FlushData() in the code, .csv file was created properly in the unity editor but it was not created on the Hololens. But right after I put FlushData(), I can see the file created in Hololens's picture folder but it makes the game and sensor data delayed more than I expected which is around 30sec from the normal 4sec (before adding flush). Do you have any suggestions or recommendations?
Thank you for the code. I have just one question, where should I call the StartNewCSV()
and FlushData()
functions? The code that you provided has a async void Start()
function which does not allow me to have my basic void start(){}
. I'm guessing I should use the FlushData()
in the Update()
function. right?
I think StartNewCSV(
) here is to create a CSV file with the unity editor. If you want to create a CSV file in the Hololens, you need to use the Windows.Storage
for UWP. Referring to https://learn.microsoft.com/en-us/windows/uwp/files/quickstart-reading-and-writing-files
For more file-accessing codes for UWP, I found this helpful:
https://github.com/Microsoft/Windows-universal-samples/tree/main/Samples/FileAccess
Hi, make sure you are also calling
MakeNewSession()
to make the folder andStartNewCSV()
to create a CSV. First verify that the CSV is being created when you are using the editor. The folder and file should go into my documents. If you have that and the PicturesLibrary capability set, then you should see a folder also being created in My Pictures.