Current position of a vehicle? - omnet++

I am using veins 5.1. I am trying use getCurrentPosition() function present in TraCIMobility. But it says there is no such function like that? How do I get the current position of a node?
My application source code:
bool VeinsInetSampleApplication::startApplication()
if (getParentModule()->getIndex() == 0) {
auto callback = [this]() {
veins::TraCICommandInterface::Junction traciJunction = traci->junction("node4");
veins::TraCICommandInterface::Junction traciJunction1 = traci->junction("node6");
veins::Coord nodes1 = traciJunction.getPosition();
veins::Coord nodes2 = traciJunction1.getPosition();
veins::Coord veh_pos = mobility_veins->getPositionAt(simTime());
};
timerManager.create(veins::TimerSpecification(callback).interval(SimTime(6, SIMTIME_S)));
}
return true;
And I have defined mobility_veins in the header file as
class VEINS_INET_API VeinsInetApplicationBase : public inet::ApplicationBase, public inet::UdpSocket::ICallback {
protected:
veins::VeinsInetMobility* mobility;
TraCIMobility* mobility_veins;
veins::TraCICommandInterface* traci;
veins::TraCICommandInterface::Vehicle* traciVehicle;
veins::TimerManager timerManager{this};
inet::L3Address destAddress;
const int portNumber = 9001;
inet::UdpSocket socket;

You can get the current position by:
mobility->getPositionAt(simTime());

Related

I am trying to use flutter Isolate with database data. But it's throwing an error. I don't know why is it happening?

I'm using the hive database. My code is:
HiveStocktaking? stocktaking =
_database.getStocktakingById(_stocktakingId);
StocktakingStats stocktakingStats =
_database.getStocktakingStats(_stocktakingId, true);
List<HiveStocktakingItem> stocktakingItemShortage = _database
.getStocktakingAllItem(_stocktakingId, 'shortage', '',
getAll: withProducts)
.values
.first;
List<HiveStocktakingItem> stocktakingItemSurplus = _database
.getStocktakingAllItem(_stocktakingId, 'surplus', '',
getAll: withProducts)
.values
.first;
int shortageLength = withProducts ? stocktakingItemShortage.length : 0;
int surplusLength = withProducts ? stocktakingItemSurplus.length : 0;
if (type == 'excel') {
createIsolate(
stocktaking,
stocktakingStats,
stocktakingItemShortage,
stocktakingItemSurplus,
shortageLength,
surplusLength,
);
}
Future createIsolate(
HiveStocktaking? stocktaking,
StocktakingStats stocktakingStats,
List<HiveStocktakingItem> stocktakingItemShortage,
List<HiveStocktakingItem> stocktakingItemSurplus,
int shortageLength,
int surplusLength) async {
ReceivePort receivePort = ReceivePort();
Isolate.spawn(isolateFunction, receivePort.sendPort);
SendPort childSendPort = await receivePort.first;
ReceivePort responsePort = ReceivePort();
childSendPort.send([
stocktaking,
stocktakingStats,
stocktakingItemShortage,
stocktakingItemSurplus,
shortageLength,
surplusLength,
responsePort.sendPort
]);
var sum = await responsePort.first;
print('sum: $sum');
}
void isolateFunction(SendPort mainSendPort) async {
ReceivePort childReceivePort = ReceivePort();
mainSendPort.send(childReceivePort.sendPort);
await for (var message in childReceivePort) {
HiveStocktaking? stocktaking = message[0];
StocktakingStats stocktakingStats = message[1];
List<HiveStocktakingItem> stocktakingItemShortage = message[2];
List<HiveStocktakingItem> stocktakingItemSurplus = message[3];
int shortageLength = message[4];
int surplusLength = message[5];
SendPort replyPort = message[6];
//heavy task
sync.Workbook workbook = sync.Workbook();
var sheet = workbook.worksheets[0];
sheet.getRangeByIndex(1, 1)
..setText('Отчет по инвентаризации')
..columnWidth = 40
..cellStyle.bold = true
..rowHeight = 30
..cellStyle.fontSize = 20;
sheet.getRangeByIndex(2, 1).setText('Магазин: ${stocktaking?.shopName}');
sheet
.getRangeByIndex(3, 1)
.setText('Дата начала: ${stocktaking?.createdAt}');
sheet
.getRangeByIndex(4, 1)
.setText('Дата завершения: ${stocktaking?.finishedAt}');
sheet.getRangeByIndex(2, 3)
..setText(
'Отсканировано товаров: ${BaseFunctions.numberRound(stocktakingStats.totalScannedMeasurementValue)}')
..columnWidth = 30;
sheet.getRangeByIndex(3, 3).setText(
'Недостач: ${BaseFunctions.numberRound(stocktakingStats.totalMeasurementValue)}');
sheet.getRangeByIndex(4, 3).setText(
'Излишков: ${BaseFunctions.numberRound(stocktakingStats.surplus)}');
// etc generating codes
List<int> bytes = workbook.saveAsStream();
workbook.dispose();
var uint8list = Uint8List.fromList(bytes);
if (Platform.isMacOS) {
String fileName = 'stocktaking_report_' +
DateFormat('dd-MM-yyyy_HH-mm-ss').format(DateTime.now()) +
'.pdf';
String? path =
await PathProviderPlatform.instance.getApplicationSupportPath();
final File file =
File(Platform.isWindows ? '$path\\$fileName' : '$path/$fileName');
await file.writeAsBytes(bytes, flush: true);
await Process.run('open', <String>['$path/$fileName'], runInShell: true);
} else {
await FileSaver.instance.saveFile(
'stocktaking_report_' +
DateFormat('dd-MM-yyyy_HH-mm-ss').format(DateTime.now()),
uint8list,
'xlsx',
mimeType: MimeType.MICROSOFTEXCEL,
);
}
replyPort.send(1);
}
}
But it is throwing this error:
[ERROR:flutter/lib/ui/ui_dart_state.cc(209)] Unhandled Exception: Invalid argument(s): Illegal argument in isolate message: (object extends NativeWrapper - Library:'dart:io' Class: _RandomAccessFileOpsImpl#13069316)
if I give the createIsolate fake data it works perfectly.
if (type == 'excel') {
ProjectFiles.createIsolate(
HiveStocktaking(),
StocktakingStats(),
[],
[],
0,
0,
);
}
I found a way to solve this issue. If you want to use the hive database in an isolate function note that you must init your database in the isolate function and close the boxes (which you want to use in the isolate) in the main thread. Register the boxes' adapter in the isolate. After your doing close the boxes which opened in isolate. To initiate the database in isolate, you have to set the database path to Hive.init(path). You can send this path through isolate's port. If you want to use closed boxes in the main thread you have to reopen it. Here some codes for example:
static Future<bool> myFunc() async {
ReceivePort receivePort = ReceivePort();
Isolate.spawn(isolateFunc, receivePort.sendPort);
SendPort childSendPort = await receivePort.first;
await Hive.box<YourBox>('boxName').close();
// database path
Directory appDocumentDir = await getApplicationDocumentsDirectory();
ReceivePort responsePort = ReceivePort();
childSendPort.send([appDocumentDir, responsePort.sendPort]);
var sum = await responsePort.first;
var box = await Hive.openBox<YourBox>('boxName');
HiveDatabase.setInstanceYourBox(box);
return sum == 1;
}
static void isolateDownloadStocktaking(SendPort mainSendPort) async {
ReceivePort childReceivePort = ReceivePort();
mainSendPort.send(childReceivePort.sendPort);
await for (var message in childReceivePort) {
Directory appDocumentDir = message[0];
Hive.init(appDocumentDir.path);
Hive.registerAdapter(YourBoxAdapter());
await HiveDatabase.getInstanceYourBox();
// you can use your box
SendPort replyPort = message[1];
await Hive.box<YourBox>('boxName').close();
replyPort.send(1);
}
}
HiveDatabase class is here:
class HiveDatabase {
static Box<YourBox>? _yourBox;
static HiveDatabase instance = HiveDatabase._();
HiveDatabase._();
static Future<HiveDatabase> getInstanceYourBox() async {
_yourBox ??= await Hive.openBox<YourBox>('boxName');
return instance;
}
static Future<HiveDatabase> setInstanceYourBox(Box<YourBox> box) async {
_yourBox = box;
return instance;
}
List<YourBox> elements() {
return (_yourBox?.values ?? []).toList();
}
Future<void> updateElement(YourBox value) async {
await _yourBox?.put(value.id, value);
}
Future<void> addElement(YourBox value) async {
await _yourBox?.put(value.id, value);
}
Future<void> deleteElement(int index) async {
await _yourBox?.deleteAt(index);
}
Future<void> clearYourBox() async {
await _yourBox?.clear();
}
}

How to use EnumProcesses in node-ffi

I was trying to use EnumProcesses with node-ffi. I got code below:
import ffi from 'ffi'
export const psapi = ffi.Library('psapi', {
EnumProcesses: ['bool', ['ulong', 'ulong', 'uint16*']]
})
export class Win32ProcessManager {
public async getProcessList () {
let lpidProcess = ref.alloc('ulong*')
const cb = 1024
const lpcbNeeded = ref.alloc('uint16*')
const res = psapi.EnumProcesses(lpidProcess, cb, lpcbNeeded)
const ulongSize = (ref as any).sizeof.ulong
const totalBytesReturned = lpcbNeeded.readInt16LE()
const processCount = totalBytesReturned / ulongSize
console.log(`processCount: ${processCount}`)
// ??? How to get the value from the lpidProcess?
return lpidProcess
}
}
I tried with ref.get but I encountered errors:
let processId = ref.get(array, 0, ref.types.ulong)
console.log(processId)
const pointerSize = (ref as any).sizeof.pointer
console.log(pointerSize)
let processId2 = ref.get(array, (ref as any).sizeof.pointer, ref.types.ulong)
console.log(processId2)
Errors:
RangeError [ERR_BUFFER_OUT_OF_BOUNDS]: Attempt to write outside buffer bounds
Anyone knows how to use node-ffi read the array data from dll?
Thanks #DrakeWu-MSFT, I finally got my code works, here are how they looks finally:
import ffi from 'ffi';
import ref from 'ref';
import ArrayType from "ref-array";
export const psapi = ffi.Library('psapi', {
EnumProcesses: ['bool', ['ulong*', 'ulong', 'uint16*']],
});
export class Win32ProcessManager {
public getProcessIdList (): number[] {
const processIdLength = 1024;
const ulongSize = (ref as any).sizeof.ulong;
const cb = processIdLength * ulongSize;
let processIdArray = ArrayType('ulong', processIdLength);
let lpidProcess = ref.alloc(processIdArray);
const lpcbNeeded = ref.alloc('uint16*');
const res = psapi.EnumProcesses(lpidProcess, cb, lpcbNeeded);
if (res) {
const totalBytesReturned = lpcbNeeded.readInt16LE();
const processCount = totalBytesReturned / ulongSize;
const processArray = (lpidProcess as any).deref();
let resultProcessArray: number[] = [];
for (let i = 0; i < processCount; i++) {
resultProcessArray.push(processArray[i]);
}
return resultProcessArray;
} else {
console.error(`Get process list failed with result from EnumProcess: ${res}`);
return [];
}
}
}
I was struggled with getting array data from the pointer, and that was wrong, as #DrakeWu-MSFT said in the comment, because I didn't allocate enough spaces for the buffer, no data can be write into that. With ref-array and a pointer to the array, it works like a charm.

Syntax help for creating a filter in aws ec2 describeinstance api call in c++

Using DescribeInstancesRequest (c++ sdk) to get response about a particular instance_id. I am having a problem constructing the filter.
I am adapting the example code provided by the aws-doc-sdk-examples c++ example code describe_instances.cpp. I have added code to filter the response to use a known valid (now hard coded) instance ID.
I have tried multiple variations to set up the filter, but the docs aren't clear to me about the "value pair" format for the filter.
Here is the complete code. It compiles just find, but always responds with the "Could not find: ..."
Please let me know what I am getting wrong with the filter syntax! (See commented section Filter an instance id)
Thanks
void Server::set_instance_info()
{
// Get server instance information via aws sdk
Aws::SDKOptions options;
Aws::InitAPI(options);
{
/* #TODO Make this a startup config value */
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = "us-west-2";
Aws::EC2::EC2Client ec2(clientConfig);
Aws::EC2::Model::DescribeInstancesRequest request;
// Filter an instance_id
Aws::EC2::Model::Filter filter;
filter.SetName("instance_id");
Aws::String filter_val{"Name=instance_id,Values=i-0e120b44acc929946"};
Aws::Vector<Aws::String> filter_values;
filter_values.push_back(filter_val);
filter.SetValues(filter_values);
Aws::Vector<Aws::EC2::Model::Filter> DIRFilter;
DIRFilter.push_back(filter);
request.SetFilters(DIRFilter);
auto outcome = ec2.DescribeInstances(request);
if (outcome.IsSuccess())
{
const auto &reservations =
outcome.GetResult().GetReservations();
for (const auto &reservation : reservations)
{
const auto &instances = reservation.GetInstances();
for (const auto &instance : instances)
{
Aws::String instanceStateString =
Aws::EC2::Model::InstanceStateNameMapper::GetNameForInstanceStateName(
instance.GetState().GetName());
Aws::String type_string =
Aws::EC2::Model::InstanceTypeMapper::GetNameForInstanceType(
instance.GetInstanceType());
Aws::String name = "Unknown";
const auto &tags = instance.GetTags();
auto nameIter = std::find_if(tags.cbegin(), tags.cend(),
[](const Aws::EC2::Model::Tag &tag)
{
return tag.GetKey() == "Name";
});
if (nameIter != tags.cend())
{
name = nameIter->GetValue();
}
Server::id_ = instance.GetInstanceId();
Server::name_ = name;
Server::type_ = type_string;
Server::dn_ = "Not implemented";
Server::ip_ = "Not implmented";
}
}
} else {
Server::id_ = "Could not find: " + filter_val;;
Server::name_ = "";
Server::type_ = "";
Server::dn_ = "";
Server::ip_ = "";
}
}
return;
}
I just couldn't get the filter to work. Any input would be appreciated. However, there is an alternate method using the WithInstanceIds member function. Reading the API docs is always a good idea!!
Here is the subroutine that works:
void Server::set_instance_info()
{
// Get server instance information via aws sdk
Aws::SDKOptions options;
Aws::InitAPI(options);
{
/* #TODO Make this a startup config value */
Aws::Client::ClientConfiguration clientConfig;
clientConfig.region = "us-west-2";
Aws::EC2::EC2Client ec2(clientConfig);
Aws::EC2::Model::DescribeInstancesRequest request;
/* #TODO Make this a startup config value */
const Aws::String instanceId{"i-0e120b44acc929946"};
Aws::Vector<Aws::String> instances;
instances.push_back(instanceId);
request.WithInstanceIds(instances);
auto outcome = ec2.DescribeInstances(request);
if (outcome.IsSuccess())
{
const auto &reservations =
outcome.GetResult().GetReservations();
for (const auto &reservation : reservations)
{
const auto &instances = reservation.GetInstances();
for (const auto &instance : instances)
{
Aws::String instanceStateString =
Aws::EC2::Model::InstanceStateNameMapper::GetNameForInstanceStateName(
instance.GetState().GetName());
Aws::String type_string =
Aws::EC2::Model::InstanceTypeMapper::GetNameForInstanceType(
instance.GetInstanceType());
Aws::String name = "Unknown";
const auto &tags = instance.GetTags();
auto nameIter = std::find_if(tags.cbegin(), tags.cend(),
[](const Aws::EC2::Model::Tag &tag)
{
return tag.GetKey() == "Name";
});
if (nameIter != tags.cend())
{
name = nameIter->GetValue();
}
Server::id_ = instance.GetInstanceId();
Server::name_ = name;
Server::type_ = type_string;
Server::dn_ = "Not implemented";
Server::ip_ = "Not implmented";
}
}
} else {
Server::id_ = "Could not find: "+ instanceId;
Server::name_ = "";
Server::type_ = "";
Server::dn_ = "";
Server::ip_ = "";
}
}
return;
}

JS: java.lang.Exception: Failed resolving method read on class android.media.AudioRecord

I'm trying to use android.media.AudioRecord to save audio, initialization is OK, startRecording() is also called without error, but when I start reading audio from the buffer I got error Failed resolving method read on class android.media.AudioRecord.
Here is the code:
const SAMPLE_RATE = 44100;
const RECORD_AUDIO = android.Manifest.permission.RECORD_AUDIO;
const AudioRecord = android.media.AudioRecord;
const AudioFormat = android.media.AudioFormat;
const MediaRecorder = android.media.MediaRecorder;
ngOnInit(): void {
this.bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
if (this.bufferSize == AudioRecord.ERROR || this.bufferSize == AudioRecord.ERROR_BAD_VALUE) {
this.bufferSize = SAMPLE_RATE * 2;
}
this.bufferSize = this.bufferSize * 10;
this.audioBuffer = new Array(this.bufferSize / 2);
if (!permissions.hasPermission(RECORD_AUDIO)) {
permissions.requestPermission(RECORD_AUDIO).then(() => {
this.createRecorder();
}, (err) => {
console.log('[BrowseComponent] ngOnInit, ', 'permissions error:', err);
});
}
else {
this.createRecorder();
}
}
createRecorder() {
this.record = new AudioRecord.Builder()
.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
.setAudioFormat(new AudioFormat.Builder()
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.setSampleRate(SAMPLE_RATE)
.setChannelMask(AudioFormat.CHANNEL_IN_MONO)
.build())
.setBufferSizeInBytes(this.bufferSize)
.build();
this.recordState = this.record && this.record.getState();
if (this.recordState != AudioRecord.STATE_INITIALIZED) {
console.error('[BrowseComponent] createRecorder, ', 'AudioRecord can\'t initialize, state:', this.recordState);
return;
}
console.log('[BrowseComponent] createRecorder, ', 'AudioRecord:', this.record);
}
startRecord() {
this.recording = true;
this.record.startRecording();
this.shortsRead = 0;
while (this.recording) {
const numberOfShort = this.record.read(this.audioBuffer, 0, this.bufferSize);
this.shortsRead += numberOfShort;
// Do something with the audioBuffer
}
}
startRecord() is called from (tap) button handler.
Any ideas what may be wrong?
I guess the problem is that you are passing JavaScript Array instead of the Java Primitive (short) typed Array, so the runtime is unable to identify a method that matches the given parameters.
Use Array.create method to typecast, refer the docs here for more details.

Receive a notification key from ios

I have the following command where I get my notification in ios, I want to get my key more I'm not getting it, what I tried was
public override void DidReceiveRemoteNotification(UIApplication application, NSDictionary userInfo, Action<UIBackgroundFetchResult> completionHandler)
{
Messaging.SharedInstance.AppDidReceiveMessage(userInfo);
NSString[] keys = { new NSString("Event_type") };
NSObject[] values = { new NSString("Recieve_Notification") };
var parameters = NSDictionary<NSString, NSObject>.FromObjectsAndKeys(keys, values, keys.Length);
Firebase.Analytics.Analytics.LogEvent("CustomEvent", parameters);
System.Diagnostics.Debug.WriteLine(userInfo);
// var aps_d = userInfo["aps"] as NSDictionary;
//var alert_d = aps_d["alert"] as NSDictionary;
//var body = alert_d["keys"] as NSString;
}
System.Diagnostics.Debug.WriteLine
receive this
[0:] {
aps = {
alert = {
body = "teste";
title = "teste";
};
};
"gcm.message_id" = "0:1505400569099941%712ac0f8712a1234";
"gcm.n.e" = 1;
"google.c.a.c_id" = 5974019197827881234;
"google.c.a.c_l" = "teste";
"google.c.a.e" = 1;
"google.c.a.ts" = 1505400123;
"google.c.a.udt" = 0;
keys = 152113;
}
keys is a top level and last entry in the dictionary, so you can directly access it via userInfo["keys"], i.e:
var keys = userInfo["keys"] as NSString;

Resources