## For instruction on writing tutorials
## http://www.ros.org/wiki/WritingTutorials
####################################
##FILL ME IN
####################################
## for a custom note with links:
## note =
## for the canned note of "This tutorial assumes that you have completed the previous tutorials:" just add the links
## note.0=[[ensenso_driver/Tutorials/FirstSteps|First Steps]]
## descriptive title for the tutorial
## title = Setting Parameters
## multi-line description to be displayed in search
## description = This tutorial shows how to set camera parameters.
## the next tutorial description (optional)
## next =
## links to next tutorial (optional)
## next.0.link=
## next.1.link=
## what level user is this tutorial for
## level= BeginnerCategory
## keywords =
####################################
<<IncludeCSTemplate(TutorialCSHeaderTemplate)>>

<<TableOfContents(4)>>

== Loading Parameters from a JSON File ==
The easiest way to change the settings of a camera is to import them from a JSON file. You can use !NxView to experiment with different settings and see how they change the 3D data. Once everything is set up for your application, you can export the settings from !NxView with the menu entry `File` → `Export Parameters`.

You can import the resulting JSON file in a ROS [[ensenso_driver/Nodes/ensenso_camera_node#Parameters|camera node]] by using the node's `settings` parameter.

== Reading and Writing Parameters ==
You can read and write specific parameters with the `get_parameter` (<<ActionLink(ensenso_camera_msgs/GetParameter)>>) and `set_parameter` (<<ActionLink(ensenso_camera_msgs/SetParameter)>>) actions.

See the definition of <<MsgLink(ensenso_camera_msgs/Parameter)>> for a list of available parameters. Most of them directly map to a node in the !NxLib. Please refer to the [[https://www.ensenso.com/manual/tree/cameras/stereoserial.html|Ensenso SDK manual]] for more information on what these parameters do. Additionally, we have the following parameters that are specific to the ROS package:

 * `REGION_OF_INTEREST`: A 3D region of interest. Every point cloud that leaves the camera node is filtered and will only contain points that are inside of this region. To disable the filtering, set it to an empty region (where the minimum and maximum coordinates are the same).

 Note that this parameter does not affect the stereo matching settings in the !NxLib. It only gets applied in the ROS node and is meant as a simple way to crop the data in an axis-aligned box. You should still set the matching volume / disparity settings correctly to save computation time and reduce ambiguous matches.
 * `FLEX_VIEW`: The !FlexView node in the !NxLib can have different types, depending on whether the camera supports !FlexView and whether it is currently enabled. To make the behavior of this parameter consistent with the other ones, it will always be treated as an integer.<<BR>>When reading the parameter, a value of -1 means that !FlexView is not supported, 0 means that it is disabled and any other number is the number of images that will be captured. When writing the parameter, any number smaller than 2 disables !FlexView and any other number sets the corresponding number of images.

== Example: Reading and Writing the Camera's Exposure ==

As an example, the following Python snippets allow you to read and change the camera's exposure. Note that for clarity, we don't include all imports and error handling. See the [[actionlib_tutorials/Tutorials/Writing a Simple Action Client (Python)|actionlib tutorials]] for more information on using the `actionlib` Python API.

We first define two clients for the `get_parameter` and `set_parameter` actions.

{{{#!python
from ensenso_camera_msgs.msg import GetParameterAction, GetParameterGoal
from ensenso_camera_msgs.msg import SetParameterAction, SetParameterGoal
from ensenso_camera_msgs.msg import Parameter

get_parameter = actionlib.SimpleActionClient("get_parameter", GetParameterAction)
set_parameter = actionlib.SimpleActionClient("set_parameter", SetParameterAction)
}}}

We can now use this client to query the current exposure value of the camera.

{{{#!python
get_parameter.send_goal(GetParameterGoal(keys=[Parameter.EXPOSURE]))
# Wait for the action to finish, check for errors...
exposure = get_parameter.get_result().results[0].float_value
}}}

We can also turn off the auto exposure (which the !NxLib turns on by default) and set our own exposure value.

{{{#!python
set_parameter.send_goal(SetParameterGoal(parameters=[
    Parameter(key=Parameter.AUTO_EXPOSURE, bool_value=False),
    Parameter(key=Parameter.EXPOSURE, float_value=10) # New exposure in ms.
]))
# Wait for the action to finish, check for errors...
}}}

== Parameter Sets ==
The camera node can manage multiple sets of parameters. This feature can be useful if you have different locations at which you want to capture images with completely different settings.

Whenever you use a parameter set that is not known yet, it will be initialized by copying the last unchanged parameter set. That is, the camera's default parameters after opening it or the parameters that were loaded from a JSON file when the node started.

{{{#!python
# Add a new parameter set "location1". It will be initialized with the default
# settings from when the camera node started. We then change the exposure settings.
set_parameter.send_goal(SetParameterGoal(parameter_set="location1", parameters=[
    Parameter(key=Parameter.AUTO_EXPOSURE, bool_value=False),
    Parameter(key=Parameter.EXPOSURE, float_value=10)
]))
# Wait for the action to finish, check for errors...

# Add a new parameter set "location2". It will be initialized with the default
# settings from when the camera node started and load all parameters that were saved
# to a JSON file (e.g. by exporting the settings from NxView).
set_parameter.send_goal(SetParameterGoal(parameter_set="location2",
    parameter_file="settings_location2.json"))
# Wait for the action to finish, check for errors...
}}}

Every action that captures images takes the name of a parameter set as an argument. This parameter set will then be loaded before the images are captured. When the given name is empty, the action will use the parameter set `default` instead.

{{{#!python
from ensenso_camera_msgs.msg import RequestDataAction, RequestDataGoal
request_data = actionlib.SimpleActionClient("request_data", RequestDataAction)

# This request will publish a point cloud captured with the default settings
# that were loaded after starting the camera node (unless you changed parameters
# in the default parameter set afterwards).
request_data.send_goal(RequestDataGoal())

# This request will use the changed exposure settings from the "location1"
# parameter set.
request_data.send_goal(RequestDataGoal(parameter_set="location1"))

# This request will use the settings from the JSON parameter file that was
# loaded into the "location2" parameter set.
request_data.send_goal(RequestDataGoal(parameter_set="location2"))
}}}

== Projector and Front Light ==
In order to simplify the usage of the camera node for the most common applications, the node can automatically enable and disable projector and front light depending on the action that currently gets executed. When you request data, the projector is automatically turned on when the disparity map should be computed. In all other cases (e.g. when collecting calibration pattern), the projector is turned off and the front light is turned on.

You can disable this behavior for the current parameter set by explicitly setting either the projector or the front light parameter.

## AUTOGENERATED DO NOT DELETE
## TutorialCategory
## FILL IN THE STACK TUTORIAL CATEGORY HERE