# Параметры

## Оглавление

1. [Что такое параметры в ROS2](#что-такое-параметры-в-ros2)
2. [Типы параметров](#типы-параметров)
3. [Объявление параметров](#объявление-параметров)
4. [Чтение параметров](#чтение-параметров)
5. [Установка параметров](#установка-параметров)
6. [Параметры из командной строки](#параметры-из-командной-строки)
7. [Параметры из YAML-файла](#параметры-из-yaml-файла)
8. [Мониторинг изменений параметров](#мониторинг-изменений-параметров)
9. [Сервисы параметров](#сервисы-параметров)
10. [Лучшие практики](#лучшие-практики)

***

## Что такое параметры в ROS2

Параметры - это конфигурационные значения (переменные), которые могут быть установлены во время запуска узла или изменены во время его работы. Они позволяют настраивать поведение узла без изменения кода.

Преимущества:

* Динамическая настройка узлов
* Возможность изменения во время выполнения
* Поддержка различных типов данных
* Интеграция с инструментами ROS2 (rqt, CLI)

***

## Типы параметров

ROS2 поддерживает следующие типы параметров:

* `bool` - логическое значение (True/False)
* `int` - целое число (64-bit)
* `float` - число с плавающей точкой (64-bit)
* `str` - строка
* `byte[]` - массив байтов
* `bool[]` - массив булевых значений
* `int[]` - массив целых чисел
* `float[]` - массив чисел с плавающей точкой
* `str[]` - массив строк

Параметру присваивается тип заданного значения по умолчанию.

***

## Объявление параметров

```python
from rclpy.node import Node

class MyNode(Node):
    def __init__(self):
        super().__init__('my_node')
        
        # Объявление параметров с значениями по умолчанию
        self.declare_parameter('my_int_param', 42)
        self.declare_parameter('my_double_param', 3.14)
        self.declare_parameter('my_string_param', 'hello')
        self.declare_parameter('my_bool_param', True)
        self.declare_parameter('my_array_param', [1, 2, 3])
        
        # Объявление параметра без значения по умолчанию
        self.declare_parameter('required_param')
```

**Параметру присваивается тип значения по умолчанию.** В ROS 2 (rclpy), когда вы объявляете параметр без значения по умолчанию, как в примере:

```python
self.declare_parameter('required_param')
```

Тип параметра будет определяться динамически в момент, когда параметру будет присвоено значение. До этого момента параметр будет иметь специальный тип `Parameter.Type.NOT_SET`.

Если вы хотите явно указать тип параметра (например, для проверки), вы можете использовать параметр `ParameterDescriptor` при объявлении:

```python
from rcl_interfaces.msg import ParameterDescriptor, ParameterType

# Объявление параметра с указанием типа
desc = ParameterDescriptor(type=ParameterType.PARAMETER_STRING)
self.declare_parameter('required_param', descriptor=desc)
```

В этом случае, если параметру будет присвоено значение несоответствующего типа, возникнет ошибка.

Основные типы параметров в ROS2:

* `ParameterType.PARAMETER_NOT_SET` (по умолчанию для параметров без значения)
* `ParameterType.PARAMETER_BOOL`
* `ParameterType.PARAMETER_INTEGER`
* `ParameterType.PARAMETER_DOUBLE`
* `ParameterType.PARAMETER_STRING`
* `ParameterType.PARAMETER_BYTE_ARRAY`
* `ParameterType.PARAMETER_BOOL_ARRAY`
* `ParameterType.PARAMETER_INTEGER_ARRAY`
* `ParameterType.PARAMETER_DOUBLE_ARRAY`
* `ParameterType.PARAMETER_STRING_ARRAY`

***

## Чтение параметров в коде

```python
# Получение параметра с проверкой существования
my_int = self.get_parameter('my_int_param').value

# Безопасное получение параметра с указанием типа
my_double = self.get_parameter('my_double_param').get_parameter_value().double_value

# Чтение с проверкой и значением по умолчанию
try:
    required_param = self.get_parameter('required_param').value
except ParameterNotDeclaredException:
    self.get_logger().error('Required parameter not set!')
    raise

# Получение всех параметров
all_params = self.get_parameters(['my_int_param', 'my_string_param'])
```

***

## Установка (изменение) параметров в коде

```python
# Установка одного параметра
self.set_parameters([Parameter('my_int_param', Parameter.Type.INTEGER, 100)])

# Установка нескольких параметров
params = [
    Parameter('my_int_param', Parameter.Type.INTEGER, 100),
    Parameter('my_string_param', Parameter.Type.STRING, 'new_value'),
    Parameter('my_bool_param', Parameter.Type.BOOL, False)
]
self.set_parameters(params)
```

Или с проверкой успешности:

```python
success = self.set_parameters([rclpy.Parameter('my_int_param', 100)])
if success:
    self.get_logger().info("Parameter updated successfully")
else:
    self.get_logger().warn("Failed to update parameter")
```

#### **Изменение параметра из другой ноды**

Можно получить клиент параметров и изменить параметры удалённой ноды:

```python
from rclpy.parameter import Parameter

class AnotherNode(Node):
    def __init__(self):
        super().__init__('another_node')
        self.client = self.create_client(AsyncParametersClient, '/my_node')
    
    async def update_param(self):
        await self.client.wait_for_service()
        param = Parameter('my_int_param', Parameter.Type.INTEGER, 100)
        await self.client.set_parameters([param])
```

***

## Установка (изменение) параметров из командной строки

При запуске узла можно передавать параметры:

```bash
ros2 run my_package my_node --ros-args -p my_int_param:=100 -p my_string_param:="new_value"
```

В коде можно проверить, был ли параметр установлен из командной строки:

```python
if self.has_parameter('my_int_param'):
    self.get_logger().info('Parameter was set from command line')
```

После запуска узла:

```bash
ros2 param set /node_name parameter_name new_value
```

**Пример:**

```bash
ros2 param set /my_node my_int_param 100
```

Через `ros2 service call` (используя сервис `set_parameters`) Можно вручную вызвать сервис изменения параметров:

```bash
ros2 service call /my_node/set_parameters rcl_interfaces/srv/SetParameters "parameters:
- name: 'my_int_param'
  value:
    type: 2  # INTEGER (см. rcl_interfaces/msg/ParameterType)
    integer_value: 100"
```

***

## Параметры из YAML-файла

1. Создайте файл конфигурации `config.yaml`:

```yaml
my_node:
  ros__parameters:
    my_int_param: 100
    my_string_param: "from_yaml"
    my_array_param: [4, 5, 6]
```

2. Запустите узел с конфигурационным файлом:

```bash
ros2 run my_package my_node --ros-args --params-file config.yaml
```

***

## Мониторинг изменений параметров

```python
from rclpy.parameter import Parameter

# Колбек для отслеживания изменений параметров
def parameters_callback(params):
    for param in params:
        self.get_logger().info(f"Parameter {param.name} changed to {param.value}")
    return SetParametersResult(successful=True)

# Установка обработчика
self.add_on_set_parameters_callback(self.parameters_callback)
```

***

## Сервисы параметров

ROS2 предоставляет сервисы для работы с параметрами:

* `list_parameters` - список всех параметров
* `get_parameters` - получить значения параметров
* `set_parameters` - установить значения параметров
* `describe_parameters` - получить описание параметров

Пример использования:

```python
from rcl_interfaces.srv import GetParameters
import rclpy

# Создание клиента
cli = self.create_client(GetParameters, '/my_node/get_parameters')

# Подготовка запроса
request = GetParameters.Request()
request.names = ['my_int_param', 'my_string_param']

# Отправка запроса
future = cli.call_async(request)
rclpy.spin_until_future_complete(self, future)

# Обработка ответа
if future.result() is not None:
    self.get_logger().info(f"Result: {future.result().values}")
else:
    self.get_logger().error('Service call failed')
```

***

## Лучшие практики

1. Всегда устанавливайте значения по умолчанию для параметров
2. Проверяйте типы параметров при чтении
3. Используйте YAML-файлы для сложных конфигураций
4. Ограничьте динамическое изменение критических параметров
5. Документируйте параметры вашего узла
6. Используйте пространства имен для параметров в больших проектах
7. Рассмотрите возможность использования динамически переконфигурируемых параметров для частых изменений

Пример документации параметров в коде:

```python
"""
Parameters:
    my_int_param (int): Description of integer parameter. Default: 42
    my_string_param (str): Description of string parameter. Default: "hello"
    my_array_param (List[float]): Description of array parameter. Default: [1.0, 2.0, 3.0]
"""
```

***

Эта шпаргалка покрывает основные аспекты работы с параметрами в ROS2 на Python. Для более глубокого изучения обратитесь к официальной документации ROS2.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://alice-and-alex-docs.gitbook.io/alice_and_alex_docs/ros2-development/parametry.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
