diff --git a/include/franka/model.h b/include/franka/model.h index 3f23f7a4..6aa01bca 100644 --- a/include/franka/model.h +++ b/include/franka/model.h @@ -63,6 +63,20 @@ class Model { */ explicit Model(franka::Network& network); + /** + * Creates a new Model instance. + * + * This constructor is for internal use only. + * + * @see Robot::loadModel + * + * @param[in] pathToLib file path to load model library from (instead of downloading from the robot) + * + * @throw ModelException if the model library cannot be loaded. + */ + explicit Model(const std::string& pathToLib); + + /** * Move-constructs a new Model instance. * diff --git a/include/franka/robot.h b/include/franka/robot.h index e80f8058..ff37e635 100644 --- a/include/franka/robot.h +++ b/include/franka/robot.h @@ -663,6 +663,12 @@ class Robot { class Impl; + /** + * Save the dynamics model library from the robot for offline use to the given path + * + */ + void downloadModelLibrary(const std::string& toFile); + private: std::unique_ptr impl_; std::mutex control_mutex_; diff --git a/src/model.cpp b/src/model.cpp index bd019115..023c4683 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -22,6 +22,7 @@ Frame operator++(Frame& frame, int /* dummy */) noexcept { } Model::Model(Network& network) : library_{new ModelLibrary(network)} {} +Model::Model(const std::string& pathToLib) : library_{new ModelLibrary(pathToLib)} {} // Has to be declared here, as the ModelLibrary type is incomplete in the header Model::~Model() noexcept = default; diff --git a/src/model_library.cpp b/src/model_library.cpp index 8fd08080..bf6269ca 100644 --- a/src/model_library.cpp +++ b/src/model_library.cpp @@ -7,7 +7,10 @@ namespace franka { ModelLibrary::ModelLibrary(franka::Network& network) - : loader_(LibraryDownloader(network).path()), + : ModelLibrary(LibraryDownloader(network).path()) {} + +ModelLibrary::ModelLibrary(const std::string& cachepath) + : loader_(cachepath), body_jacobian_joint1{reinterpret_cast(loader_.getSymbol("Ji_J_J1"))}, body_jacobian_joint2{reinterpret_cast(loader_.getSymbol("Ji_J_J2"))}, body_jacobian_joint3{reinterpret_cast(loader_.getSymbol("Ji_J_J3"))}, diff --git a/src/model_library.h b/src/model_library.h index a1df1a72..5f3f8a60 100644 --- a/src/model_library.h +++ b/src/model_library.h @@ -13,6 +13,7 @@ namespace franka { class ModelLibrary { public: ModelLibrary(Network& network); + ModelLibrary(const std::string& cachepath); private: LibraryLoader loader_; diff --git a/src/robot.cpp b/src/robot.cpp index 36a4e989..b1b292c4 100644 --- a/src/robot.cpp +++ b/src/robot.cpp @@ -3,10 +3,12 @@ #include #include +#include #include "control_loop.h" #include "network.h" #include "robot_impl.h" +#include "library_downloader.h" namespace franka { @@ -306,4 +308,11 @@ Model Robot::loadModel() { return impl_->loadModel(); } +void Robot::downloadModelLibrary(const std::string& toFile) { + std::ofstream dst(toFile, std::ios::binary); + LibraryDownloader downloaderObj(*(impl_->network_)); + std::ifstream src(downloaderObj.path(), std::ios::binary); + dst << src.rdbuf(); +} + } // namespace franka diff --git a/src/robot_impl.h b/src/robot_impl.h index 3a6bed98..83868f1b 100644 --- a/src/robot_impl.h +++ b/src/robot_impl.h @@ -51,6 +51,8 @@ class Robot::Impl : public RobotControl { Model loadModel() const; + std::unique_ptr network_; + protected: bool motionGeneratorRunning() const noexcept; bool controllerRunning() const noexcept; @@ -73,7 +75,6 @@ class Robot::Impl : public RobotControl { research_interface::robot::RobotState receiveRobotState(); void updateState(const research_interface::robot::RobotState& robot_state); - std::unique_ptr network_; Logger logger_;