diff --git a/gen/Filesystem.yml b/gen/Filesystem.yml index bc2757c1..97d89872 100644 --- a/gen/Filesystem.yml +++ b/gen/Filesystem.yml @@ -1,6 +1,9 @@ --- functions: - GetLaunchDirectory: GetOperatingDirectory: GetDeployDirectory: + GetOperatingDirectoryFs: + ignore: true + GetDeployDirectoryFs: + ignore: true diff --git a/pyproject.toml b/pyproject.toml index 2b824335..69ec4425 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,7 @@ extension = "_wpilib" sources = [ "wpilib/src/main.cpp", "wpilib/src/rpy/ControlWord.cpp", + "wpilib/src/rpy/Filesystem.cpp", "wpilib/src/rpy/Notifier.cpp", "wpilib/src/rpy/SmartDashboardData.cpp", "wpilib/src/rpy/MotorControllerGroup.cpp", @@ -91,6 +92,7 @@ DutyCycleEncoder = "frc/DutyCycleEncoder.h" Encoder = "frc/Encoder.h" Errors = "frc/Errors.h" # Filesystem = "frc/Filesystem.h" +Filesystem = "rpy/Filesystem.h" # GenericHID = "frc/GenericHID.h" # interfaces I2C = "frc/I2C.h" IterativeRobotBase = "frc/IterativeRobotBase.h" diff --git a/wpilib/__init__.py b/wpilib/__init__.py index cfc2f8d0..7651296f 100644 --- a/wpilib/__init__.py +++ b/wpilib/__init__.py @@ -99,7 +99,9 @@ Watchdog, XboxController, getCurrentThreadPriority, + getDeployDirectory, getErrorMessage, + getOperatingDirectory, getTime, setCurrentThreadPriority, wait, @@ -200,7 +202,9 @@ "Watchdog", "XboxController", "getCurrentThreadPriority", + "getDeployDirectory", "getErrorMessage", + "getOperatingDirectory", "getTime", "setCurrentThreadPriority", "wait", diff --git a/wpilib/deployinfo.py b/wpilib/deployinfo.py index 3eed3bb9..e510a92a 100644 --- a/wpilib/deployinfo.py +++ b/wpilib/deployinfo.py @@ -23,7 +23,7 @@ def getDeployData() -> typing.Optional[typing.Dict[str, str]]: :returns: None in simulation, or a dictionary """ - if RobotBase.isReal(): + if not RobotBase.isReal(): return None try: diff --git a/wpilib/src/rpy/Filesystem.h b/wpilib/src/rpy/Filesystem.h new file mode 100644 index 00000000..3859d136 --- /dev/null +++ b/wpilib/src/rpy/Filesystem.h @@ -0,0 +1,33 @@ + +#pragma once + +#include + +namespace robotpy::filesystem { + +/** + * Obtains the operating directory of the program. On the roboRIO, this + * is /home/lvuser/py. In simulation, it is the location of robot.py + * + * @return The result of the operating directory lookup. + */ +std::string GetOperatingDirectory(); + +/** + * Obtains the deploy directory of the program, which is the remote location + * the deploy directory is deployed to by default. On the roboRIO, this is + * /home/lvuser/py/deploy. In simulation, it is where the simulation was launched + * from, in the subdirectory "deploy" (`dirname(robot.py)`/deploy). + * + * @return The result of the operating directory lookup + */ +std::string GetDeployDirectory(); + +// intended to be used by C++ bindings, returns same as GetOperatingDirectory +fs::path GetOperatingDirectoryFs(); +// intended to be used by C++ bindings, returns same as GetDeployDirectory +fs::path GetDeployDirectoryFs(); + +} // namespace robotpy::filesystem + +#include "Filesystem.inc" diff --git a/wpilib/src/rpy/Filesystem.inc b/wpilib/src/rpy/Filesystem.inc new file mode 100644 index 00000000..ae5d9ac1 --- /dev/null +++ b/wpilib/src/rpy/Filesystem.inc @@ -0,0 +1,45 @@ + +// TODO: this should be in a shared library, but robotpy-build does not support that + +#include +#include + +namespace robotpy::filesystem { + +static fs::path getMainPath() { + py::gil_scoped_acquire gil; + py::dict locals; + py::exec(R"( + import sys, os.path + main = sys.modules['__main__']; + if hasattr(main, '__file__'): + main_path = os.path.abspath(os.path.dirname(main.__file__)) + + )", + py::globals(), locals); + + if (locals.contains("main_path")) { + return fs::path(py::cast(locals["main_path"])); + } else { +#ifdef __FRC_ROBORIO__ + return fs::path("/home/lvuser/py"); +#else + return fs::current_path(); +#endif + } +} + +inline std::string GetOperatingDirectory() { + return GetOperatingDirectoryFs().string(); +} + +inline std::string GetDeployDirectory() { return GetDeployDirectoryFs().string(); } + +inline fs::path GetOperatingDirectoryFs() { + static fs::path operatingPath = getMainPath(); + return operatingPath; +} + +inline fs::path GetDeployDirectoryFs() { return GetOperatingDirectoryFs() / "deploy"; } + +} // namespace robotpy::filesystem \ No newline at end of file