139a5b6494
PiperOrigin-RevId: 838701951 Change-Id: I339eafd35d919710cb47bb04e9a8e29f92739513
95 lines
3.3 KiB
C++
95 lines
3.3 KiB
C++
// Copyright 2025 DeepMind Technologies Limited
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
#ifndef MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_HISTORY_H_
|
|
#define MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_HISTORY_H_
|
|
|
|
#include <span>
|
|
#include <vector>
|
|
#include <mujoco/mujoco.h>
|
|
|
|
namespace mujoco::platform {
|
|
|
|
// A historical buffer of simulation data.
|
|
class SimHistory {
|
|
public:
|
|
SimHistory() = default;
|
|
|
|
// Simulation data is stored a an array of mjtNum; see mj_getState().
|
|
using State = std::vector<mjtNum>;
|
|
|
|
// Clears and initializes the history buffer to store state.
|
|
void Init(int state_size, int max_history = 2000, int max_bytes = 1e8);
|
|
|
|
// Adds an uninitialized state to the history and returns a reference to it
|
|
// so that the caller can populate the data. Also resets the current index to
|
|
// 0; see SetIndex() for details.
|
|
std::span<mjtNum> AddToHistory();
|
|
|
|
// Returns the history at the given index (i.e. the number of steps) in the
|
|
// past. The `offset` will be clamped internally to the range [0, Size() - 1].
|
|
// This function returns the valid, clamped value.
|
|
//
|
|
// For example, calling SetIndex(0) will return the most recently recorded
|
|
// state. Calling SetIndex(-N) will return the state from N steps ago.
|
|
//
|
|
// Note that future calls to `AddToHistory` will begin recording from the
|
|
// newly set index, effectively creating a new "branch" of the history buffer.
|
|
// If you do not want to lose any states, you must call `SetIndex(0)` before
|
|
// before resuming playback.
|
|
//
|
|
// For example, consider you have recorded 6 states:
|
|
// N(-5) N(-4) N(-3) N(-2) N(-1) N(0)
|
|
// -----------------------------------------^
|
|
//
|
|
// You then call `SetIndex(-3)`:
|
|
// N(-5) N(-4) N(-3) N(-2) N(-1) N(0)
|
|
// ------------------^
|
|
//
|
|
// And then call `AddToHistory()
|
|
// N(-5) N(-4) N(-3) N(-2) N(-1) N(0)
|
|
// | | | x x x
|
|
// v v v
|
|
// N'(-3) N'(-2) N'(-1) N'(0)
|
|
// -------------------------^
|
|
//
|
|
// In this case, we effectively erase states 0 to -3 of the previous history,
|
|
// "copy" the older states into the new branch, and add the most recent state
|
|
// at the "head" of the history buffer.
|
|
std::span<mjtNum> SetIndex(int offset);
|
|
|
|
// Returns the currently set index.
|
|
int GetIndex() const { return offset_; }
|
|
|
|
// Returns the number of states in the history buffer.
|
|
int Size() const { return size_; }
|
|
|
|
private:
|
|
// The history of states.
|
|
std::vector<State> history_;
|
|
|
|
// The index at which the next AddToHistory() call will write.
|
|
int cursor_ = 0;
|
|
|
|
// The most recently requested offset from SetIndex().
|
|
int offset_ = 0;
|
|
|
|
// The total number of states available in the history buffer.
|
|
int size_ = 0;
|
|
};
|
|
|
|
} // namespace mujoco::platform
|
|
|
|
#endif // MUJOCO_SRC_EXPERIMENTAL_PLATFORM_SIM_HISTORY_H_
|