Files
ros2-assignments/doc/architecture/classes/Simulator.md

119 lines
3.7 KiB
Markdown

# Simulator (`assignments::three::Simulator`)
The `Simulator` class provides a flexible time-based value generation engine that supports multiple interpolation types. It is used by both the IMU and Wheel data simulator nodes to generate configurable sensor data patterns.
## Implementation Details
**Namespace**: `assignments::three`
**Header**: `simulator/Simulator.hpp`
### Data Structures
**SimType Enum**
```cpp
enum class SimType {
CONSTANT, // y = c (constant value)
LINEAR, // y = y0 + (y1-y0) * (t-t0)/(t1-t0)
QUADRATIC // Lagrange interpolation through 3 points
};
```
**IntervalConfig Struct**
```cpp
struct IntervalConfig {
SimType type; // Interpolation type
double t_start; // Interval start time
double t_end; // Interval end time
double y_start; // Start value
double y_end; // End value
double t_mid; // Mid-point time (quadratic only)
double y_mid; // Mid-point value (quadratic only)
};
```
### Constructor
```cpp
Simulator(rclcpp::Node* node, const std::vector<std::string>& objects)
```
- Takes a ROS2 node pointer for parameter access
- Takes a list of object/channel names to configure
- Loads interval configurations from ROS2 parameters
- Validates intervals for overlaps (throws `std::runtime_error` if detected)
## Core Functionality
**`double get_object_value(const std::string& object, double t)`**
- Returns the simulated value for a given object at time `t`
- If `t` is within an interval, computes the interpolated value
- If `t` is after all intervals, holds the last interval's end value
- If `t` is before all intervals, returns 0.0
- If object doesn't exist, returns 0.0
**`double compute_value(double t, const IntervalConfig& interval)`** (private)
- Computes the interpolated value based on interval type:
- **CONSTANT**: Returns `y_start`
- **LINEAR**: Lagrange interpolation between 2 points
- **QUADRATIC**: Lagrange interpolation through 3 points
**`void load_intervals(rclcpp::Node* node, const std::vector<std::string>& objects)`** (private)
- Declares and loads parameters for each object
- Validates that intervals don't overlap
- Respects `max_intervals` limit
## Parameter Configuration
For each object, the following parameters are used:
| Parameter | Type | Description |
|-----------|------|-------------|
| `max_intervals` | int | Global maximum intervals per object |
| `<object>.num_intervals` | int | Number of intervals for this object |
| `<object>.interval_<n>.type` | string | "constant", "linear", or "quadratic" |
| `<object>.interval_<n>.t_start` | double | Interval start time |
| `<object>.interval_<n>.t_end` | double | Interval end time |
| `<object>.interval_<n>.y_start` | double | Value at start |
| `<object>.interval_<n>.y_end` | double | Value at end |
| `<object>.interval_<n>.t_mid` | double | Mid-point time (quadratic) |
| `<object>.interval_<n>.y_mid` | double | Mid-point value (quadratic) |
## Example Configuration
```yaml
# Constant acceleration of 5.0 m/s² from t=0 to t=10
linear_x:
num_intervals: 1
interval_0:
type: "constant"
t_start: 0.0
t_end: 10.0
y_start: 5.0
# Linear ramp from 0 to 10 over 5 seconds
wheel_fl:
num_intervals: 1
interval_0:
type: "linear"
t_start: 0.0
t_end: 5.0
y_start: 0.0
y_end: 10.0
# Quadratic curve peaking at t=5
angular_z:
num_intervals: 1
interval_0:
type: "quadratic"
t_start: 0.0
t_end: 10.0
y_start: 0.0
y_end: 0.0
t_mid: 5.0
y_mid: 3.14
```
## Error Handling
- Throws `std::runtime_error` if overlapping intervals are detected for the same object
- Logs warning for unknown interval types, defaults to CONSTANT
- Returns 0.0 for non-existent objects (graceful degradation)