public override void setf_command(double command)
        {
            if (command < MIN_POSITION || command > MAX_POSITION)
            {
                throw new ArgumentException($"Command must be between {MIN_POSITION} and {MAX_POSITION}");
            }

            ros_csharp_interop.rosmsg.ROSTime t;
            lock (this)
            {
                t = _now_ros();
            }

            var cmd1 = new IOComponentCommand();

            cmd1.time = t;
            cmd1.op   = "set";
            cmd1.args = "{\"signals\": {\"position_m\": {\"data\": [" + command.ToString() + "], \"format\": {\"type\": \"float\"}}}}";

            _gripper_command_pub.publish(cmd1);

            lock (this)
            {
                _command = command;
            }
        }
        public override void home()
        {
            ros_csharp_interop.rosmsg.ROSTime t;
            lock (this)
            {
                t = _now_ros();
            }
            var cmd1 = new IOComponentCommand();

            cmd1.time = t;
            cmd1.op   = "set";
            cmd1.args = "{\"signals\": {\"calibrate\": {\"data\": [true], \"format\": {\"type\": \"bool\" }}}}";
            _gripper_command_pub.publish(cmd1);

            Thread.Sleep(2500);
        }
        public override void open()
        {
            ros_csharp_interop.rosmsg.ROSTime t;
            lock (this)
            {
                t = _now_ros();
            }

            var cmd1 = new IOComponentCommand();

            cmd1.time = t;
            cmd1.op   = "set";
            cmd1.args = "{\"signals\": {\"cmd_grip\": {\"data\": [false], \"format\": {\"type\": \"bool\"}}}}";

            _gripper_command_pub.publish(cmd1);

            lock (this)
            {
                _command = 0;
            }
        }