How to read a yaml node array into std::vector - yaml-cpp

A total noob with yaml-cpp. I have a node something like this:
numbers : [1,2,3,4,5]
In the CPP file, I want to parse into a vector:
std::vector<int> vi = node["numbers"];
This doesn't work. I can't find any documentation other than the tutorial- and it isn't covered in the tutoral.

yaml-cpp already has overloads for standard container types, so the as<T>() function works here:
std::vector<int> vi = node["numbers"].as<std::vector<int>>();

Related

Create a CByteArray from a CPointer in Visual Works Smalltalk

Some C function return aCPointer to a C struct.
The C struct is known.
Now i want to put the C struct into a ByteArray. Basically copy the contents of the struct to a ByteArray.
In GemStone/S this can be done with:
CByteArray fromCPointer: aCPointer numBytes: 120.
"this create aCByteArray with the contents of the struct referenced by CPointer (copying only 120 bytes)"
Is there something similar on Visual Works ?
I did not find it yet.
It could be possible to replicate C struct at Visual Works level but is only one struct and it is ok to handle it at low level.
There's only the rather ugly #copyAt:to:size:startingAt: that you can send to a pointer. You need to allocate a ByteArray yourself (make sure it's big enough).
answer := ByteArray new: size.
pointer
copyAt: 0
to: answer
size: size
startingAt: 1.
The other way (ByteArray -> Pointer) would be done using #copyAt:from:size:startingAt:.
This method works for both ByteArray and UninterpretedBytes. If you want to read data from the bytes, UninterpretedBytes may be more helpful as you can send things like #longAt: to read a long from an offset.
If aCPointer points to a struct of char * for example:
struct Names
{char * name;
char * longname;} name;
Then:
(aCPointer at: 0) copyCStringFromHeap. "answer [name]"
(aCPointer at: 1) copyCStringFromHeap. "answer [longname]"
For structs with char * it work nicely not tested with other C types.

Error: No operator "=" matches these operands in "Servo_Project.cpp", Line: 15, Col: 22

So I tried using code from another post around here to see if I could use it, it was a code meant to utilize a potentiometer to move a servo motor, but when I attempted to compile it is gave the error above saying No operator "=" matches these operands in "Servo_Project.cpp". How do I go about fixing this error?
Just in case ill say this, the boards I was trying to compile the code were a NUCLEO-L476RG, the board from the post I mentioned utilized Nucleo L496ZG board and a Tower Pro Micro Servo 9G.
#include "mbed.h"
#include "Servo.h"
Servo myservo(D6);
AnalogOut MyPot(A0);
int main() {
float PotReading;
PotReading = MyPot.read();
while(1) {
for(int i=0; i<100; i++) {
myservo = (i/100);
wait(0.01);
}
}
}
This line:
myservo = (i/100);
Is wrong in a couple of ways. First, i/100 will always be zero - integer division truncates in C++. Second, there's not an = operator that allows an integer value to be assigned to a Servo object. YOu need to invoke some kind of Servo method instead, likely write().
myservo.write(SOMETHING);
The SOMETHING should be the position or speed of the servo you're trying to get working. See the Servo class reference for an explanation. Your code tries to use fractions from 0-1 and thatvisn't going to work - the Servo wants a position/speed between 0 and 180.
You should look in the Servo.h header to see what member functions and operators are implemented.
Assuming what you are using is this, it does have:
Servo& operator= (float percent);
Although note that the parameter is float and you are passing an int (the parameter is also in the range 0.0 to 1.0 - so not "percent" as its name suggests - so be wary, both the documentation and the naming are poor). You should have:
myservo = i/100.0f;
However, even though i / 100 would produce zero for all i in the loop, that does not explain the error, since an implicit cast should be possible - even if clearly undesirable. You should look in the actual header you are using to see if the operator= is declared - possibly you have the wrong file or a different version or just an entirely different implementation that happens to use teh same name.
I also notice that if you look in the header, there is no documentation mark-up for this function and the Servo& operator= (Servo& rhs); member is not documented at all - hence the confusing automatically generated "Shorthand for the write and read functions." on the Servo doc page when the function shown is only one of those things. It is possible it has been removed from your version.
Given that the documentation is incomplete and that the operator= looks like an after thought, the simplest solution is to use the read() / write() members directly in any case. Or implement your own Servo class - it appears to be only a thin wrapper/facade of the PwmOut class in any case. Since that is actually part of mbed rather than user contributed code of unknown quality, you may be on firmer ground.

Return numpy matrix from SWIG method using numpy.i

I've found the following SWIG rule in numpy.i documentation.
( DATA_TYPE ARGOUT_ARRAY2[ANY][ANY] )
Frankly, this snippet gives no idea how to wrap a C++ function returning a 3*3 matrix. What does "ANY" mean? Suppose, I've got a function with a signature void make_matrix(double** matrix). It allocates 3*3*sizeof(double) bytes with malloc() and writes them to out parameter. Now to apply this rule? How to bind 3 to "ANY"? How to bind matrix to "ARGOUT_ARRAY2"? How to bind DATA_TYPE to double? Is there any kind of documentation covering these details?
Based on the docs you cite (in the Input Arrays section):
The first signature listed, ( DATA_TYPE IN_ARRAY[ANY] ) is for one-dimensional arrays with hard-coded dimensions. Likewise, ( DATA_TYPE IN_ARRAY2[ANY][ANY] ) is for two-dimensional arrays with hard-coded dimensions, and similarly for three-dimensional.
The all caps portions are place holders for the values you are actually using. Proper use is dependent on a thorough understanding of SWIG syntax.
If you happen to be using the venerable Eigen library to represent your matrices in C++, then there are some very useful SWIG wrappers available within the Biomechanical Toolkit which allow Eigen matrices to be transparently converted into numpy arrays.
Your SWIG interface definition should contain something along the following lines:
%module(docstring="Simple SWIG+Eigen demo") myeigenswig
%include eigen.i
%include numpy.i
%{
#define SWIG_FILE_WITH_INIT
#include <Eigen/Core>
#include "mylibrary.hpp"
%}
%init %{
import_array();
%}
%eigen_typemaps(Eigen::VectorXd)
%eigen_typemaps(Eigen::MatrixXd)
Eigen::MatrixXd myFunction();
Another option, if you're not using Eigen, is to convert your 3x3 C++ array into a 9-element std::vector<double>, which SWIG will easily convert into a Python list, and which can then be turned into a numpy array by invoking numpy.asarray(vectorFromCxx).reshape((3,3)). This won't be especially efficient, involving quite a bit of copying between different data structures, but may be sufficient for your application unless you're passing many matrices between C++ & Python.

Can't create simple binary data structure with IdrisNet2

I am trying to use the IdrisNet2 library to define some binary data structures. I am using Idris 0.9.17.1 and commit 262b746c9a2405e43d1de6a48de44cac2fd19932 of IdrisNet2. I am defining a packet with one 16 bit field:
module Main
import IdrisNet.PacketLang
import Data.So
myPacket : PacketLang
myPacket = with PacketLang do
bits 16
main : IO ()
main = putStrLn "hello"
I get the compiler error:
Can't solve goal
So (fromInteger 16 > fromInteger 0)
What exactly is the problem and how can I fix it? I am guessing that I need to prove to the compiler that 16 is greater than 0, but I'm not sure how to do this in Idris or why this is necessary.
Sorry about that. A while back we decided to standardize on uppercase for all the types and their constructors; that meant oh and so got renamed to Oh and So. So there was an update to this lib to get it to compile, but it looks like an oh in the default tactics to solve an implicit param got overlooked:
https://github.com/SimonJF/IdrisNet2/blob/master/src/IdrisNet/PacketLang.idr#L149
So that tactic would always fail (oh is an undefined reference). You could explicitly pass the value of p there, and that would work: bits 16 {p = Oh}.
But I've submitted a pull request to fix that issue in the lib: https://github.com/SimonJF/IdrisNet2/pull/11

PIC C18: Converting double to string

I am using PIC18F2550. Programming it with C18 language.
I need a function that converts double to string like below:
void dtoa( char *szString, // Output string
double dbDouble, // Input number
unsigned char ucFPlaces) // Number of digits in the resulting fractional part
{
// ??????????????
}
To be called like this in the main program:
void main (void)
{
// ...
double dbNumber = 123.45678;
char szText[9];
dtoa(szText, dbNumber, 3); // szText becomes "123.456" or rounded to "123.457"
// ...
}
So write one!
5mins, a bit of graph paper and a coffee is all it should take.
In fact it's a good interview question
Tiny printf might work for you: http://www.sparetimelabs.com/tinyprintf/index.html
Generally, the Newlib C library (BSD license, from RedHat, part of Cygwin as well as used in many many "bare-metal" embedded-systems compilers) is a good place to start for usefuls sources for things that would be in the standard C library.
The Newlib dtoa.c sources are in the src/newlib/libc/stdlib subdirectory of the source tree:
Online source browser: http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/stdlib/?cvsroot=src#dirlist
Direct link to the current version of the dtoa.c file: http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libc/stdlib/dtoa.c?rev=1.5&content-type=text/plain&cvsroot=src
The file is going to be a little odd, in that Newlib uses some odd macros for the function declarations, but should be straightforward to adapt -- and, being BSD-licensed, you can pretty much do whatever you want with it if you keep the copyright notice on it.