generated from wessel/boilerplate
119 lines
3.7 KiB
Markdown
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) |