How to access the child nodes in a device tree (DTS) in Zephyr using DT_FOREACH_CHILD - nrf52

I'm developing an application for an nRF52 SoC to access some external devices, kind of detectors in this case, so I have defined a custom format (and its corresponding yaml file) for my device access description node. It is kind of:
n: detectors {
compatible = "foo-detectors";
// Definition of first channel
det0: det_0 {
irq-pins = <13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "Bar detector channel 1";
};
// Definition of second channel
det1: det_1 {
irq-pins = <17 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
label = "Bar detector channel 2";
};
};
Suppose I have a structure definition for holding data about the pins to which those devices are physically connected, say:
struct foo_detector_desc {
int irqpin;
int irqpin_flags;
}
Using Zephyr macros, I can use from my code the individual values for those nodes. For instance, DT_PROP_BY_IDX(DT_NODELABEL(det0), irq_pins, 0) expands to 13, DT_PROP_BY_IDX(DT_NODELABEL(det0), irq_pins, 1) expands to the value of OR'ed flags GPIO_PULL_UP | GPIO_ACTIVE_LOW.
But I don't want to create a ten-page code full of conditionals in the form DT_NODE_EXISTS(DT_ALIAS(det#)), but something more compact, flexible and maintainable.
I came across Zephyr macro DT_FOREACH_CHILD that is intended for being used in that scenario with which I can create a list with the labels, as showcased in the example embedded in the documentation:
#define LABEL_AND_COMMA(node_id) DT_LABEL(node_id),
const char *child_labels[] = {
DT_FOREACH_CHILD(DT_NODELABEL(n), LABEL_AND_COMMA)
};
Trying to use that for filling a static structures array, I tried following code but, yet it expands to two elements in the array, the structure fields are not initialised with desired values.
#define PIN_INFO_AND_COMMA(node_id) \
{ \
.pin=DT_PROP_BY_IDX(node_id, irq_pins, 0),\
.flags=DT_PROP_BY_IDX(node_id, irq_pins, 1),\
},
const struct detector_data _det_data[] = {
DT_FOREACH_CHILD(DT_NODELABEL(n), PIN_INFO_AND_COMMA)
};
I'm using Visual Studio Code with the nRF Connect plugin.
Is there a way to generate/see how those macros expand when compiled?
What is the correct way for initialising the structure fields (pins, flags)?
BR

It is possible to expand the macros one level at a time in VS Code. It is needed to click over the macro, then select it by double-clicking on it, and a bulb light will, eventually, show up. The option Insert Macro will replace the macro with its expansion.
Regarding using the DTS in code, the code I wrote in my previous post is OK, but I think I found a bug in the debugger. If I don't include any code using the value of _det_data, the debugger doesn't say the constant was optimised-out and displays wrong values when inspecting its content. That made me waste a lot of time.
For anyone interested on using DTS files for nRF devices in Zephyr, I posted all details in a thread in Nordic's developers forum (here).
BR

Related

Example third person controler in Unity / StringToHash

I am trying to learn game development through different ways and sources and recently I have created a project in unity with example ThirdPersonController.
While looking through the code I came across one thing which I am finding difficult to wrap my mind around. It is "StringToHash". What is the purpose of this? Here is an example of variable with specified values set:
private void AssignAnimationIDs()
{
_animIDSpeed = Animator.StringToHash("Speed");
_animIDGrounded = Animator.StringToHash("Grounded");
_animIDJump = Animator.StringToHash("Jump");
_animIDFreeFall = Animator.StringToHash("FreeFall");
_animIDMotionSpeed = Animator.StringToHash("MotionSpeed");
}
and here is an example when this is used when being called:
if (_hasAnimator)
{
_animator.SetFloat(_animIDSpeed, _animationBlend);
_animator.SetFloat(_animIDMotionSpeed, inputMagnitude);
}
Welcome to Stack overflow.
Similar question already has been asked HERE . Unity Docs .
In your code below you changing values (parameters) of your animator. To find which values it should change it must compare the name of the value you gave in .SetFloat to the ones it has (in "parameters" section on "animator" tab).
You could do
.SetFloat("speed", _animationBlend);
But to get that milliseconds of time advantage (optimization) your "speed" is converted to integers first (like in your code above) and then you use it.

VsCode Extension custom CompletionItem disables built-in Intellisense

I am working on a VsCode extension in that I want to provide custom snippets for code completion.
I know about the option of using snippet json files directly, however those have the limitation of not being able to utilize the CompletionItemKind property that determines the icon next to the completion suggestion in the pop-up.
My issue:
If I implement a simple CompletionItemProvider like this:
context.subscriptions.push(
vscode.languages.registerCompletionItemProvider(
{scheme:"file",language:"MyLang"},
{
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
let item = new vscode.CompletionItem('test');
item.documentation = 'my test function';
item.kind = vscode.CompletionItemKind.Function;
return [item];
}
}
)
)
then the original VsCode IntelliSense text suggestions are not shown anymore, only my own. Should I just return a kind of an empty response, like
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position) {
return [null|[]|undefined];
}
the suggestions appear again as they should. It seems to me that instead of merging the results of the built-in IntelliSense and my own provider, the built-in ones get simply overridden.
Question:
How can I keep the built-in IntelliSense suggestions while applying my own CompletionItems?
VsCode Version: v1.68.1 Ubuntu
I seem to have found the answer for my problem, so I will answer my question.
Multiple providers can be registered for a language. In that case providers are sorted
by their {#link languages.match score} and groups of equal score are sequentially asked for
completion items. The process stops when one or many providers of a group return a
result.
My provider seems to provide results that are just higher scored than those of IntelliSense.
Since I didn't provide any trigger characters, my CompletionItems were comteping directly with the words found by the built-in system by every single pressed key and won.My solution is to simply parse and register the words in my TextDocument myself and extend my provider results by them. I could probably just as well create and register a new CompletionItemProvider for them if I wanted to, however I decided to have a different structure for my project.

Stop huge error output from testing-library

I love testing-library, have used it a lot in a React project, and I'm trying to use it in an Angular project now - but I've always struggled with the enormous error output, including the HTML text of the render. Not only is this not usually helpful (I couldn't find an element, here's the HTML where it isn't); but it gets truncated, often before the interesting line if you're running in debug mode.
I simply added it as a library alongside the standard Angular Karma+Jasmine setup.
I'm sure you could say the components I'm testing are too large if the HTML output causes my console window to spool for ages, but I have a lot of integration tests in Protractor, and they are SO SLOW :(.
I would say the best solution would be to use the configure method and pass a custom function for getElementError which does what you want.
You can read about configuration here: https://testing-library.com/docs/dom-testing-library/api-configuration
An example of this might look like:
configure({
getElementError: (message: string, container) => {
const error = new Error(message);
error.name = 'TestingLibraryElementError';
error.stack = null;
return error;
},
});
You can then put this in any single test file or use Jest's setupFiles or setupFilesAfterEnv config options to have it run globally.
I am assuming you running jest with rtl in your project.
I personally wouldn't turn it off as it's there to help us, but everyone has a way so if you have your reasons, then fair enough.
1. If you want to disable errors for a specific test, you can mock the console.error.
it('disable error example', () => {
const errorObject = console.error; //store the state of the object
console.error = jest.fn(); // mock the object
// code
//assertion (expect)
console.error = errorObject; // assign it back so you can use it in the next test
});
2. If you want to silence it for all the test, you could use the jest --silent CLI option. Check the docs
The above might even disable the DOM printing that is done by rtl, I am not sure as I haven't tried this, but if you look at the docs I linked, it says
"Prevent tests from printing messages through the console."
Now you almost certainly have everything disabled except the DOM recommendations if the above doesn't work. On that case you might look into react-testing-library's source code and find out what is used for those print statements. Is it a console.log? is it a console.warn? When you got that, just mock it out like option 1 above.
UPDATE
After some digging, I found out that all testing-library DOM printing is built on prettyDOM();
While prettyDOM() can't be disabled you can limit the number of lines to 0, and that would just give you the error message and three dots ... below the message.
Here is an example printout, I messed around with:
TestingLibraryElementError: Unable to find an element with the text: Hello ther. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
...
All you need to do is to pass in an environment variable before executing your test suite, so for example with an npm script it would look like:
DEBUG_PRINT_LIMIT=0 npm run test
Here is the doc
UPDATE 2:
As per the OP's FR on github this can also be achieved without injecting in a global variable to limit the PrettyDOM line output (in case if it's used elsewhere). The getElementError config option need to be changed:
dom-testing-library/src/config.js
// called when getBy* queries fail. (message, container) => Error
getElementError(message, container) {
const error = new Error(
[message, prettyDOM(container)].filter(Boolean).join('\n\n'),
)
error.name = 'TestingLibraryElementError'
return error
},
The callstack can also be removed
You can change how the message is built by setting the DOM testing library message building function with config. In my Angular project I added this to test.js:
configure({
getElementError: (message: string, container) => {
const error = new Error(message);
error.name = 'TestingLibraryElementError';
error.stack = null;
return error;
},
});
This was answered here: https://github.com/testing-library/dom-testing-library/issues/773 by https://github.com/wyze.

How to connect ITK with VTK?

I'm reading DICOM series using itk and converting them into VTK for visualization purposes. Even though I manage to visualize DICOM series in 3 different windows with 3 different orientations (XY, XZ and YZ) I can't even click on the windows. When I click or try to change the slice viewed, my code gives an access violation error. I'm using ImageViewer2 to visualize the slices. A file called itkVTKImageExportBase.cxx is opened when I try to find out what the error is. The lines referred to are:
void VTKImageExportBase::UpdateInformationCallbackFunction(void* userData)
{
static_cast<VTKImageExportBase*>
(userData)->UpdateInformationCallback();
}
My code is as follows:
typedef itk::VTKImageExport< ImageType > ExportFilterType;
ExportFilterType::Pointer itkExporter = ExportFilterType::New();
itkExporter->SetInput( reader->GetOutput() );
// Create the vtkImageImport and connect it to the itk::VTKImageExport instance.
vtkImageImport* vtkImporter = vtkImageImport::New();
ConnectPipelines(itkExporter, vtkImporter);
pViewerXY->SetInput(vtkImporter->GetOutput());
pViewerXY->SetSlice(3);
pViewerXY->SetSliceOrientationToXY();
pViewerXY->SetupInteractor(m_pVTKWindow_1);
pViewerXY->UpdateDisplayExtent();
m_pVTKWindow_1->AddObserver(vtkCommand::KeyPressEvent, m_pVTKWindow_1_CallbackCommand);
m_pVTKWindow_1->Update();
pViewerXZ->SetInput (vtkImporter->GetOutput());
pViewerXZ->SetSliceOrientationToXZ();
pViewerXZ->SetupInteractor(m_pVTKWindow_2);
pViewerXZ->UpdateDisplayExtent();
m_pVTKWindow_2->AddObserver(vtkCommand::KeyPressEvent, m_pVTKWindow_2_CallbackCommand);
m_pVTKWindow_2->Update();
pViewerYZ->SetInput (vtkImporter->GetOutput());
pViewerYZ->SetSliceOrientationToYZ();
pViewerYZ->SetupInteractor(m_pVTKWindow_3);
pViewerYZ->UpdateDisplayExtent();
m_pVTKWindow_3->AddObserver(vtkCommand::KeyPressEvent, m_pVTKWindow_3_CallbackCommand);
m_pVTKWindow_3->Update();
pViewerXX windows are imageviewer2 objects whereas m_pVTKWindow_X refers to wxVTK objects to use in wxWidgets GUI package.
Optional: My exporter and importer are as given below:
template <typename ITK_Exporter, typename VTK_Importer>
void ConnectPipelines(ITK_Exporter exporter, VTK_Importer* importer)
{
importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCallback());
importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallback());
importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback());
importer->SetSpacingCallback(exporter->GetSpacingCallback());
importer->SetOriginCallback(exporter->GetOriginCallback());
importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback());
importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCallback());
importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateExtentCallback());
importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback());
importer->SetDataExtentCallback(exporter->GetDataExtentCallback());
importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback());
importer->SetCallbackUserData(exporter->GetCallbackUserData());
}
/**
* This function will connect the given vtkImageExport filter to
* the given itk::VTKImageImport filter.
*/
template <typename VTK_Exporter, typename ITK_Importer>
void ConnectPipelines(VTK_Exporter* exporter, ITK_Importer importer)
{
importer->SetUpdateInformationCallback(exporter->GetUpdateInformationCallback());
importer->SetPipelineModifiedCallback(exporter->GetPipelineModifiedCallback());
importer->SetWholeExtentCallback(exporter->GetWholeExtentCallback());
importer->SetSpacingCallback(exporter->GetSpacingCallback());
importer->SetOriginCallback(exporter->GetOriginCallback());
importer->SetScalarTypeCallback(exporter->GetScalarTypeCallback());
importer->SetNumberOfComponentsCallback(exporter->GetNumberOfComponentsCallback());
importer->SetPropagateUpdateExtentCallback(exporter->GetPropagateUpdateExtentCallback());
importer->SetUpdateDataCallback(exporter->GetUpdateDataCallback());
importer->SetDataExtentCallback(exporter->GetDataExtentCallback());
importer->SetBufferPointerCallback(exporter->GetBufferPointerCallback());
importer->SetCallbackUserData(exporter->GetCallbackUserData());
}
I don't have an exact answer to your question, but have you considered using one of the common medical image processing frameworks? There are a couple of them like MITK (mitk.org) or Slicer3D (slicer.org). They do a great job of linking together ITK, VTK and a sophisticated GUI Framework like QT (in the MITK case).
I have worked a long time in medical image processing and used MITK extensively. In my opinion, using a medical image processing framework really helps you focus on your real image processing problems, rather than trying to build processing/visualization pipelines for different types of visualizations.
If you look at InsightApplications, there are two methods:
The same as you tried, which is here, or
This one, which creates a pipeline object that can be connected on both sides. We're actually using this, and it works out quite well for us. You can copy this class into your code and use it.
There are some interesting usage examples in there too. Take a look at them and see if you can modify anything for your requirement.
Classes in the ITKVTkGlue module can be used to convert an ITK image to in a pipeline. See the tests for examples of how the classes are applied.

ICU custom transliteration

I am looking to utilize the ICU library for transliteration, but I would like to provide a custom transliteration file for a set of specific custom transliterations, to be incorporated into the ICU core at compile time for use in binary form elsewhere. I am working with the source of ICU 4.2 for compatibility reasons.
As I understand it, from the ICU Data page of their website, one way of going about this is to create the file trnslocal.mk within ICUHOME/source/data/translit/ , and within this file have the single line TRANSLIT_SOURCE_LOCAL=custom.txt.
For the custom.txt file itself, I used the following format, based on the master file root.txt:
custom{
RuleBasedTransliteratorIDs {
Kanji-Romaji {
file {
resource:process(transliterator){"custom/Kanji_Romaji.txt"}
direction{"FORWARD"}
}
}
}
TransliteratorNamePattern {
// Format for the display name of a Transliterator.
// This is the language-neutral form of this resource.
"{0,choice,0#|1#{1}|2#{1}-{2}}" // Display name
}
// Transliterator display names
// This is the English form of this resource.
"%Translit%Hex" { "%Translit%Hex" }
"%Translit%UnicodeName" { "%Translit%UnicodeName" }
"%Translit%UnicodeChar" { "%Translit%UnicodeChar" }
TransliterateLATIN{
"",
""
}
}
I then store within the directory custom the file Kanji_Romaji.txt, as found here. Because it uses > instead of the → I have seen in other files, I converted each entry appropriately, so they now look like:
丁 → Tei ;
七 → Shichi ;
When I compile the ICU project, I am presented with no errors.
When I attempt to utilize this custom transliterator within a testfile, however (a testfile that works fine with the in-built transliterators), I am met with the error error: 65569:U_INVALID_ID.
I am using the following code to construct the transliterator and output the error:
UErrorCode status = U_ZERO_ERROR;
Transliterator *K_R = Transliterator::createInstance("Kanji-Romaji", UTRANS_FORWARD, status);
if (U_FAILURE(status))
{
std::cout << "error: " << status << ":" << u_errorName(status) << std::endl;
return 0;
}
Additionally, a loop through to Transliterator::countAvailableIDs() and Transliterator::getAvailableID(i) does not list my custom transliteration. I remember reading with regard to custom converters that they must be registered within /source/data/mappings/convrtrs.txt . Is there a similar file for transliterators?
It seems that my custom transliterator is either not being built into the appropriate packages (though there are no compile errors), is improperly formatted, or somehow not being registered for use. Incidentally, I am aware of the RuleBasedTransliterator route at runtime, but I would prefer to be able to compile the custom transliterations for use in any produced binary.
Let me know if any additional clarification is necessary. I know there is at least one ICU programmer on here, who has been quite helpful in other posts I have written and seen elsewhere as well. I would appreciate any help I can find. Thank you in advance!
Transliterators are sourced from CLDR - you could add your transliterator to CLDR (the crosswire directory contains it in XML format in the cldr/ directory) and rebuild ICU data. ICU doesn't have a simple mechanism for adding transliterators as you are trying to do. What I would do is forget about trnslocal.mk or custom.txt as you don't need to add any files, and simply modify root.txt - you might file a bug if you have a suggested improvement.