The truth is that I have a simple tool to let the game auto run on my android phone. I want to collect the some performance data like Profiler provides, memory, draw calls, each mem allocate on each function and so on. So is there any api or tool to reach that?
As you already noticed, you can't save from the Profiler more than 300 frames of data.
The only way to save a stream of profiling data, is to write a class and attach the script to every game object in the scene.
using UnityEngine;
using UnityEngine.Profiling;
using System.Collections;
public class ProfilerDataLogger : MonoBehaviour
{
int frameCount = 0;
void Update()
{
if (Input.GetKey(KeyCode.LeftControl) && Input.GetKeyDown(KeyCode.L))
{
StopAllCoroutines();
frameCount = 0;
StartCoroutine(DataLogger());
}
}
IEnumerator DataLogger()
{
while (true)
{
string filepath = Application.persistentDataPath + "/profilerData" + frameCount + ".log";
Profiler.logFile = filepath;
Profiler.enableBinaryLog = true;
Profiler.enabled = true;
for (int i = 0; i < 300; i++)
{
yield return new WaitForEndOfFrame();
if (!Profiler.enabled)
Profiler.enabled = true;
}
frameCount++;
}
}
}
Then, you can load the log files (each containing 300 frames of data) in the Profiler, or you can write a class in order to execute the loading from the Editor.
Related
When trying to start a new waypoint mission while one is already in progress, I usually get a OpenProtocol::ErrorCode::MissionACK::WayPoint::DATA_NOT_ENOUGH error when I try to upload the first waypoint. Strangely, if I stop the mission afterwards and try uploading again, it works.
Unfortunately, I couldn't find any detailed documentation on what this error means.
Here's my code (note that it's the onboard SDK, not the mobile SDK; the code is Java calling into native code; interface generated by SWIG):
public void uploadWaypointMissionImpl(#NonNull DroneMission mission) throws DroneException{
WayPointInitSettings wpis = newMissionSettings(mission);
MissionManager missionManager = vehicle.getMissionManager();
WaypointMission wptMission;
int wpcount = missionManager.getWayptCounter();
if (wpcount > 0){
wptMission = missionManager.getWpMission();
wptMission.stop(REQUEST_TIMEOUT_SECONDS);
wptMission.init(wpis, REQUEST_TIMEOUT_SECONDS);
} else{
missionManager.initWaypoint(wpis, REQUEST_TIMEOUT_SECONDS));
wptMission = missionManager.getWpMission();
}
if (wptMission == null)
throw new DroneException("Failed to initialize mission manager");
int pointCount = mission.getNavPoints().size();
logger.i("Waypoint mission created, uploading %d points", pointCount);
for (int i = 0; i < pointCount; ++i){
WayPointSettings wp = newWayPointSettings(mission, i);
wptMission.uploadIndexData(wp, REQUEST_TIMEOUT_SECONDS).getAck(); // <-- ERROR HERE
}
}
private static WayPointInitSettings newMissionSettings(#NonNull DroneMission mission){
WayPointInitSettings wpis = new WayPointInitSettings();
wpis.setMaxVelocity(mission.getVelocityMps());
wpis.setIdleVelocity(mission.getVelocityMps());
wpis.setTraceMode((short)(!mission.isInPlace() && Prefs.drone.traceMode().get() ? 1 : 0));
wpis.setRCLostAction((short)(Prefs.drone.rcLostMode().get() ? 1 : 0));
wpis.setGimbalPitch((short)(Prefs.drone.gimbalPitchAutoMode().get() ? 1 : 0));
wpis.setYawMode((short)0);
wpis.setExecutiveTimes((short)1);
wpis.setFinishAction((short)4);
wpis.setLatitude(0.0);
wpis.setLongitude(0.0);
wpis.setAltitude(0.0f);
wpis.setIndexNumber((short)mission.getNavPoints().size());
Uint8Array reserved = new Uint8Array(16);
for (int i = 0; i < 16; ++i){
reserved.setitem(i, (short)0);
}
wpis.setReserved(reserved.cast());
return wpis;
}
private static WayPointSettings newWayPointSettings(#NonNull DroneMission mission, int index){
WayPointSettings wp = new WayPointSettings();
wp.setDamping(Prefs.drone.dampingDistanceM().get());
wp.setGimbalPitch(Prefs.drone.gimbalPitch().get().shortValue());
wp.setYaw(Prefs.drone.yawDeg().get().shortValue());
wp.setTurnMode((short)(Prefs.drone.turnModeCounterClockwise().get() ? 1 : 0));
wp.setActionTimeLimit(100);
wp.setHasAction((short)0);
wp.setActionNumber((short)0);
wp.setActionRepeat((short)0);
Uint8Array commandList = new Uint8Array(16);
Uint16Array commandParameter = new Uint16Array(16);
for (int i = 0; i < 16; ++i){
commandList.setitem(i, (short)0);
commandParameter.setitem(i, 0);
}
wp.setCommandList(commandList.cast());
wp.setCommandParameter(commandParameter.cast());
NavPoint point = mission.getNavPoints().get(index);
wp.setLongitude(point.getLocation().getLngRad());
wp.setLatitude(point.getLocation().getLatRad());
wp.setAltitude((float)Math.ceil(point.getCruisingAltitude() - mission.getTakeoffAltitudeMeters()));
wp.setIndex((short)index);
return wp;
}
Waypoint mission needs a minimum of 3 waypoints when i tried it on an android device, try adding 2 more points but note that they must have 1 meter distance between each point
Edit: I added code for making waypoints and adding them to a list
// Create a waypoint instance
Waypoint mWaypoint1 = new Waypoint(Latitude, Longitude, altitude);
//check if the mission's builder is null
if (waypointMissionBuilder != null) {
waypointList.add(mWaypoint1);
waypointMissionBuilder.waypointList(waypointList).
waypointCount(waypointList.size());
}
else {
waypointMissionBuilder = new WaypointMission.Builder();
waypointList.add(mWaypoint1);
waypointMissionBuilder.waypointList(waypointList).
waypointCount(waypointList.size());
}
You need to make a waypoint instance which has Lat,Long,Alt. give it the correct parameters and add it to the list then use the builder to config, upload and start the mission. In case the list's size is 2 or less the mission will give you a djiError when trying to use the config function.
Hi,maybe you need to call the "wptMission.stop"before you start a new waypoint mission.All the data of this mission you write is uploaded to the flight controller,only when you call the "wptMission.stop",the flight controller will know you want to call other commands.
I'm currently doing a project on Netduino Plus 2 using .net micro framework which requires me to code for a pulse sensor. I have tried finding codes for pulse sensor but to no avail. I tried using AnalogInput codes for pulse sensor but the output values seemed wrong (there was a constant high value despite no heartbeat placed near the sensor). Please advise!
Here are my current codes for the heartbeat sensor:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;
namespace heartrate
{
public class Program
{
public static void Main()
{
SecretLabs.NETMF.Hardware.AnalogInput rate =
new SecretLabs.NETMF.Hardware.AnalogInput(Pins.GPIO_PIN_A0);
int sensorvalue = 0;
while (true)
{
sensorvalue = rate.Read();
Debug.Print("" + sensorvalue);
Thread.Sleep(1000);
}
}
}
}
Here are the specs of the sensor, how it looks like and how it is connected.
http://www.elecrow.com/wiki/index.php?title=Pulse_Sensor
(This tutorial is for arduino, but I think the wiring is similar to that of Netduino)
Hard to tell without specs on your pulse device and how it is attached. For Analog input & output in my latest project (https://github.com/osstekz/cncBuddy) I use classes InputPort & OutputPort (Microsoft.SPOT.Hardware)
ex:
public NESControllerAdapter(Cpu.Pin pinClk, Cpu.Pin pinLatch, Cpu.Pin pinData1/*, Cpu.Pin pinData2 = Cpu.Pin.GPIO_NONE*/) {
// Binds to all pins
this._outpClk = new OutputPort(pinClk, false);
this._outpLatch = new OutputPort(pinLatch, false);
this._inpData1 = new InputPort(pinData1, false, Port.ResistorMode.Disabled);
//if (pinData2 != Cpu.Pin.GPIO_NONE) this._inpData2 = new InputPort(pinData2, false, Port.ResistorMode.Disabled);
}
...then like your rate.Read(); loop
public int ButtonPressed() {
// Locks all parms
this._PinTick(this._outpLatch);
// Reads plug state value
for (int i = 0; i < CncBuddyShared.iTOTALNESCONTROLLERBUTTONS; ++i) {
// Read the value, if true return this index as the first pressed button
if (this._inpData1.Read() == false) return i;
// Selects the next value
this._PinTick(this._outpClk);
}
return NESCONTROLLER_PRESSEDBUTTOM_NONE;
}
the code below is for a fundraiser dinner to purchase a land, the purpose is to show the progress of the square meter of land purchased (around 2976m2). everytime a square meter is purchased, the application adds an image tile which corresponds to an acctual 1m2. eventually the tiles (~2976 of them) fill up like in a grid to complete the land once fully purchased.
The size of each tiles is around 320bytes, there are 2976 tiles in total.
I have also showing below an image example.
The thing that drives me crazy with this code (in javafx) is that it consumes around 90 to 100% of 1 of my processors and the memory usage keeps increasing as the tiles add up until the code buffer run out of memory and the program crashes after a while. this is not desirable during the fundraising dinner.
the full code is available for testing at
you will need to change boolean split to true false, which will split the images for you, (around 3000 images);
https://github.com/rihani/Condel-Park-Fundraiser/tree/master/src/javafxapplication3
The main culprit that uses all the memory and CPU is the AnimationTimer() function shown below and I am wondering if anyone can help me reduce memory and CPU usage in this code.
to briefly explain how the code below is used, the land is divided into 2 panes, when the first one grid_pane1 is filled up the second pane grid_pane2 starts to then fill up.
also a flashing tile is used to show the current progress.
I am using total_donnation ++; to test the code, but would normally use mysql to pull the new value raised during the findraising dinner
AnimationTimer() Code:
translate_timer = new AnimationTimer() {
#Override public void handle(long now) {
if (now > translate_lastTimerCall + 10000_000_000l)
{
old_total_donnation = total_donnation;
try
{
// c = DBConnect.connect();
// SQL = "Select * from donations";
// rs = c.createStatement().executeQuery(SQL);
// while (rs.next())
// {total_donnation = rs.getInt("total_donnation");}
// c.close();
total_donnation ++;
if(total_donnation != old_total_donnation)
{
System.out.format("Total Donation: %s \n", total_donnation);
old_total_donnation = total_donnation;
if (!pane1_full)
{
grid_pane1.getChildren().clear();
grid_pane1.getChildren().removeAll(imageview_tile1,hBox_outter_last);
}
grid_pane2.getChildren().clear();
grid_pane2.getChildren().removeAll(imageview_tile2,hBox_outter_last);
for(i=0; i<=total_donnation; i++)
{
if (pane1_full){ System.out.println("Pane 1 has not been redrawn"); break;}
file1 = new File("pane1_img"+i+".png");
pane1_tiled_image = new Image(file1.toURI().toString(),image_Width,image_Height,false,false);
imageview_tile1 = new ImageView(pane1_tiled_image);
grid_pane1.add(imageview_tile1, current_column_pane1,current_row_pane1);
current_column_pane1 = current_column_pane1+1;
if (current_column_pane1 == max_columns_pane1 )
{
current_row_pane1 = current_row_pane1+1;
current_column_pane1 = 0;
}
if (i == max_donnation_pane1 ){ pane1_full = true; System.out.println("Pane 1 full"); break;}
if (i == total_donnation)
{
if (i != max_donnation_pane1)
{
hBox_outter_last = new HBox();
hBox_outter_last.setStyle(style_outter);
hBox_outter_last.getChildren().add(blink_image);
ft1 = new FadeTransition(Duration.millis(500), hBox_outter_last);
ft1.setFromValue(1.0);
ft1.setToValue(0.3);
ft1.setCycleCount(Animation.INDEFINITE);
ft1.setAutoReverse(true);
ft1.play();
grid_pane1.add(hBox_outter_last, current_column_pane1,current_row_pane1);
}
}
}
if (i < total_donnation)
{
total_donnation_left = total_donnation - max_donnation_pane1;
for(j=0; j<=total_donnation_left; j++)
{
file2 = new File("pane2_img"+j+".png");
pane2_tiled_image = new Image(file2.toURI().toString(),image_Width,image_Height,false,false);
imageview_tile2 = new ImageView(pane2_tiled_image);
grid_pane2.add(imageview_tile2, current_column_pane2,current_row_pane2);
current_column_pane2 = current_column_pane2+1;
if (current_column_pane2 == max_columns_pane2 )
{
current_row_pane2 = current_row_pane2+1;
current_column_pane2 = 0;
}
if (j == max_donnation_pane2 ){ System.out.println("Pane 2 full"); break;}
if (j == total_donnation_left)
{
if (j != max_donnation_pane2)
{
hBox_outter_last = new HBox();
hBox_outter_last.setStyle(style_outter);
hBox_outter_last.getChildren().add(blink_image);
ft = new FadeTransition(Duration.millis(500), hBox_outter_last);
ft.setFromValue(1.0);
ft.setToValue(0.3);
ft.setCycleCount(Animation.INDEFINITE);
ft.setAutoReverse(true);
ft.play();
grid_pane2.add(hBox_outter_last, current_column_pane2,current_row_pane2);
}
}
}
}
current_column_pane1 =0;
current_row_pane1=0;
current_column_pane2=0;
current_row_pane2=0;
}
}
catch (Exception ex) {}
translate_lastTimerCall = now;
}
}
};
First and foremost, you create a lot of indefinite FadeTransitions that are never stopped. These add up over time and cause both memory and CPU leaks. You should stop() the transition before starting a new one. Alternatively, you only need one transition to interpolate the value of a DoubleProperty and then bind node's opacity to this property:
DoubleProperty opacity = new SimpleDoubleProperty();
Transition opacityTransition = new Transition() {
protected void interpolate(double frac) {
opacity.set(frac);
}
};
// elsewhere
hBox_outter_last.opacityProperty().bind(opacity);
You may want to preload all the image tiles beforehand, so that you avoid reading from disk in the loop.
You unnecessarily destroy and recreate large part of the scene in every cycle. You should modify your code to only add the new tiles and not drop them all and recreate them from scratch.
Finally, when you actually query the database, you should do it from a different thread and not the JavaFX application thread, because your UI will be unresponsive for the time of the query (e.g. not animating your fade transitions).
I have a suggestion:
Do not split the image instead using 2 panels. One for displaying the whole image. The second will be a grid pane overlapping the first pane. Therefore, when a square meter is purchased, the background of corresponding grid-cell will become transparent.
For the last couple of days I've been trying to find out why my gwt application is leaking on IE 9.
I want to share one of my findings with you and maybe someone can give me a clue about what is going one here...
I wrote this small test:
public class Memory implements EntryPoint
{
FlowPanel mainPanel = new FlowPanel();
FlowPanel buttonsPanel = new FlowPanel();
FlowPanel contentPanel = new FlowPanel();
Timer timer;
Date startDate;
public void onModuleLoad()
{
mainPanel.setWidth("100%");
mainPanel.setHeight("100%");
RootPanel.get().add(mainPanel);
Button startBtn = new Button("start test");
startBtn.addClickHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event)
{
startDate = new Date();
System.out.println("Started at " + startDate);
timer = new Timer()
{
public void run()
{
Date now = new Date();
if(isWithin5Minutes(startDate, now))
{
manageContent();
}
else
{
System.out.println("Complete at " + new Date());
timer.cancel();
contentPanel.clear();
}
}
};
timer.scheduleRepeating(50);
}
});
buttonsPanel.add(startBtn);
mainPanel.add(buttonsPanel);
mainPanel.add(contentPanel);
}
private void manageContent()
{
if(contentPanel.getWidgetCount() > 0)
{
contentPanel.clear();
}
else
{
for(int i =0; i < 20; i++)
{
Image image = new Image();
image.setUrl("/images/test.png");
contentPanel.add(image);
}
}
}
private boolean isWithin5Minutes(Date start, Date now)
{
//true if 'now' is within 5 minutes of 'start' date
}
}
So, I have this Timer that runs every 50 ms (during around 5 minutes) and executes the following:
- if the panel has content, clear it;
- if the panel has no content add 20 png images (30x30 with transparency) to it.
Using the Process Explorer from sysInternals I got the following results:
IE 9:
Firefox 21.0:
I ran the same program with some changes (.jpg images instead of .png, create the images only once and use them as member variables, create the images using a ClientBundle) but the result was the same. Also, I ran the application in production mode.
Is there something wrong with my code that could cause this behavior in IE?
Shouldn't the Garbage Collector (GC) free some of the used memory at least when the timer ends?
Any of you came across this problem before?
Garbage collector in IE is quite strange thing. E.g. you can force it to run by simply minimizing browser window. I guess leaks in your case are images that weren't removed properly by browser when you clear container. Try to remove them by using JS "delete" operation, like that:
private native void utilizeElement(Element element) /*-{
delete element;
}-*/;
Then change your manageContent a little:
if(contentPanel.getWidgetCount() > 0)
{
for (Iterator<Widget> it = contentPanel.iterator(); it.hasNext();)
utilizeElement(it.next().getElement());
contentPanel.clear();
}
Hope this helps.
I'm new to Windows Forms, in my project, i need to change the image in the picture box at runtime. I'm able to do that with the help of a timer. The picture just gets changed. Is it possible to do some transitions when image changes, for example fade in, fade out, blur etc.. If possible could some one please let me know how to do it. I searched in net but in vain.Thanks in advance.
Varun
Simply take new code file and paste below code in it
an original answer for the similar question, answer taken from another question
Answer
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
public class BlendPanel : Panel
{
private Image mImg1;
private Image mImg2;
private float mBlend;
public BlendPanel()
{
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
}
public Image Image1
{
get { return mImg1; }
set { mImg1 = value; Invalidate(); }
}
public Image Image2
{
get { return mImg2; }
set { mImg2 = value; Invalidate(); }
}
public float Blend
{
get { return mBlend; }
set { mBlend = value; Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
if (mImg1 == null || mImg2 == null)
e.Graphics.FillRectangle(new SolidBrush(this.BackColor), new Rectangle(0, 0, this.Width, this.Height));
else
{
Rectangle rc = new Rectangle(0, 0, this.Width, this.Height);
ColorMatrix cm = new ColorMatrix();
ImageAttributes ia = new ImageAttributes();
cm.Matrix33 = mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg2, rc, 0, 0, mImg2.Width, mImg2.Height, GraphicsUnit.Pixel, ia);
cm.Matrix33 = 1F - mBlend;
ia.SetColorMatrix(cm);
e.Graphics.DrawImage(mImg1, rc, 0, 0, mImg1.Width, mImg1.Height, GraphicsUnit.Pixel, ia);
}
base.OnPaint(e);
}
}
Build your project. You can now drop a BlendPanel from the top of the toolbox onto your form. Here's a sample program that uses it:
private float mBlend;
private int mDir = 1;
public int count = 0;
public Bitmap[] pictures;
public void myPhoto()
{
pictures = new Bitmap[9];
pictures[0] = new Bitmap(#"Library Images\cf3.jpg");
pictures[1] = new Bitmap(#"Library Images\cf4.jpg");
pictures[2] = new Bitmap(#"Library Images\l1.JPG");
pictures[3] = new Bitmap(#"Library Images\l2.JPG");
pictures[4] = new Bitmap(#"Library Images\l3.JPG");
pictures[5] = new Bitmap(#"Library Images\l4.JPG");
pictures[6] = new Bitmap(#"Library Images\l5.JPG");
pictures[7] = new Bitmap(#"Library Images\l6.JPG");
pictures[8] = new Bitmap(#"Library Images\l7.JPG");
timer1.Interval = 50; //time of transition
timer1.Tick += BlendTick;
try
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
catch
{
}
timer1.Enabled = true;
}
private void BlendTick(object sender, EventArgs e)
{
mBlend += mDir * 0.02F;
if (mBlend > 1)
{
mBlend = 0.0F;
if ((count + 1) < pictures.Length)
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[++count];
}
else
{
blendPanel1.Image1 = pictures[count];
blendPanel1.Image2 = pictures[0];
count = 0;
}
}
blendPanel1.Blend = mBlend;
}
You'll need to modify the new Bitmap(#"yourimagePath"); calls. Build and run. You should see the displayed image smoothly morph from your first image to your second image without any flickering.
I hope it helps for other...
There is no built-in support for such effects, but you can implement them. I'd suggest to write a custom control that renders the image and have a method for fade-swap, fade itself can be reached with alpha-blending drawing with .NET Graphics class.
However, Graphics class isn't very fast, I don't recommend to use this technique for big images. If you need some fancy UI with hw-accelerated effects, take a look at WPF.
Blend effects are easy to get going by using the ColorMatrix class. There's a good example available in my answer in this thread.
A simple way to get a blur is to resize the image, making it smaller, then redraw it back, making it larger. The Graphics.InterpolationMode property affects the type of blur you'll get.
Those are quicky do-it-yourself solutions. Any decent graphics library has these kind of operations built-in. You probably want something free, check out ImageMagick.NET
To put it simply, not without external (3rd-party) libraries.